Skip to content

Commit

Permalink
PCI: Make sure bus number resources stay within their parents bounds
Browse files Browse the repository at this point in the history
Right now we use 0xff for busn_res.end when probing and later reduce it to
the value that is actually used. This does not work if a parent bridge has
already a lower subordinate value. For example during hotplug of a new
bridge below an already-configured bridge the following message is printed
from pci_bus_insert_busn_res():

  pci_bus 0000:06: busn_res: can not insert [bus 06-ff] under [bus 05-9b] (conflicts with (null) [bus 05-9b])

This patch clamps the bus range to that of the parent and also ensures that
we do not exceed the parents range when assigning the final subordinate
value.

We also check that busses configured by the firmware fit into their parents
bounds.

[bhelgaas: reword dev_warn() and fix printk format warning]
Signed-off-by: Andreas Noever <andreas.noever@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
  • Loading branch information
Andreas Noever authored and Bjorn Helgaas committed Feb 11, 2014
1 parent ced04d1 commit 1820ffd
Showing 1 changed file with 8 additions and 2 deletions.
10 changes: 8 additions & 2 deletions drivers/pci/probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -782,7 +782,7 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
/* Check if setup is sensible at all */
if (!pass &&
(primary != bus->number || secondary <= bus->number ||
secondary > subordinate)) {
secondary > subordinate || subordinate > bus->busn_res.end)) {
dev_info(&dev->dev, "bridge configuration invalid ([bus %02x-%02x]), reconfiguring\n",
secondary, subordinate);
broken = 1;
Expand Down Expand Up @@ -854,7 +854,8 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
child = pci_add_new_bus(bus, dev, max+1);
if (!child)
goto out;
pci_bus_insert_busn_res(child, max+1, 0xff);
pci_bus_insert_busn_res(child, max+1,
bus->busn_res.end);
}
max++;
buses = (buses & 0xff000000)
Expand Down Expand Up @@ -927,6 +928,11 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
/*
* Set the subordinate bus number to its real value.
*/
if (max > bus->busn_res.end) {
dev_warn(&dev->dev, "max busn %02x is outside %pR\n",
max, &bus->busn_res);
max = bus->busn_res.end;
}
pci_bus_update_busn_res_end(child, max);
pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max);
}
Expand Down

0 comments on commit 1820ffd

Please sign in to comment.