The pseries and powernv pcibios_bus_add_device() hooks insert the device
into the EEH PE tree with bare list manipulation that
arch/powerpc/kernel/eeh.c itself flags as unlocked, and for SR-IOV the
pseries hook attaches every VF's eeh_dev to the shared physfn PE. Every
caller is serialized by enumeration context today; an upcoming change
runs pci_bus_add_device() for sibling VFs concurrently and makes the race
reachable.

Serialize the platform hook dispatch with an arch-local mutex. Exclusion
against the EEH recovery thread stays carried by pci_rescan_remove_lock,
and on probe-path enables the residue folds into the pre-existing
exposure described in a later patch in this series ("PCI/IOV: Initialize
virtual functions in parallel"). A proper PE-tree lock is a larger EEH
cleanup, so eeh_pe.c is left alone.

Assisted-by: LLM
Signed-off-by: Pavol Sakac <[email protected]>
---
 arch/powerpc/kernel/pci-common.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 4fc52c21fe5d..21cccd0e97f8 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1046,6 +1046,15 @@ void pcibios_setup_bus_self(struct pci_bus *bus)
                phb->controller_ops.dma_bus_setup(bus);
 }
 
+/*
+ * The pseries/powernv hooks update the shared EEH PE tree with no
+ * internal locking; serialize concurrent sibling VF additions.
+ * Removal-side updates do not take this lock: additions are
+ * drained before any unwind, and the sysfs enable and EEH paths
+ * hold pci_rescan_remove_lock.
+ */
+static DEFINE_MUTEX(pcibios_bus_add_device_lock);
+
 void pcibios_bus_add_device(struct pci_dev *dev)
 {
        struct pci_controller *phb;
@@ -1068,8 +1077,11 @@ void pcibios_bus_add_device(struct pci_dev *dev)
        if (ppc_md.pci_irq_fixup)
                ppc_md.pci_irq_fixup(dev);
 
-       if (ppc_md.pcibios_bus_add_device)
+       if (ppc_md.pcibios_bus_add_device) {
+               mutex_lock(&pcibios_bus_add_device_lock);
                ppc_md.pcibios_bus_add_device(dev);
+               mutex_unlock(&pcibios_bus_add_device_lock);
+       }
 }
 
 int pcibios_device_add(struct pci_dev *dev)
-- 
2.47.3


Reply via email to