[PATCH] powerpc/rtas_pci: No hotplug on permanently removed device on pSeries

Shivaprasad G Bhat sbhat at linux.ibm.com
Mon Apr 27 12:55:19 AEST 2026


The eeh_driver disables and offlines the PE permanently when it
exceeds the freeze count beyond eeh_max_freeze within the last hour.
The PE is only offline, so the device tree entries, eeh device
references are all intact till the real unplug of the device from
the guest/host takes place.

On pSeries, with a new hotplug of any PCI device, the drmgr initiates
a system-wide PCI rescan, which finds devices offlined by the eeh_driver
and there will be attempts to bring them online. This leads to
recurring EEHs either at the config read time itself or a bit
later depending on the type of the problem.

For PowerNV, the commit d2b0f6f77ee5 ("powerpc/eeh: No hotplug on
permanently removed dev") introduced the EEH_DEV_REMOVED flag to
prevent such inadvertent rescans on hierarchical toplogies relavent in
Baremetal setups. For pSeries, such topologies don't really make sense
as the devices are either part of the same PE OR exposed as independent
devices on multiple virtual PHBs. However, the inadvertent rescans are
still a possibility with either hotplug of a new device or otherwise
with manual system-wide pci bus rescan attempts.

So the patch checks for EEH_DEV_REMOVED before allowing config space
access just like PowerNV, making the PCI core omit the PE, and thus
preventing subsequent EEH recurances. The patch is tested on PowerVM
and KVM machines with single and multi-function devices, and on the
devices behind a switch. The unplug of the affected devices post EEH
removal is also working fine as expected.

Signed-off-by: Shivaprasad G Bhat <sbhat at linux.ibm.com>
References: d2b0f6f77ee5 ("powerpc/eeh: No hotplug on permanently removed dev")
---
 arch/powerpc/kernel/rtas_pci.c |    6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
index fccf96e897f6..ce24b18712ca 100644
--- a/arch/powerpc/kernel/rtas_pci.c
+++ b/arch/powerpc/kernel/rtas_pci.c
@@ -57,6 +57,9 @@ int rtas_pci_dn_read_config(struct pci_dn *pdn, int where, int size, u32 *val)
 	if (pdn->edev && pdn->edev->pe &&
 	    (pdn->edev->pe->state & EEH_PE_CFG_BLOCKED))
 		return PCIBIOS_SET_FAILED;
+
+	if (pdn->edev && pdn->edev->mode & EEH_DEV_REMOVED)
+		return PCIBIOS_SET_FAILED;
 #endif
 
 	addr = rtas_config_addr(pdn->busno, pdn->devfn, where);
@@ -108,6 +111,9 @@ int rtas_pci_dn_write_config(struct pci_dn *pdn, int where, int size, u32 val)
 	if (pdn->edev && pdn->edev->pe &&
 	    (pdn->edev->pe->state & EEH_PE_CFG_BLOCKED))
 		return PCIBIOS_SET_FAILED;
+
+	if (pdn->edev && pdn->edev->mode & EEH_DEV_REMOVED)
+		return PCIBIOS_SET_FAILED;
 #endif
 
 	addr = rtas_config_addr(pdn->busno, pdn->devfn, where);




More information about the Linuxppc-dev mailing list