Skip to content

Commit 7c97ee7

Browse files
committed
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
2 parents dd81c65 + 0bd9611 commit 7c97ee7

8 files changed

Lines changed: 16 additions & 0 deletions

File tree

drivers/pci/controller/cadence/pcie-cadence-host.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,8 +366,10 @@ void cdns_pcie_host_disable(struct cdns_pcie_rc *rc)
366366
struct pci_host_bridge *bridge;
367367

368368
bridge = pci_host_bridge_from_priv(rc);
369+
pci_lock_rescan_remove();
369370
pci_stop_root_bus(bridge->bus);
370371
pci_remove_root_bus(bridge->bus);
372+
pci_unlock_rescan_remove();
371373

372374
cdns_pcie_host_deinit(rc);
373375
cdns_pcie_host_link_disable(rc);

drivers/pci/controller/dwc/pcie-designware-host.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -705,8 +705,10 @@ void dw_pcie_host_deinit(struct dw_pcie_rp *pp)
705705

706706
dwc_pcie_debugfs_deinit(pci);
707707

708+
pci_lock_rescan_remove();
708709
pci_stop_root_bus(pp->bridge->bus);
709710
pci_remove_root_bus(pp->bridge->bus);
711+
pci_unlock_rescan_remove();
710712

711713
dw_pcie_stop_link(pci);
712714

drivers/pci/controller/pcie-altera.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,8 +1075,10 @@ static void altera_pcie_remove(struct platform_device *pdev)
10751075
struct altera_pcie *pcie = platform_get_drvdata(pdev);
10761076
struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
10771077

1078+
pci_lock_rescan_remove();
10781079
pci_stop_root_bus(bridge->bus);
10791080
pci_remove_root_bus(bridge->bus);
1081+
pci_unlock_rescan_remove();
10801082
altera_pcie_irq_teardown(pcie);
10811083
}
10821084

drivers/pci/controller/pcie-brcmstb.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1894,8 +1894,10 @@ static void brcm_pcie_remove(struct platform_device *pdev)
18941894
struct brcm_pcie *pcie = platform_get_drvdata(pdev);
18951895
struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
18961896

1897+
pci_lock_rescan_remove();
18971898
pci_stop_root_bus(bridge->bus);
18981899
pci_remove_root_bus(bridge->bus);
1900+
pci_unlock_rescan_remove();
18991901
if (pcie->cfg->has_err_report)
19001902
brcm_unregister_die_notifiers(pcie);
19011903

drivers/pci/controller/pcie-iproc.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1528,8 +1528,10 @@ void iproc_pcie_remove(struct iproc_pcie *pcie)
15281528
{
15291529
struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
15301530

1531+
pci_lock_rescan_remove();
15311532
pci_stop_root_bus(host->bus);
15321533
pci_remove_root_bus(host->bus);
1534+
pci_unlock_rescan_remove();
15331535

15341536
iproc_pcie_msi_disable(pcie);
15351537

drivers/pci/controller/pcie-mediatek.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1196,8 +1196,10 @@ static void mtk_pcie_remove(struct platform_device *pdev)
11961196
struct mtk_pcie *pcie = platform_get_drvdata(pdev);
11971197
struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
11981198

1199+
pci_lock_rescan_remove();
11991200
pci_stop_root_bus(host->bus);
12001201
pci_remove_root_bus(host->bus);
1202+
pci_unlock_rescan_remove();
12011203
mtk_pcie_free_resources(pcie);
12021204

12031205
mtk_pcie_irq_teardown(pcie);

drivers/pci/controller/pcie-rockchip-host.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,8 +1012,10 @@ static void rockchip_pcie_remove(struct platform_device *pdev)
10121012
struct rockchip_pcie *rockchip = dev_get_drvdata(dev);
10131013
struct pci_host_bridge *bridge = pci_host_bridge_from_priv(rockchip);
10141014

1015+
pci_lock_rescan_remove();
10151016
pci_stop_root_bus(bridge->bus);
10161017
pci_remove_root_bus(bridge->bus);
1018+
pci_unlock_rescan_remove();
10171019
irq_domain_remove(rockchip->irq_domain);
10181020

10191021
rockchip_pcie_deinit_phys(rockchip);

drivers/pci/controller/plda/pcie-plda-host.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,8 +640,10 @@ EXPORT_SYMBOL_GPL(plda_pcie_host_init);
640640

641641
void plda_pcie_host_deinit(struct plda_pcie_rp *port)
642642
{
643+
pci_lock_rescan_remove();
643644
pci_stop_root_bus(port->bridge->bus);
644645
pci_remove_root_bus(port->bridge->bus);
646+
pci_unlock_rescan_remove();
645647

646648
plda_pcie_irq_domain_deinit(port);
647649

0 commit comments

Comments
 (0)