summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuixin Liu <kanie@linux.alibaba.com>2026-08-31 19:04:49 +0800
committerDave Jiang <dave.jiang@intel.com>2026-09-17 20:04:19 -0700
commit17ff3a9fd8669ea53fe83a7013871f30214d5537 (patch)
tree4bebb856bcc7e11ff26cde0dbd810e1758a6c0f6
parent51493ff66ad6b1c8e904cf3ab8c69e9c59aaba0f (diff)
downloadlinux-next-17ff3a9fd8669ea53fe83a7013871f30214d5537.tar.gz
linux-next-17ff3a9fd8669ea53fe83a7013871f30214d5537.zip
cxl/pci: Skip reset detection for DVSEC emulated decoders
HDM decoders are emulated from the DVSEC range registers in two cases: (a) the component registers expose no HDM decoder capability, or (b) the capability is present but the DVSEC ranges were the ones in use at driver load. After an FLR or SBR, __cxl_endpoint_decoder_reset_detected() reads the HDM decoder Committed bit for every decoder marked enabled, emulated ones included. In case (a) regs.hdm_decoder is NULL and the read oopses. In case (b) the Committed bit was never set, so a reset gets reported that never happened. Use the absence of cxld->commit to elide the check for emulated decoders. Case (b) tested under QEMU: a reset on an endpoint driven down the DVSEC emulation path no longer reports a reset or strips the decoder flags. Fixes: 934edcd436dc ("cxl: Add post-reset warning if reset results in loss of previously committed HDM decoders") Signed-off-by: Guixin Liu <kanie@linux.alibaba.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com> Link: https://lore.kernel.org/linux-cxl/20260811113608.2815625-1-kanie@linux.alibaba.com/ Link: https://patch.msgid.link/20260831110449.719086-1-kanie@linux.alibaba.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
-rw-r--r--drivers/cxl/core/pci.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
index 9d807c1a002c..43b9b7afff29 100644
--- a/drivers/cxl/core/pci.c
+++ b/drivers/cxl/core/pci.c
@@ -683,6 +683,15 @@ static int __cxl_endpoint_decoder_reset_detected(struct device *dev, void *data)
if ((cxld->flags & CXL_DECODER_F_ENABLE) == 0)
return 0;
+ /*
+ * Decoders emulated from the DVSEC range registers have no commit
+ * callback and no HDM decoder registers to consult.
+ */
+ if (!cxld->commit) {
+ dev_warn(dev, "DVSEC emulated decode may have been cleared by reset\n");
+ return 0;
+ }
+
cxlhdm = dev_get_drvdata(&port->dev);
hdm = cxlhdm->regs.hdm_decoder;
ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(cxld->id));