From: Dave Jiang Date: Thu, 19 Mar 2026 15:25:41 +0000 (-0700) Subject: cxl: Add endpoint decoder flags clear when PCI reset happens X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7974835aa9d54125a1b6a2948f927d745748bf46;p=thirdparty%2Fkernel%2Flinux.git cxl: Add endpoint decoder flags clear when PCI reset happens 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 Reviewed-by: Alison Schofield Reviewed-by: Jonathan Cameron Link: https://patch.msgid.link/20260319152541.2739343-1-dave.jiang@intel.com Signed-off-by: Dave Jiang --- diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h index 9b947286eb9b0..d09c84bcc0150 100644 --- a/drivers/cxl/cxl.h +++ b/drivers/cxl/cxl.h @@ -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, diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c index fbb300a018302..84cff73b39e59 100644 --- a/drivers/cxl/pci.c +++ b/drivers/cxl/pci.c @@ -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);