PCI: Protect pci_reassign_bridge_resources() against concurrent addition/removal
pci_reassign_bridge_resources() can be called by pci_resize_resource() at runtime, it walks the PCI tree up and down, and it isn't currently protected against any changes or hotplug operation. Hold the pci_bus_sem to protect it. Link: https://lore.kernel.org/r/7339fd73ccaf58552737ab10008333fd9f7723f2.camel@kernel.crashing.org Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
This commit is contained in:
parent
54ecb8f702
commit
fb794a708a
|
@ -2066,6 +2066,8 @@ int pci_reassign_bridge_resources(struct pci_dev *bridge, unsigned long type)
|
|||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
down_read(&pci_bus_sem);
|
||||
|
||||
/* Walk to the root hub, releasing bridge BARs when possible */
|
||||
next = bridge;
|
||||
do {
|
||||
|
@ -2100,8 +2102,10 @@ int pci_reassign_bridge_resources(struct pci_dev *bridge, unsigned long type)
|
|||
next = bridge->bus ? bridge->bus->self : NULL;
|
||||
} while (next);
|
||||
|
||||
if (list_empty(&saved))
|
||||
if (list_empty(&saved)) {
|
||||
up_read(&pci_bus_sem);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
__pci_bus_size_bridges(bridge->subordinate, &added);
|
||||
__pci_bridge_assign_resources(bridge, &added, &failed);
|
||||
|
@ -2122,6 +2126,7 @@ int pci_reassign_bridge_resources(struct pci_dev *bridge, unsigned long type)
|
|||
}
|
||||
|
||||
free_list(&saved);
|
||||
up_read(&pci_bus_sem);
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
|
@ -2150,6 +2155,7 @@ cleanup:
|
|||
pci_setup_bridge(bridge->subordinate);
|
||||
}
|
||||
free_list(&saved);
|
||||
up_read(&pci_bus_sem);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue