moby/hyperkit

Segfault in ACPI table generation if no PCI devices instantiated

povik opened this issue · 5 comments

povik commented

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;
}
ijc commented

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.

ijc commented

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.

povik commented

Does it work if you return before the dsdt_fixup call if bi == 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.

ijc commented

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?

povik commented

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.