Merge branch 'pci/controller/rescan_lock'

- Protect root bus removal with rescan lock in altera, brcmstb, cadence,
  dwc, iproc, mediatek, plda, rockchip to prevent use-after-free or crashes
  when racing with sysfs rescan or hotplug (Hans Zhang)

* pci/controller/rescan_lock:
  PCI: rockchip: Protect root bus removal with rescan lock
  PCI: plda: Protect root bus removal with rescan lock
  PCI: mediatek: Protect root bus removal with rescan lock
  PCI: iproc: Protect root bus removal with rescan lock
  PCI: dwc: Protect root bus removal with rescan lock
  PCI: cadence: Protect root bus removal with rescan lock
  PCI: brcmstb: Protect root bus removal with rescan lock
  PCI: altera: Protect root bus removal with rescan lock
This commit is contained in:
Bjorn Helgaas 2026-06-23 17:32:23 -05:00
commit 7c97ee7c49
8 changed files with 16 additions and 0 deletions

View File

@ -366,8 +366,10 @@ void cdns_pcie_host_disable(struct cdns_pcie_rc *rc)
struct pci_host_bridge *bridge;
bridge = pci_host_bridge_from_priv(rc);
pci_lock_rescan_remove();
pci_stop_root_bus(bridge->bus);
pci_remove_root_bus(bridge->bus);
pci_unlock_rescan_remove();
cdns_pcie_host_deinit(rc);
cdns_pcie_host_link_disable(rc);

View File

@ -705,8 +705,10 @@ void dw_pcie_host_deinit(struct dw_pcie_rp *pp)
dwc_pcie_debugfs_deinit(pci);
pci_lock_rescan_remove();
pci_stop_root_bus(pp->bridge->bus);
pci_remove_root_bus(pp->bridge->bus);
pci_unlock_rescan_remove();
dw_pcie_stop_link(pci);

View File

@ -1075,8 +1075,10 @@ static void altera_pcie_remove(struct platform_device *pdev)
struct altera_pcie *pcie = platform_get_drvdata(pdev);
struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
pci_lock_rescan_remove();
pci_stop_root_bus(bridge->bus);
pci_remove_root_bus(bridge->bus);
pci_unlock_rescan_remove();
altera_pcie_irq_teardown(pcie);
}

View File

@ -1894,8 +1894,10 @@ static void brcm_pcie_remove(struct platform_device *pdev)
struct brcm_pcie *pcie = platform_get_drvdata(pdev);
struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
pci_lock_rescan_remove();
pci_stop_root_bus(bridge->bus);
pci_remove_root_bus(bridge->bus);
pci_unlock_rescan_remove();
if (pcie->cfg->has_err_report)
brcm_unregister_die_notifiers(pcie);

View File

@ -1528,8 +1528,10 @@ void iproc_pcie_remove(struct iproc_pcie *pcie)
{
struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
pci_lock_rescan_remove();
pci_stop_root_bus(host->bus);
pci_remove_root_bus(host->bus);
pci_unlock_rescan_remove();
iproc_pcie_msi_disable(pcie);

View File

@ -1196,8 +1196,10 @@ static void mtk_pcie_remove(struct platform_device *pdev)
struct mtk_pcie *pcie = platform_get_drvdata(pdev);
struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
pci_lock_rescan_remove();
pci_stop_root_bus(host->bus);
pci_remove_root_bus(host->bus);
pci_unlock_rescan_remove();
mtk_pcie_free_resources(pcie);
mtk_pcie_irq_teardown(pcie);

View File

@ -1012,8 +1012,10 @@ static void rockchip_pcie_remove(struct platform_device *pdev)
struct rockchip_pcie *rockchip = dev_get_drvdata(dev);
struct pci_host_bridge *bridge = pci_host_bridge_from_priv(rockchip);
pci_lock_rescan_remove();
pci_stop_root_bus(bridge->bus);
pci_remove_root_bus(bridge->bus);
pci_unlock_rescan_remove();
irq_domain_remove(rockchip->irq_domain);
rockchip_pcie_deinit_phys(rockchip);

View File

@ -640,8 +640,10 @@ EXPORT_SYMBOL_GPL(plda_pcie_host_init);
void plda_pcie_host_deinit(struct plda_pcie_rp *port)
{
pci_lock_rescan_remove();
pci_stop_root_bus(port->bridge->bus);
pci_remove_root_bus(port->bridge->bus);
pci_unlock_rescan_remove();
plda_pcie_irq_domain_deinit(port);