Guard against buggy PCI bridges

* panic on pci controller init failure. No reason to continue just to crash later on.
* guard against buggy or misconfigured bridges (like the VIA Apollo MVP3 in my K6-2)
by limiting the recursion depth in FixupDevices and DiscoverBus.
This commit is contained in:
François Revol
2011-12-23 16:58:58 +01:00
parent 78ce5eb732
commit a90b9b0221
@@ -469,6 +469,7 @@ pci_init(void)
if (pci_controller_init() != B_OK) {
TRACE(("PCI: pci_controller_init failed\n"));
panic("PCI: pci_controller_init failed\n");
return B_ERROR;
}
@@ -830,6 +831,15 @@ PCI::_FixupDevices(int domain, uint8 bus)
FLOW("PCI: FixupDevices domain %u, bus %u\n", domain, bus);
int maxBusDevices = _GetDomainData(domain)->max_bus_devices;
static int recursed = 0;
if (recursed++ > 10) {
// guard against buggy chipsets
// XXX: is there any official limit ?
dprintf("PCI: FixupDevices: too many recursions (buggy chipset?)\n");
recursed--;
return;
}
for (int dev = 0; dev < maxBusDevices; dev++) {
uint16 vendorId = ReadConfig(domain, bus, dev, 0, PCI_vendor_id, 2);
@@ -857,9 +867,12 @@ PCI::_FixupDevices(int domain, uint8 bus)
int busBehindBridge = ReadConfig(domain, bus, dev, function,
PCI_secondary_bus, 1);
TRACE(("PCI: FixupDevices: checking bus %d behind %04x:%04x\n",
busBehindBridge, vendorId, deviceId));
_FixupDevices(domain, busBehindBridge);
}
}
recursed--;
}
@@ -981,6 +994,15 @@ PCI::_DiscoverBus(PCIBus *bus)
FLOW("PCI: DiscoverBus, domain %u, bus %u\n", bus->domain, bus->bus);
int maxBusDevices = _GetDomainData(bus->domain)->max_bus_devices;
static int recursed = 0;
if (recursed++ > 10) {
// guard against buggy chipsets
// XXX: is there any official limit ?
dprintf("PCI: DiscoverBus: too many recursions (buggy chipset?)\n");
recursed--;
return;
}
for (int dev = 0; dev < maxBusDevices; dev++) {
uint16 vendorID = ReadConfig(bus->domain, bus->bus, dev, 0,
@@ -995,6 +1017,7 @@ PCI::_DiscoverBus(PCIBus *bus)
if (bus->next)
_DiscoverBus(bus->next);
recursed--;
}