[PATCH 04/20] cxl: Media ready check refactoring

mhonap@nvidia.com posted 20 patches 3 weeks, 5 days ago
There is a newer version of this series
[PATCH 04/20] cxl: Media ready check refactoring
Posted by mhonap@nvidia.com 3 weeks, 5 days ago
From: Manish Honap <mhonap@nvidia.com>

Before accessing CXL device memory after reset/power-on, the driver
must ensure media is ready. Not every CXL device implements the CXL
Memory Device register group (many Type-2 devices do not).
cxl_await_media_ready() reads cxlds->regs.memdev; calling it
on a Type-2 without that block can result in kernel panic.

This commit refactors the HDM range based check in a new function which
can be safely used for type-2 and type-3 devices. cxl_await_media_ready
still uses the same format of checking the HDM range and memory device
register status.

Co-developed-by: Zhi Wang <zhiw@nvidia.com>
Signed-off-by: Zhi Wang <zhiw@nvidia.com>
Signed-off-by: Manish Honap <mhonap@nvidia.com>
---
 drivers/cxl/core/pci.c | 35 ++++++++++++++++++++++++++++++-----
 include/cxl/cxl.h      |  1 +
 2 files changed, 31 insertions(+), 5 deletions(-)

diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
index 52ed0b4f5e78..2b7e4d73a6dd 100644
--- a/drivers/cxl/core/pci.c
+++ b/drivers/cxl/core/pci.c
@@ -142,16 +142,24 @@ static int cxl_dvsec_mem_range_active(struct cxl_dev_state *cxlds, int id)
 	return 0;
 }
 
-/*
- * Wait up to @media_ready_timeout for the device to report memory
- * active.
+/**
+ * cxl_await_range_active - Wait for all HDM DVSEC memory ranges to be active
+ * @cxlds: CXL device state (DVSEC and HDM count must be valid)
+ *
+ * For each HDM decoder range reported in the CXL DVSEC capability, waits for
+ * the range to report MEM INFO VALID (up to 1s per range), then MEM ACTIVE
+ * (up to media_ready_timeout seconds per range, default 60s). Used by
+ * cxl_await_media_ready() and by callers that only need range readiness
+ * without checking the memory device status register.
+ *
+ * Return: 0 if all ranges become valid and active, -ETIMEDOUT if a timeout
+ * occurs, or a negative errno from config read on failure.
  */
-int cxl_await_media_ready(struct cxl_dev_state *cxlds)
+int cxl_await_range_active(struct cxl_dev_state *cxlds)
 {
 	struct pci_dev *pdev = to_pci_dev(cxlds->dev);
 	int d = cxlds->cxl_dvsec;
 	int rc, i, hdm_count;
-	u64 md_status;
 	u16 cap;
 
 	rc = pci_read_config_word(pdev,
@@ -172,6 +180,23 @@ int cxl_await_media_ready(struct cxl_dev_state *cxlds)
 			return rc;
 	}
 
+	return 0;
+}
+EXPORT_SYMBOL_NS_GPL(cxl_await_range_active, "CXL");
+
+/*
+ * Wait up to @media_ready_timeout for the device to report memory
+ * active.
+ */
+int cxl_await_media_ready(struct cxl_dev_state *cxlds)
+{
+	u64 md_status;
+	int rc;
+
+	rc = cxl_await_range_active(cxlds);
+	if (rc)
+		return rc;
+
 	md_status = readq(cxlds->regs.memdev + CXLMDEV_STATUS_OFFSET);
 	if (!CXLMDEV_READY(md_status))
 		return -EIO;
diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
index 27c006fa53c3..684603799fb1 100644
--- a/include/cxl/cxl.h
+++ b/include/cxl/cxl.h
@@ -323,5 +323,6 @@ int cxl_find_regblock(struct pci_dev *pdev, enum cxl_regloc_type type,
 		      struct cxl_register_map *map);
 void cxl_probe_component_regs(struct device *dev, void __iomem *base,
 			      struct cxl_component_reg_map *map);
+int cxl_await_range_active(struct cxl_dev_state *cxlds);
 
 #endif /* __CXL_CXL_H__ */
-- 
2.25.1
Re: [PATCH 04/20] cxl: Media ready check refactoring
Posted by Dave Jiang 3 weeks, 4 days ago

On 3/11/26 1:34 PM, mhonap@nvidia.com wrote:
> From: Manish Honap <mhonap@nvidia.com>
> 
> Before accessing CXL device memory after reset/power-on, the driver
> must ensure media is ready. Not every CXL device implements the CXL
> Memory Device register group (many Type-2 devices do not).
> cxl_await_media_ready() reads cxlds->regs.memdev; calling it
> on a Type-2 without that block can result in kernel panic.

please consider:
Access the memory device registers on a Type-2 device may result in kernel panic.

> 
> This commit refactors the HDM range based check in a new function which
> can be safely used for type-2 and type-3 devices. cxl_await_media_ready
> still uses the same format of checking the HDM range and memory device
> register status.
> 
> Co-developed-by: Zhi Wang <zhiw@nvidia.com>
> Signed-off-by: Zhi Wang <zhiw@nvidia.com>
> Signed-off-by: Manish Honap <mhonap@nvidia.com>

Reviewed-by: Dave Jiang <dave.jiang@intel.com>

> ---
>  drivers/cxl/core/pci.c | 35 ++++++++++++++++++++++++++++++-----
>  include/cxl/cxl.h      |  1 +
>  2 files changed, 31 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
> index 52ed0b4f5e78..2b7e4d73a6dd 100644
> --- a/drivers/cxl/core/pci.c
> +++ b/drivers/cxl/core/pci.c
> @@ -142,16 +142,24 @@ static int cxl_dvsec_mem_range_active(struct cxl_dev_state *cxlds, int id)
>  	return 0;
>  }
>  
> -/*
> - * Wait up to @media_ready_timeout for the device to report memory
> - * active.
> +/**
> + * cxl_await_range_active - Wait for all HDM DVSEC memory ranges to be active
> + * @cxlds: CXL device state (DVSEC and HDM count must be valid)
> + *
> + * For each HDM decoder range reported in the CXL DVSEC capability, waits for
> + * the range to report MEM INFO VALID (up to 1s per range), then MEM ACTIVE
> + * (up to media_ready_timeout seconds per range, default 60s). Used by
> + * cxl_await_media_ready() and by callers that only need range readiness
> + * without checking the memory device status register.
> + *
> + * Return: 0 if all ranges become valid and active, -ETIMEDOUT if a timeout
> + * occurs, or a negative errno from config read on failure.
>   */
> -int cxl_await_media_ready(struct cxl_dev_state *cxlds)
> +int cxl_await_range_active(struct cxl_dev_state *cxlds)
>  {
>  	struct pci_dev *pdev = to_pci_dev(cxlds->dev);
>  	int d = cxlds->cxl_dvsec;
>  	int rc, i, hdm_count;
> -	u64 md_status;
>  	u16 cap;
>  
>  	rc = pci_read_config_word(pdev,
> @@ -172,6 +180,23 @@ int cxl_await_media_ready(struct cxl_dev_state *cxlds)
>  			return rc;
>  	}
>  
> +	return 0;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_await_range_active, "CXL");
> +
> +/*
> + * Wait up to @media_ready_timeout for the device to report memory
> + * active.
> + */
> +int cxl_await_media_ready(struct cxl_dev_state *cxlds)
> +{
> +	u64 md_status;
> +	int rc;
> +
> +	rc = cxl_await_range_active(cxlds);
> +	if (rc)
> +		return rc;
> +
>  	md_status = readq(cxlds->regs.memdev + CXLMDEV_STATUS_OFFSET);
>  	if (!CXLMDEV_READY(md_status))
>  		return -EIO;
> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
> index 27c006fa53c3..684603799fb1 100644
> --- a/include/cxl/cxl.h
> +++ b/include/cxl/cxl.h
> @@ -323,5 +323,6 @@ int cxl_find_regblock(struct pci_dev *pdev, enum cxl_regloc_type type,
>  		      struct cxl_register_map *map);
>  void cxl_probe_component_regs(struct device *dev, void __iomem *base,
>  			      struct cxl_component_reg_map *map);
> +int cxl_await_range_active(struct cxl_dev_state *cxlds);
>  
>  #endif /* __CXL_CXL_H__ */