]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
cxl: Add endpoint decoder flags clear when PCI reset happens
authorDave Jiang <dave.jiang@intel.com>
Thu, 19 Mar 2026 15:25:41 +0000 (08:25 -0700)
committerDave Jiang <dave.jiang@intel.com>
Fri, 20 Mar 2026 15:38:45 +0000 (08:38 -0700)
When a PCI reset happens, the lock and enable flags of the CXL device
should be cleared to avoid stale state flags after reset. Add flag
clearing during cxl_reset_done() to clear the relevant endpoint
decoder flags for all decoders of the endpoint device.

Reported-by: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: Alison Schofield <alison.schofield@intel.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Link: https://patch.msgid.link/20260319152541.2739343-1-dave.jiang@intel.com
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
drivers/cxl/cxl.h
drivers/cxl/pci.c

index 9b947286eb9b013dc1f7753766f4e601faedb816..d09c84bcc0150c491dc3d02b9d6247682f911426 100644 (file)
@@ -333,6 +333,7 @@ int cxl_dport_map_rcd_linkcap(struct pci_dev *pdev, struct cxl_dport *dport);
 #define CXL_DECODER_F_LOCK  BIT(4)
 #define CXL_DECODER_F_ENABLE    BIT(5)
 #define CXL_DECODER_F_NORMALIZED_ADDRESSING BIT(6)
+#define CXL_DECODER_F_RESET_MASK (CXL_DECODER_F_ENABLE | CXL_DECODER_F_LOCK)
 
 enum cxl_decoder_type {
        CXL_DECODER_DEVMEM = 2,
index fbb300a018302134cd044f9a799173d1d4d819ad..84cff73b39e59c2123ce2cbb360d03947cd1c768 100644 (file)
@@ -1030,6 +1030,19 @@ static void cxl_error_resume(struct pci_dev *pdev)
                 dev->driver ? "successful" : "failed");
 }
 
+static int cxl_endpoint_decoder_clear_reset_flags(struct device *dev, void *data)
+{
+       struct cxl_endpoint_decoder *cxled;
+
+       if (!is_endpoint_decoder(dev))
+               return 0;
+
+       cxled = to_cxl_endpoint_decoder(dev);
+       cxled->cxld.flags &= ~CXL_DECODER_F_RESET_MASK;
+
+       return 0;
+}
+
 static void cxl_reset_done(struct pci_dev *pdev)
 {
        struct cxl_dev_state *cxlds = pci_get_drvdata(pdev);
@@ -1045,6 +1058,9 @@ static void cxl_reset_done(struct pci_dev *pdev)
        guard(device)(&cxlmd->dev);
        if (cxlmd->endpoint &&
            cxl_endpoint_decoder_reset_detected(cxlmd->endpoint)) {
+               device_for_each_child(&cxlmd->endpoint->dev, NULL,
+                                     cxl_endpoint_decoder_clear_reset_flags);
+
                dev_crit(dev, "SBR happened without memory regions removal.\n");
                dev_crit(dev, "System may be unstable if regions hosted system memory.\n");
                add_taint(TAINT_USER, LOCKDEP_STILL_OK);