[SRU][N/P][PATCH 1/2] s390/pci: Fix stale function handles in error handling
Massimiliano Pellizzer
massimiliano.pellizzer at canonical.com
Fri Aug 29 07:49:59 UTC 2025
From: Niklas Schnelle <schnelle at linux.ibm.com>
BugLink: https://bugs.launchpad.net/bugs/2121149
The error event information for PCI error events contains a function
handle for the respective function. This handle is generally captured at
the time the error event was recorded. Due to delays in processing or
cascading issues, it may happen that during firmware recovery multiple
events are generated. When processing these events in order Linux may
already have recovered an affected function making the event information
stale. Fix this by doing an unconditional CLP List PCI function
retrieving the current function handle with the zdev->state_lock held
and ignoring the event if its function handle is stale.
Cc: stable at vger.kernel.org
Fixes: 4cdf2f4e24ff ("s390/pci: implement minimal PCI error recovery")
Reviewed-by: Julian Ruess <julianr at linux.ibm.com>
Reviewed-by: Gerd Bayer <gbayer at linux.ibm.com>
Reviewed-by: Farhan Ali <alifm at linux.ibm.com>
Signed-off-by: Niklas Schnelle <schnelle at linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev at linux.ibm.com>
(cherry picked from commit 45537926dd2aaa9190ac0fac5a0fbeefcadfea95)
Signed-off-by: Massimiliano Pellizzer <massimiliano.pellizzer at canonical.com>
---
arch/s390/pci/pci_event.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/arch/s390/pci/pci_event.c b/arch/s390/pci/pci_event.c
index 2fbee3887d13..82ee2578279a 100644
--- a/arch/s390/pci/pci_event.c
+++ b/arch/s390/pci/pci_event.c
@@ -273,6 +273,8 @@ static void __zpci_event_error(struct zpci_ccdf_err *ccdf)
struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid);
struct pci_dev *pdev = NULL;
pci_ers_result_t ers_res;
+ u32 fh = 0;
+ int rc;
zpci_dbg(3, "err fid:%x, fh:%x, pec:%x\n",
ccdf->fid, ccdf->fh, ccdf->pec);
@@ -281,6 +283,15 @@ static void __zpci_event_error(struct zpci_ccdf_err *ccdf)
if (zdev) {
mutex_lock(&zdev->state_lock);
+ rc = clp_refresh_fh(zdev->fid, &fh);
+ if (rc)
+ goto no_pdev;
+ if (!fh || ccdf->fh != fh) {
+ /* Ignore events with stale handles */
+ zpci_dbg(3, "err fid:%x, fh:%x (stale %x)\n",
+ ccdf->fid, fh, ccdf->fh);
+ goto no_pdev;
+ }
zpci_update_fh(zdev, ccdf->fh);
if (zdev->zbus->bus)
pdev = pci_get_slot(zdev->zbus->bus, zdev->devfn);
--
2.48.1
More information about the kernel-team
mailing list