[PATCH v9 13/13] cxl: Disable HPA/SPA translation handlers for Normalized Addressing

Robert Richter posted 13 patches 4 weeks, 1 day ago
There is a newer version of this series
[PATCH v9 13/13] cxl: Disable HPA/SPA translation handlers for Normalized Addressing
Posted by Robert Richter 4 weeks, 1 day ago
The root decoder provides the callbacks hpa_to_spa and spa_to_hpa to
perform Host Physical Address (HPA) and System Physical Address
translations, respectively. The callbacks are required to convert
addresses when HPA != SPA. XOR interleaving depends on this mechanism,
and the necessary handlers are implemented.

The translation handlers are used for poison injection
(trace_cxl_poison, cxl_poison_inject_fops) and error handling
(cxl_event_trace_record).

In AMD Zen5 systems with Normalized Addressing, endpoint addresses are
not SPAs, and translation handlers are required for these features to
function correctly.

Now, as ACPI PRM translation could be expensive in tracing or error
handling code paths, do not yet enable translations to avoid its
intensive use. Instead, disable those features which are used only for
debugging and enhanced logging.

Introduce the flag CXL_REGION_F_NORM_ADDR that indicates Normalized
Addressing for a region and use it to disable poison injection and DPA
to HPA conversion.

Note: Dropped unused CXL_DECODER_F_MASK macro.

Signed-off-by: Robert Richter <rrichter@amd.com>
---
 drivers/cxl/core/atl.c    |  3 +++
 drivers/cxl/core/region.c | 33 +++++++++++++++++++++++++--------
 drivers/cxl/cxl.h         |  9 ++++++++-
 3 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/drivers/cxl/core/atl.c b/drivers/cxl/core/atl.c
index 09d0ea1792d9..13f1118dc026 100644
--- a/drivers/cxl/core/atl.c
+++ b/drivers/cxl/core/atl.c
@@ -169,8 +169,11 @@ static int cxl_prm_setup_root(struct cxl_root *cxl_root, void *data)
 	 * decoders in the BIOS would prevent a capable kernel (or
 	 * other operating systems) from shutting down auto-generated
 	 * regions and managing resources dynamically.
+	 *
+	 * Indicate that Normalized Addressing is enabled.
 	 */
 	cxld->flags |= CXL_DECODER_F_LOCK;
+	cxld->flags |= CXL_DECODER_F_NORM_ADDR;
 
 	ctx->hpa_range = hpa_range;
 	ctx->interleave_ways = ways;
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index 80cd77f0842e..8b68ccce1554 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -1097,14 +1097,16 @@ static int cxl_rr_assign_decoder(struct cxl_port *port, struct cxl_region *cxlr,
 	return 0;
 }
 
-static void cxl_region_set_lock(struct cxl_region *cxlr,
-				struct cxl_decoder *cxld)
+static void cxl_region_setup_flags(struct cxl_region *cxlr,
+				   struct cxl_decoder *cxld)
 {
-	if (!test_bit(CXL_DECODER_F_LOCK, &cxld->flags))
-		return;
+	if (test_bit(CXL_DECODER_F_LOCK, &cxld->flags)) {
+		set_bit(CXL_REGION_F_LOCK, &cxlr->flags);
+		clear_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags);
+	}
 
-	set_bit(CXL_REGION_F_LOCK, &cxlr->flags);
-	clear_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags);
+	if (test_bit(CXL_DECODER_F_NORM_ADDR, &cxld->flags))
+		set_bit(CXL_REGION_F_NORM_ADDR, &cxlr->flags);
 }
 
 /**
@@ -1218,7 +1220,7 @@ static int cxl_port_attach_region(struct cxl_port *port,
 		}
 	}
 
-	cxl_region_set_lock(cxlr, cxld);
+	cxl_region_setup_flags(cxlr, cxld);
 
 	rc = cxl_rr_ep_add(cxl_rr, cxled);
 	if (rc) {
@@ -2493,7 +2495,7 @@ static struct cxl_region *cxl_region_alloc(struct cxl_root_decoder *cxlrd, int i
 	device_set_pm_not_required(dev);
 	dev->bus = &cxl_bus_type;
 	dev->type = &cxl_region_type;
-	cxl_region_set_lock(cxlr, &cxlrd->cxlsd.cxld);
+	cxl_region_setup_flags(cxlr, &cxlrd->cxlsd.cxld);
 
 	return cxlr;
 }
@@ -3132,6 +3134,13 @@ u64 cxl_dpa_to_hpa(struct cxl_region *cxlr, const struct cxl_memdev *cxlmd,
 	u8 eiw = 0;
 	int pos;
 
+	/*
+	 * Conversion between SPA and DPA is not supported in
+	 * Normalized Address mode.
+	 */
+	if (test_bit(CXL_REGION_F_NORM_ADDR, &cxlr->flags))
+		return ULLONG_MAX;
+
 	for (int i = 0; i < p->nr_targets; i++) {
 		if (cxlmd == cxled_to_memdev(p->targets[i])) {
 			cxled = p->targets[i];
@@ -3922,6 +3931,14 @@ static int cxl_region_setup_poison(struct cxl_region *cxlr)
 	struct cxl_region_params *p = &cxlr->params;
 	struct dentry *dentry;
 
+	/*
+	 * Do not enable poison injection in Normalized Address mode.
+	 * Conversion between SPA and DPA is required for this, but it is
+	 * not supported in this mode.
+	 */
+	if (test_bit(CXL_REGION_F_NORM_ADDR, &cxlr->flags))
+		return 0;
+
 	/* Create poison attributes if all memdevs support the capabilities */
 	for (int i = 0; i < p->nr_targets; i++) {
 		struct cxl_endpoint_decoder *cxled = p->targets[i];
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index 20b0fd43fa7b..0ab0a86e1d4f 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -332,7 +332,7 @@ int cxl_dport_map_rcd_linkcap(struct pci_dev *pdev, struct cxl_dport *dport);
 #define CXL_DECODER_F_TYPE3 BIT(3)
 #define CXL_DECODER_F_LOCK  BIT(4)
 #define CXL_DECODER_F_ENABLE    BIT(5)
-#define CXL_DECODER_F_MASK  GENMASK(5, 0)
+#define CXL_DECODER_F_NORM_ADDR BIT(6)
 
 enum cxl_decoder_type {
 	CXL_DECODER_DEVMEM = 2,
@@ -525,6 +525,13 @@ enum cxl_partition_mode {
  */
 #define CXL_REGION_F_LOCK 2
 
+/*
+ * Indicate Normalized Addressing. Use it to disable SPA conversion if
+ * HPA != SPA and an address translation callback handler does not
+ * exist. Flag is needed by AMD Zen5 platforms.
+ */
+#define CXL_REGION_F_NORM_ADDR 3
+
 /**
  * struct cxl_region - CXL region
  * @dev: This region's device
-- 
2.47.3
Re: [PATCH v9 13/13] cxl: Disable HPA/SPA translation handlers for Normalized Addressing
Posted by Jonathan Cameron 3 weeks, 4 days ago
On Sat, 10 Jan 2026 12:46:58 +0100
Robert Richter <rrichter@amd.com> wrote:

> The root decoder provides the callbacks hpa_to_spa and spa_to_hpa to
> perform Host Physical Address (HPA) and System Physical Address
> translations, respectively. The callbacks are required to convert
> addresses when HPA != SPA. XOR interleaving depends on this mechanism,
> and the necessary handlers are implemented.
> 
> The translation handlers are used for poison injection
> (trace_cxl_poison, cxl_poison_inject_fops) and error handling
> (cxl_event_trace_record).
> 
> In AMD Zen5 systems with Normalized Addressing, endpoint addresses are
> not SPAs, and translation handlers are required for these features to
> function correctly.
> 
> Now, as ACPI PRM translation could be expensive in tracing or error
> handling code paths, do not yet enable translations to avoid its
> intensive use. Instead, disable those features which are used only for
> debugging and enhanced logging.
> 
> Introduce the flag CXL_REGION_F_NORM_ADDR that indicates Normalized
> Addressing for a region and use it to disable poison injection and DPA
> to HPA conversion.
> 
> Note: Dropped unused CXL_DECODER_F_MASK macro.

Meh, ideally that would be a precusor patch that Dave could pick up immediately.

Hopefully the whole thing merges though and so we don't have to care
about that.

Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Re: [PATCH v9 13/13] cxl: Disable HPA/SPA translation handlers for Normalized Addressing
Posted by Alison Schofield 3 weeks, 4 days ago
On Sat, Jan 10, 2026 at 12:46:58PM +0100, Robert Richter wrote:
> The root decoder provides the callbacks hpa_to_spa and spa_to_hpa to
> perform Host Physical Address (HPA) and System Physical Address
> translations, respectively. The callbacks are required to convert
> addresses when HPA != SPA. XOR interleaving depends on this mechanism,
> and the necessary handlers are implemented.
> 
> The translation handlers are used for poison injection
> (trace_cxl_poison, cxl_poison_inject_fops) and error handling
> (cxl_event_trace_record).
> 
> In AMD Zen5 systems with Normalized Addressing, endpoint addresses are
> not SPAs, and translation handlers are required for these features to
> function correctly.
> 
> Now, as ACPI PRM translation could be expensive in tracing or error
> handling code paths, do not yet enable translations to avoid its
> intensive use. Instead, disable those features which are used only for
> debugging and enhanced logging.
> 
> Introduce the flag CXL_REGION_F_NORM_ADDR that indicates Normalized
> Addressing for a region and use it to disable poison injection and DPA
> to HPA conversion.
> 
> Note: Dropped unused CXL_DECODER_F_MASK macro.

Reviewed-by: Alison Schofield <alison.schofield@intel.com>

So not for the commit log, but for my closure ;) - 

A system with normalized addressing:

will still:
	support poison listings by memdev and by region
	support poison inject and clear by memdev

they'll be different, in that:
	if a DPA address maps into a region, the region SPA mapping will
	always be ULLONG_MAX. The region name will still be available and
	valid. That same difference applies for General Media and DRAM events.
	(This is the 'enhanced logging' referred to in the commit log.)

will not:
	support poison inject or clear by region.
	(This is the 'debugging' referred to in commit log.)
Re: [PATCH v9 13/13] cxl: Disable HPA/SPA translation handlers for Normalized Addressing
Posted by Robert Richter 3 weeks, 4 days ago
On 13.01.26 19:59:05, Alison Schofield wrote:
> On Sat, Jan 10, 2026 at 12:46:58PM +0100, Robert Richter wrote:
> > The root decoder provides the callbacks hpa_to_spa and spa_to_hpa to
> > perform Host Physical Address (HPA) and System Physical Address
> > translations, respectively. The callbacks are required to convert
> > addresses when HPA != SPA. XOR interleaving depends on this mechanism,
> > and the necessary handlers are implemented.
> > 
> > The translation handlers are used for poison injection
> > (trace_cxl_poison, cxl_poison_inject_fops) and error handling
> > (cxl_event_trace_record).
> > 
> > In AMD Zen5 systems with Normalized Addressing, endpoint addresses are
> > not SPAs, and translation handlers are required for these features to
> > function correctly.
> > 
> > Now, as ACPI PRM translation could be expensive in tracing or error
> > handling code paths, do not yet enable translations to avoid its
> > intensive use. Instead, disable those features which are used only for
> > debugging and enhanced logging.
> > 
> > Introduce the flag CXL_REGION_F_NORM_ADDR that indicates Normalized
> > Addressing for a region and use it to disable poison injection and DPA
> > to HPA conversion.
> > 
> > Note: Dropped unused CXL_DECODER_F_MASK macro.
> 
> Reviewed-by: Alison Schofield <alison.schofield@intel.com>
> 
> So not for the commit log, but for my closure ;) - 
> 
> A system with normalized addressing:
> 
> will still:
> 	support poison listings by memdev and by region
> 	support poison inject and clear by memdev
> 
> they'll be different, in that:
> 	if a DPA address maps into a region, the region SPA mapping will
> 	always be ULLONG_MAX. The region name will still be available and
> 	valid. That same difference applies for General Media and DRAM events.
> 	(This is the 'enhanced logging' referred to in the commit log.)
> 
> will not:
> 	support poison inject or clear by region.
> 	(This is the 'debugging' referred to in commit log.)
> 

Good conclusion. :-) Thanks for review.

-Robert
Re: [PATCH v9 13/13] cxl: Disable HPA/SPA translation handlers for Normalized Addressing
Posted by Dave Jiang 3 weeks, 4 days ago

On 1/10/26 4:46 AM, Robert Richter wrote:
> The root decoder provides the callbacks hpa_to_spa and spa_to_hpa to
> perform Host Physical Address (HPA) and System Physical Address
> translations, respectively. The callbacks are required to convert
> addresses when HPA != SPA. XOR interleaving depends on this mechanism,
> and the necessary handlers are implemented.
> 
> The translation handlers are used for poison injection
> (trace_cxl_poison, cxl_poison_inject_fops) and error handling
> (cxl_event_trace_record).
> 
> In AMD Zen5 systems with Normalized Addressing, endpoint addresses are
> not SPAs, and translation handlers are required for these features to
> function correctly.
> 
> Now, as ACPI PRM translation could be expensive in tracing or error
> handling code paths, do not yet enable translations to avoid its
> intensive use. Instead, disable those features which are used only for
> debugging and enhanced logging.
> 
> Introduce the flag CXL_REGION_F_NORM_ADDR that indicates Normalized
> Addressing for a region and use it to disable poison injection and DPA
> to HPA conversion.
> 
> Note: Dropped unused CXL_DECODER_F_MASK macro.
> 
> Signed-off-by: Robert Richter <rrichter@amd.com>
> ---
>  drivers/cxl/core/atl.c    |  3 +++
>  drivers/cxl/core/region.c | 33 +++++++++++++++++++++++++--------
>  drivers/cxl/cxl.h         |  9 ++++++++-
>  3 files changed, 36 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/cxl/core/atl.c b/drivers/cxl/core/atl.c
> index 09d0ea1792d9..13f1118dc026 100644
> --- a/drivers/cxl/core/atl.c
> +++ b/drivers/cxl/core/atl.c
> @@ -169,8 +169,11 @@ static int cxl_prm_setup_root(struct cxl_root *cxl_root, void *data)
>  	 * decoders in the BIOS would prevent a capable kernel (or
>  	 * other operating systems) from shutting down auto-generated
>  	 * regions and managing resources dynamically.
> +	 *
> +	 * Indicate that Normalized Addressing is enabled.
>  	 */
>  	cxld->flags |= CXL_DECODER_F_LOCK;
> +	cxld->flags |= CXL_DECODER_F_NORM_ADDR;

IMO,
Spelling out NORMALIZED probably make the flag clearer the address is normalized vs a normal address.

DJ
>  
>  	ctx->hpa_range = hpa_range;
>  	ctx->interleave_ways = ways;
> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
> index 80cd77f0842e..8b68ccce1554 100644
> --- a/drivers/cxl/core/region.c
> +++ b/drivers/cxl/core/region.c
> @@ -1097,14 +1097,16 @@ static int cxl_rr_assign_decoder(struct cxl_port *port, struct cxl_region *cxlr,
>  	return 0;
>  }
>  
> -static void cxl_region_set_lock(struct cxl_region *cxlr,
> -				struct cxl_decoder *cxld)
> +static void cxl_region_setup_flags(struct cxl_region *cxlr,
> +				   struct cxl_decoder *cxld)
>  {
> -	if (!test_bit(CXL_DECODER_F_LOCK, &cxld->flags))
> -		return;
> +	if (test_bit(CXL_DECODER_F_LOCK, &cxld->flags)) {
> +		set_bit(CXL_REGION_F_LOCK, &cxlr->flags);
> +		clear_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags);
> +	}
>  
> -	set_bit(CXL_REGION_F_LOCK, &cxlr->flags);
> -	clear_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags);
> +	if (test_bit(CXL_DECODER_F_NORM_ADDR, &cxld->flags))
> +		set_bit(CXL_REGION_F_NORM_ADDR, &cxlr->flags);
>  }
>  
>  /**
> @@ -1218,7 +1220,7 @@ static int cxl_port_attach_region(struct cxl_port *port,
>  		}
>  	}
>  
> -	cxl_region_set_lock(cxlr, cxld);
> +	cxl_region_setup_flags(cxlr, cxld);
>  
>  	rc = cxl_rr_ep_add(cxl_rr, cxled);
>  	if (rc) {
> @@ -2493,7 +2495,7 @@ static struct cxl_region *cxl_region_alloc(struct cxl_root_decoder *cxlrd, int i
>  	device_set_pm_not_required(dev);
>  	dev->bus = &cxl_bus_type;
>  	dev->type = &cxl_region_type;
> -	cxl_region_set_lock(cxlr, &cxlrd->cxlsd.cxld);
> +	cxl_region_setup_flags(cxlr, &cxlrd->cxlsd.cxld);
>  
>  	return cxlr;
>  }
> @@ -3132,6 +3134,13 @@ u64 cxl_dpa_to_hpa(struct cxl_region *cxlr, const struct cxl_memdev *cxlmd,
>  	u8 eiw = 0;
>  	int pos;
>  
> +	/*
> +	 * Conversion between SPA and DPA is not supported in
> +	 * Normalized Address mode.
> +	 */
> +	if (test_bit(CXL_REGION_F_NORM_ADDR, &cxlr->flags))
> +		return ULLONG_MAX;
> +
>  	for (int i = 0; i < p->nr_targets; i++) {
>  		if (cxlmd == cxled_to_memdev(p->targets[i])) {
>  			cxled = p->targets[i];
> @@ -3922,6 +3931,14 @@ static int cxl_region_setup_poison(struct cxl_region *cxlr)
>  	struct cxl_region_params *p = &cxlr->params;
>  	struct dentry *dentry;
>  
> +	/*
> +	 * Do not enable poison injection in Normalized Address mode.
> +	 * Conversion between SPA and DPA is required for this, but it is
> +	 * not supported in this mode.
> +	 */
> +	if (test_bit(CXL_REGION_F_NORM_ADDR, &cxlr->flags))
> +		return 0;
> +
>  	/* Create poison attributes if all memdevs support the capabilities */
>  	for (int i = 0; i < p->nr_targets; i++) {
>  		struct cxl_endpoint_decoder *cxled = p->targets[i];
> diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
> index 20b0fd43fa7b..0ab0a86e1d4f 100644
> --- a/drivers/cxl/cxl.h
> +++ b/drivers/cxl/cxl.h
> @@ -332,7 +332,7 @@ int cxl_dport_map_rcd_linkcap(struct pci_dev *pdev, struct cxl_dport *dport);
>  #define CXL_DECODER_F_TYPE3 BIT(3)
>  #define CXL_DECODER_F_LOCK  BIT(4)
>  #define CXL_DECODER_F_ENABLE    BIT(5)
> -#define CXL_DECODER_F_MASK  GENMASK(5, 0)
> +#define CXL_DECODER_F_NORM_ADDR BIT(6)
>  
>  enum cxl_decoder_type {
>  	CXL_DECODER_DEVMEM = 2,
> @@ -525,6 +525,13 @@ enum cxl_partition_mode {
>   */
>  #define CXL_REGION_F_LOCK 2
>  
> +/*
> + * Indicate Normalized Addressing. Use it to disable SPA conversion if
> + * HPA != SPA and an address translation callback handler does not
> + * exist. Flag is needed by AMD Zen5 platforms.
> + */
> +#define CXL_REGION_F_NORM_ADDR 3
> +
>  /**
>   * struct cxl_region - CXL region
>   * @dev: This region's device