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) {
|
if (pci_controller_init() != B_OK) {
|
||||||
TRACE(("PCI: pci_controller_init failed\n"));
|
TRACE(("PCI: pci_controller_init failed\n"));
|
||||||
|
panic("PCI: pci_controller_init failed\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -830,6 +831,15 @@ PCI::_FixupDevices(int domain, uint8 bus)
|
|||||||
FLOW("PCI: FixupDevices domain %u, bus %u\n", domain, bus);
|
FLOW("PCI: FixupDevices domain %u, bus %u\n", domain, bus);
|
||||||
|
|
||||||
int maxBusDevices = _GetDomainData(domain)->max_bus_devices;
|
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++) {
|
for (int dev = 0; dev < maxBusDevices; dev++) {
|
||||||
uint16 vendorId = ReadConfig(domain, bus, dev, 0, PCI_vendor_id, 2);
|
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,
|
int busBehindBridge = ReadConfig(domain, bus, dev, function,
|
||||||
PCI_secondary_bus, 1);
|
PCI_secondary_bus, 1);
|
||||||
|
|
||||||
|
TRACE(("PCI: FixupDevices: checking bus %d behind %04x:%04x\n",
|
||||||
|
busBehindBridge, vendorId, deviceId));
|
||||||
_FixupDevices(domain, busBehindBridge);
|
_FixupDevices(domain, busBehindBridge);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
recursed--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -981,6 +994,15 @@ PCI::_DiscoverBus(PCIBus *bus)
|
|||||||
FLOW("PCI: DiscoverBus, domain %u, bus %u\n", bus->domain, bus->bus);
|
FLOW("PCI: DiscoverBus, domain %u, bus %u\n", bus->domain, bus->bus);
|
||||||
|
|
||||||
int maxBusDevices = _GetDomainData(bus->domain)->max_bus_devices;
|
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++) {
|
for (int dev = 0; dev < maxBusDevices; dev++) {
|
||||||
uint16 vendorID = ReadConfig(bus->domain, bus->bus, dev, 0,
|
uint16 vendorID = ReadConfig(bus->domain, bus->bus, dev, 0,
|
||||||
@@ -995,6 +1017,7 @@ PCI::_DiscoverBus(PCIBus *bus)
|
|||||||
|
|
||||||
if (bus->next)
|
if (bus->next)
|
||||||
_DiscoverBus(bus->next);
|
_DiscoverBus(bus->next);
|
||||||
|
recursed--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user