Segfault in ACPI table generation if no PCI devices instantiated
povik opened this issue · 5 comments
If hyperkit is launched with the -A flag and no PCI devices, it crashes.
In the code below, taken from src/lib/pci_emul.c
, bi
gets dereferenced even though it's NULL.
static void
pci_bus_write_dsdt(int bus)
{
struct businfo *bi;
/*
* If there are no devices on this 'bus' then just return.
*/
if ((bi = pci_businfo[bus]) == NULL) {
/*
* Bus 0 is special because it decodes the I/O ports used
* for PCI config space access even if there are no devices
* on it.
*/
if (bus != 0)
return;
}
dsdt_fixup(bus, bi->iobase, bi->iolimit, bi->membase32, bi->memlimit32,
bi->membase64, bi->memlimit64);
(void) pci_pirq_prt_entry;
(void) pci_apic_prt_entry;
}
Thanks for the report @povik.
Does it work if you return before the dsdt_fixup
call if bi == NULL
?
I notice that we seem to have removed src/lib/dsdt.asl
in commit e25584d, I think that's the source to the massive binary array in acpitbl_build_dsdt
which the dsdt_fixup
call is modifying. We should probably reinstate that file as part of whatever fix we do here.
Does it work if you return...
If not then adding:
if (pci_businfo[0] == NULL)
pci_businfo[0] = calloc(1, sizeof(struct businfo));
before the loop in init_pci
would perhaps be the next thing to try, this would arrange that there was a PCI bus even if no devices were specified which seems largely harmless.
Does it work if you return before the
dsdt_fixup
call ifbi == NULL
?
The crash is avoided then. I can't comment on whether the ACPI is working properly because of the guest kernel I am running.
Thanks. This seems like an improvement even if we can't go as far as confirming ACPI is ok -- it definitely wasn't ok before.
Would you mind raising a PR with the fix?
OOI, why were you using -A
if not to get ACPI support for your guest?
The PR is there. I was toying with a Plan 9 kernel, but so far haven't made it send me anything over the console. I tried the -A flag just to see if it might help.