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:
@@ -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--;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user