Re: [PATCH v9 11/11] PCI/CXL: Restore HDM state after CXL bus reset
From: Richard Cheng
Date: Thu Jul 16 2026 - 03:47:13 EST
On Thu, Jul 09, 2026 at 01:03:04AM +0800, Srirangan Madhavan wrote:
> 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.
>
Tested-by: Richard Cheng <icheng@xxxxxxxxxx>
> 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 f708c7b80acf..67cdc51182f7 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 ef25ba5f7fe9..b394704950a5 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -5004,6 +5004,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
>