[PATCH RFC] PCI/CXL: Restore HDM state after CXL bus reset
From: Srirangan Madhavan
Date: Fri Jul 03 2026 - 18:09:09 EST
CXL bus reset can clear HDM global control and decoder programming.
Restore cached HDM state after a successful cxl_bus reset while the
IOMMU reset block remains active.
This intentionally restores only the HDM component decoder state cached
by the CXL reset support. It does not attempt to restore CXL Device DVSEC
range/control registers.
This was exercised with cxl_bus reset on a CXL Type 2 device. Testing
confirmed that CXL Device DVSEC range/control state is a separate restore
class from HDM component decoder state.
This depends on the CXL reset series because it reuses the HDM state cache
and restore helper introduced there
Signed-off-by: Srirangan Madhavan <smadhavan@xxxxxxxxxx>
---
drivers/cxl/core/reset.c | 5 +++++
drivers/pci/pci.c | 3 +++
include/cxl/cxl.h | 6 ++++++
3 files changed, 14 insertions(+)
diff --git a/drivers/cxl/core/reset.c b/drivers/cxl/core/reset.c
index cfb9b5101c28..b889687d69d8 100644
--- a/drivers/cxl/core/reset.c
+++ b/drivers/cxl/core/reset.c
@@ -894,6 +894,11 @@ static int cxl_restore_hdm_decoders(struct cxl_reset_context *ctx)
return cxl_restore_hdm(ctx->target);
}
+int cxl_restore_hdm_after_pci_reset(struct pci_dev *pdev)
+{
+ return cxl_restore_hdm(pdev);
+}
+
static void cxl_hdm_range_context_init(struct cxl_hdm_range_context *ctx)
{
INIT_LIST_HEAD(&ctx->ranges);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 7521e705f718..88fa3117e0e7 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -4972,6 +4972,9 @@ static int cxl_reset_bus_function(struct pci_dev *dev, bool probe)
pci_write_config_word(bridge, dvsec + PCI_DVSEC_CXL_PORT_CTL,
reg);
+ if (!rc)
+ rc = cxl_restore_hdm_after_pci_reset(dev);
+
pci_dev_reset_iommu_done(dev);
return rc;
}
diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
index de58f484b7d9..c1019e1b3b27 100644
--- a/include/cxl/cxl.h
+++ b/include/cxl/cxl.h
@@ -154,6 +154,7 @@ int cxl_commit(struct cxl_decoder_settings *settings, void __iomem *hdm);
#ifdef CONFIG_CXL_HDM
void pci_cxl_hdm_init(struct pci_dev *pdev);
void pci_cxl_hdm_release(struct pci_dev *pdev);
+int cxl_restore_hdm_after_pci_reset(struct pci_dev *pdev);
int cxl_reset_function(struct pci_dev *pdev, bool probe);
#else
static inline void pci_cxl_hdm_init(struct pci_dev *pdev)
@@ -164,6 +165,11 @@ static inline void pci_cxl_hdm_release(struct pci_dev *pdev)
{
}
+static inline int cxl_restore_hdm_after_pci_reset(struct pci_dev *pdev)
+{
+ return 0;
+}
+
static inline int cxl_reset_function(struct pci_dev *pdev, bool probe)
{
return -ENOTTY;
--
2.43.0