aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2025-10-03 12:13:12 -0500
committerBjorn Helgaas <bhelgaas@google.com>2025-10-03 12:13:12 -0500
commit3d56c863189dcf72118326bb4043f24907cc4f5c (patch)
tree2811e5af624660222f8d684ff1aaedbf2f7ddef8 /drivers/pci
parentMerge branch 'pci/resource' (diff)
parentPCI: Add lockdep assertion in pci_stop_and_remove_bus_device() (diff)
downloadlinux-3d56c863189dcf72118326bb4043f24907cc4f5c.tar.gz
linux-3d56c863189dcf72118326bb4043f24907cc4f5c.zip
Merge branch 'pci/virtualization'
- Add rescan/remove locking when enabling/disabling SR-IOV, which solves list corruption on s390, where disabling SR-IOV also generates hotplug events (Niklas Schnelle) - Add lockdep assertion in pci_stop_and_remove_bus_device() to catch device removal without appropriate locking (Niklas Schnelle) * pci/virtualization: PCI: Add lockdep assertion in pci_stop_and_remove_bus_device() PCI/IOV: Add PCI rescan-remove locking when enabling/disabling SR-IOV
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/iov.c5
-rw-r--r--drivers/pci/pci.h2
-rw-r--r--drivers/pci/probe.c2
-rw-r--r--drivers/pci/remove.c1
4 files changed, 9 insertions, 1 deletions
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index ac4375954c94..77dee43b7858 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -629,15 +629,18 @@ static int sriov_add_vfs(struct pci_dev *dev, u16 num_vfs)
if (dev->no_vf_scan)
return 0;
+ pci_lock_rescan_remove();
for (i = 0; i < num_vfs; i++) {
rc = pci_iov_add_virtfn(dev, i);
if (rc)
goto failed;
}
+ pci_unlock_rescan_remove();
return 0;
failed:
while (i--)
pci_iov_remove_virtfn(dev, i);
+ pci_unlock_rescan_remove();
return rc;
}
@@ -762,8 +765,10 @@ static void sriov_del_vfs(struct pci_dev *dev)
struct pci_sriov *iov = dev->sriov;
int i;
+ pci_lock_rescan_remove();
for (i = 0; i < iov->num_VFs; i++)
pci_iov_remove_virtfn(dev, i);
+ pci_unlock_rescan_remove();
}
static void sriov_disable(struct pci_dev *dev)
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 7e74fe95a44c..c1541cef82bb 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -89,6 +89,8 @@ struct pcie_tlp_log;
extern const unsigned char pcie_link_speed[];
extern bool pci_early_dump;
+extern struct mutex pci_rescan_remove_lock;
+
bool pcie_cap_has_lnkctl(const struct pci_dev *dev);
bool pcie_cap_has_lnkctl2(const struct pci_dev *dev);
bool pcie_cap_has_rtctl(const struct pci_dev *dev);
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index f63ffe2ce637..c83e75a0ec12 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -3507,7 +3507,7 @@ EXPORT_SYMBOL_GPL(pci_rescan_bus);
* pci_rescan_bus(), pci_rescan_bus_bridge_resize() and PCI device removal
* routines should always be executed under this mutex.
*/
-static DEFINE_MUTEX(pci_rescan_remove_lock);
+DEFINE_MUTEX(pci_rescan_remove_lock);
void pci_lock_rescan_remove(void)
{
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index 16f21edbc29d..ce5c25adef55 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -140,6 +140,7 @@ static void pci_remove_bus_device(struct pci_dev *dev)
*/
void pci_stop_and_remove_bus_device(struct pci_dev *dev)
{
+ lockdep_assert_held(&pci_rescan_remove_lock);
pci_stop_bus_device(dev);
pci_remove_bus_device(dev);
}