⬢ DragonFlyBSD Kernel Audit
DF-5619 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/platform/pc64/acpica/acpi_cstate_machdep.c b/sys/platform/pc64/acpica/acpi_cstate_machdep.c
--- a/sys/platform/pc64/acpica/acpi_cstate_machdep.c
+++ b/sys/platform/pc64/acpica/acpi_cstate_machdep.c
@@ -84,12 +84,24 @@
 			    cx->gas.SpaceId);
 			return EINVAL;
 		}
+		/*
+		 * A C2+ I/O or memory C-state is only operational when
+		 * its register resource was allocated; the caller only
+		 * installs the bus-space enter method in that case.
+		 * Reject the descriptor rather than letting a state with
+		 * no entry method into the idle loop.
+		 */
+		if (cx->type != ACPI_STATE_C1 && cx->res == NULL)
+			return EINVAL;
 		return 0;
 	}
 
 	switch (cx->gas.SpaceId) {
 	case ACPI_ADR_SPACE_SYSTEM_IO:
 	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
+		/* No register resource, no entry method. */
+		if (cx->type != ACPI_STATE_C1 && cx->res == NULL)
+			return EINVAL;
 		break;
 
 	case ACPI_ADR_SPACE_FIXED_HARDWARE:
diff --git a/sys/dev/acpica/acpi_cpu_cstate.c b/sys/dev/acpica/acpi_cpu_cstate.c
--- a/sys/dev/acpica/acpi_cpu_cstate.c
+++ b/sys/dev/acpi_cpu_cstate.c
@@ -618,6 +618,18 @@
     }
     AcpiOsFree(buf.Pointer);
 
+    /*
+     * An empty state table must not parse as success: idle would run on
+     * zeroed/rejected states whose enter method is NULL, and the NO_C3
+     * quirk path in acpi_cst_postattach() would resurrect rejected
+     * states through cst_non_c3.
+     */
+    if (sc->cst_cx_count == 0) {
+	device_printf(sc->cst_dev, "no usable Cx state in _CST\n");
+	sc->cst_flags &= ~ACPI_CST_FLAG_PROBING;
+	return (ENXIO);
+    }
+
     if (sc->cst_flags & ACPI_CST_FLAG_MATCH_HT) {
 	cpumask_t mask;