hrev43284 adds 1 changeset to branch 'master' old head: 81f3e1eeb2999a842d48f9c1ab8e2b45acf4f9ad new head: 8a5fb91c07d432b9af95e88cecbf7cd868b79d57 ---------------------------------------------------------------------------- 8a5fb91: Stricter tests for PCI bridges at interrupt routing. Validate the candidate child device a bit more by checking the device ID and the base and subclass of the device. We don't even know if the child is still on the PCI bus and some firmware may mark disabled devices by simply invalidating one of these values. Possibly fixes #8111. Added TODO concerning that we might not want to fail at all since we ensure that we matched all devices after routing preparation at which state we would notice any missing child devices anyway. [ Michael Lotz <mmlr@xxxxxxxx> ] ---------------------------------------------------------------------------- 1 files changed, 27 insertions(+), 2 deletions(-) src/system/kernel/arch/x86/irq_routing_table.cpp | 29 ++++++++++++++++- ############################################################################ Revision: hrev43284 Commit: 8a5fb91c07d432b9af95e88cecbf7cd868b79d57 URL: http://cgit.haiku-os.org/haiku/commit/?id=8a5fb91 Author: Michael Lotz <mmlr@xxxxxxxx> Date: Fri Nov 18 11:57:26 2011 UTC Ticket: https://dev.haiku-os.org/ticket/8111 Stricter tests for PCI bridges at interrupt routing. Validate the candidate child device a bit more by checking the device ID and the base and subclass of the device. We don't even know if the child is still on the PCI bus and some firmware may mark disabled devices by simply invalidating one of these values. Possibly fixes #8111. Added TODO concerning that we might not want to fail at all since we ensure that we matched all devices after routing preparation at which state we would notice any missing child devices anyway. ---------------------------------------------------------------------------- diff --git a/src/system/kernel/arch/x86/irq_routing_table.cpp b/src/system/kernel/arch/x86/irq_routing_table.cpp index a9e46c7..48d386d 100644 --- a/src/system/kernel/arch/x86/irq_routing_table.cpp +++ b/src/system/kernel/arch/x86/irq_routing_table.cpp @@ -595,6 +595,26 @@ read_irq_routing_table_recursive(acpi_module_info* acpi, pci_module_info* pci, return B_OK; } + // Verify that the device is really present... + uint16 deviceID = pci->read_pci_config(pciAddress.bus, + pciAddress.device, pciAddress.function, PCI_device_id, 2); + if (deviceID == 0xffff) { + // Not present or disabled. + TRACE("device not present\n"); + return B_OK; + } + + // ... and that it really is a PCI bridge we support. + uint8 baseClass = pci->read_pci_config(pciAddress.bus, + pciAddress.device, pciAddress.function, PCI_class_base, 1); + uint8 subClass = pci->read_pci_config(pciAddress.bus, + pciAddress.device, pciAddress.function, PCI_class_sub, 1); + if (baseClass != PCI_bridge || subClass != PCI_pci) { + // Not a bridge or an unsupported one. + TRACE("not a PCI bridge\n"); + return B_OK; + } + uint8 headerType = pci->read_pci_config(pciAddress.bus, pciAddress.device, pciAddress.function, PCI_header_type, 1); @@ -605,8 +625,8 @@ read_irq_routing_table_recursive(acpi_module_info* acpi, pci_module_info* pci, break; default: - // Simply not a bridge or not present at all. - TRACE("not a PCI bridge (0x%02x)\n", headerType); + // Unsupported header type. + TRACE("unsupported header type (0x%02x)\n", headerType); return B_OK; } @@ -625,6 +645,11 @@ read_irq_routing_table_recursive(acpi_module_info* acpi, pci_module_info* pci, dprintf("invalid secondary bus %u on primary bus %u," " can't configure irq routing of devices below\n", secondaryBus, currentBus); + // TODO: Maybe we want to just return B_OK anyway so that we don't + // fail this step. We ensure that we matched all devices at the + // end of preparation, so we'd detect missing child devices anyway + // and it would not cause us to fail for empty misconfigured busses + // that we don't actually care about. return B_ERROR; }