Download raw body.
[3/5] acpimadt: fix null dereference and mp_busses misuse without I/O APIC
This is a series of commits to expose ACPI tables to vmd guests.
These were committed and tested individually.
They can be reviewed in their entirety here:
https://github.com/openbsd/src/compare/master...nomadium:src:add-support-for-acpi-in-vmd.patch
---
sys/dev/acpi/acpimadt.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/sys/dev/acpi/acpimadt.c b/sys/dev/acpi/acpimadt.c
index 275f2b1e6ce..99832a2f125 100644
--- a/sys/dev/acpi/acpimadt.c
+++ b/sys/dev/acpi/acpimadt.c
@@ -198,6 +198,7 @@ acpimadt_attach(struct device *parent, struct device *self, void *aux)
struct mp_intr_map *map;
struct ioapic_softc *apic;
int nlapic_nmis = 0;
+ int nioapic = 0;
int pin;
/* Do some sanity checks before committing to run in APIC mode. */
@@ -218,8 +219,6 @@ acpimadt_attach(struct device *parent, struct device *self, void *aux)
aml_evalname(acpi_sc, NULL, "\\_PIC", 1, &arg, NULL);
- mp_busses = acpimadt_busses;
- mp_nbusses = nitems(acpimadt_busses);
mp_isa_bus = &acpimadt_isa_bus;
lapic_boot_init(madt->local_apic_address);
@@ -292,6 +291,7 @@ acpimadt_attach(struct device *parent, struct device *self, void *aux)
aaa.apic_vecbase = entry->madt_ioapic.global_int_base;
config_found(mainbus, &aaa, acpimadt_print);
+ nioapic++;
break;
case ACPI_MADT_LAPIC_NMI:
nlapic_nmis++;
@@ -337,6 +337,18 @@ acpimadt_attach(struct device *parent, struct device *self, void *aux)
addr += entry->madt_lapic.length;
}
+ /*
+ * Only switch to APIC-mode bus tables when at least one I/O APIC
+ * was found. Without an I/O APIC, PCI interrupt routing must use
+ * the legacy PIC path; setting mp_busses to a non-NULL empty table
+ * would cause pci_intr_map to search the table, find nothing, and
+ * fail instead of falling back to the IRQ line.
+ */
+ if (nioapic) {
+ mp_busses = acpimadt_busses;
+ mp_nbusses = nitems(acpimadt_busses);
+ }
+
mp_intrs = mallocarray(nlapic_nmis, sizeof(struct mp_intr_map),
M_DEVBUF, M_NOWAIT);
if (mp_intrs == NULL)
@@ -361,6 +373,8 @@ acpimadt_attach(struct device *parent, struct device *self, void *aux)
pin = entry->madt_override.global_int;
apic = ioapic_find_bybase(pin);
+ if (apic == NULL)
+ break;
map = malloc(sizeof(*map), M_DEVBUF, M_NOWAIT | M_ZERO);
if (map == NULL)
@@ -443,6 +457,8 @@ acpimadt_attach(struct device *parent, struct device *self, void *aux)
continue;
apic = ioapic_find_bybase(pin);
+ if (apic == NULL)
+ continue;
map = malloc(sizeof(*map), M_DEVBUF, M_NOWAIT | M_ZERO);
if (map == NULL)
--
2.54.0
[3/5] acpimadt: fix null dereference and mp_busses misuse without I/O APIC