[PATCH v3 02/11] cxl/region: Store HPA range in struct cxl_region

Robert Richter posted 11 patches 2 weeks, 6 days ago
[PATCH v3 02/11] cxl/region: Store HPA range in struct cxl_region
Posted by Robert Richter 2 weeks, 6 days ago
Each region has a known host physical address (HPA) range it is
assigned to. Endpoint decoders assigned to a region share the same HPA
range. The region's address range is the system's physical address
(SPA) range.

Endpoint decoders in systems that need address translation use HPAs
which are not SPAs. To make the SPA range accessible to the endpoint
decoders, store and track the region's SPA range in struct cxl_region.
Introduce the @hpa_range member to the struct. Now, the SPA range of
an endpoint decoder can be determined based on its assigned region.

Patch is a prerequisite to implement address translation which uses
struct cxl_region to store all relevant region and interleaving
parameters.

Signed-off-by: Robert Richter <rrichter@amd.com>
---
 drivers/cxl/core/region.c | 17 +++++++++++++++++
 drivers/cxl/cxl.h         |  2 ++
 2 files changed, 19 insertions(+)

diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index 2c37c060d983..777d04870180 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -664,6 +664,11 @@ static int alloc_hpa(struct cxl_region *cxlr, resource_size_t size)
 		return PTR_ERR(res);
 	}
 
+	cxlr->hpa_range = (struct range) {
+		.start = res->start,
+		.end = res->end,
+	};
+
 	p->res = res;
 	p->state = CXL_CONFIG_INTERLEAVE_ACTIVE;
 
@@ -700,8 +705,14 @@ static int free_hpa(struct cxl_region *cxlr)
 	if (p->state >= CXL_CONFIG_ACTIVE)
 		return -EBUSY;
 
+	cxlr->hpa_range = (struct range) {
+		.start = 0,
+		.end = -1,
+	};
+
 	cxl_region_iomem_release(cxlr);
 	p->state = CXL_CONFIG_IDLE;
+
 	return 0;
 }
 
@@ -2400,6 +2411,11 @@ static void unregister_region(void *_cxlr)
 	for (i = 0; i < p->interleave_ways; i++)
 		detach_target(cxlr, i);
 
+	cxlr->hpa_range = (struct range) {
+		.start = 0,
+		.end = -1,
+	};
+
 	cxl_region_iomem_release(cxlr);
 	put_device(&cxlr->dev);
 }
@@ -3458,6 +3474,7 @@ static int __construct_region(struct cxl_region *cxlr,
 	}
 
 	set_bit(CXL_REGION_F_AUTO, &cxlr->flags);
+	cxlr->hpa_range = *hpa;
 
 	res = kmalloc(sizeof(*res), GFP_KERNEL);
 	if (!res)
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index 350ccd6949b3..f182982f1c14 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -518,6 +518,7 @@ enum cxl_partition_mode {
  * @dev: This region's device
  * @id: This region's id. Id is globally unique across all regions
  * @cxlrd: Region's root decoder
+ * @hpa_range: Address range occupied by the region
  * @mode: Operational mode of the mapped capacity
  * @type: Endpoint decoder target type
  * @cxl_nvb: nvdimm bridge for coordinating @cxlr_pmem setup / shutdown
@@ -532,6 +533,7 @@ struct cxl_region {
 	struct device dev;
 	int id;
 	struct cxl_root_decoder *cxlrd;
+	struct range hpa_range;
 	enum cxl_partition_mode mode;
 	enum cxl_decoder_type type;
 	struct cxl_nvdimm_bridge *cxl_nvb;
-- 
2.39.5
Re: [PATCH v3 02/11] cxl/region: Store HPA range in struct cxl_region
Posted by Gregory Price 2 weeks ago
On Fri, Sep 12, 2025 at 04:45:04PM +0200, Robert Richter wrote:
> Each region has a known host physical address (HPA) range it is
> assigned to. Endpoint decoders assigned to a region share the same HPA
> range. The region's address range is the system's physical address
> (SPA) range.
> 
> Endpoint decoders in systems that need address translation use HPAs
> which are not SPAs. To make the SPA range accessible to the endpoint
> decoders, store and track the region's SPA range in struct cxl_region.
> Introduce the @hpa_range member to the struct. Now, the SPA range of
> an endpoint decoder can be determined based on its assigned region.
> 
> Patch is a prerequisite to implement address translation which uses
> struct cxl_region to store all relevant region and interleaving
> parameters.
> 
> Signed-off-by: Robert Richter <rrichter@amd.com>

Reviewed-by: Gregory Price <gourry@gourry.net>
Re: [PATCH v3 02/11] cxl/region: Store HPA range in struct cxl_region
Posted by Jonathan Cameron 2 weeks, 3 days ago
On Fri, 12 Sep 2025 16:45:04 +0200
Robert Richter <rrichter@amd.com> wrote:

> Each region has a known host physical address (HPA) range it is
> assigned to. Endpoint decoders assigned to a region share the same HPA
> range. The region's address range is the system's physical address
> (SPA) range.
> 
> Endpoint decoders in systems that need address translation use HPAs
> which are not SPAs. To make the SPA range accessible to the endpoint
> decoders, store and track the region's SPA range in struct cxl_region.
> Introduce the @hpa_range member to the struct. Now, the SPA range of
> an endpoint decoder can be determined based on its assigned region.
> 
> Patch is a prerequisite to implement address translation which uses
> struct cxl_region to store all relevant region and interleaving
> parameters.
> 
> Signed-off-by: Robert Richter <rrichter@amd.com>
Trivial comment inline.

Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>

> ---
>  drivers/cxl/core/region.c | 17 +++++++++++++++++
>  drivers/cxl/cxl.h         |  2 ++
>  2 files changed, 19 insertions(+)
> 
> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
> index 2c37c060d983..777d04870180 100644
> --- a/drivers/cxl/core/region.c
> +++ b/drivers/cxl/core/region.c
> @@ -664,6 +664,11 @@ static int alloc_hpa(struct cxl_region *cxlr, resource_size_t size)
>  		return PTR_ERR(res);
>  	}
>  
> +	cxlr->hpa_range = (struct range) {
> +		.start = res->start,
> +		.end = res->end,
> +	};
> +
>  	p->res = res;
>  	p->state = CXL_CONFIG_INTERLEAVE_ACTIVE;
>  
> @@ -700,8 +705,14 @@ static int free_hpa(struct cxl_region *cxlr)
>  	if (p->state >= CXL_CONFIG_ACTIVE)
>  		return -EBUSY;
>  
> +	cxlr->hpa_range = (struct range) {
> +		.start = 0,
> +		.end = -1,
> +	};

There is DEFINE_RANGE() which you could use here
	cxlr->hpa_range = DEFINE_RANGE(0, -1);

Not sure if it is worth bothering though.



> +
>  	cxl_region_iomem_release(cxlr);
>  	p->state = CXL_CONFIG_IDLE;
> +
>  	return 0;
>  }
Re: [PATCH v3 02/11] cxl/region: Store HPA range in struct cxl_region
Posted by Robert Richter 2 weeks, 1 day ago
On 15.09.25 11:23:41, Jonathan Cameron wrote:
> On Fri, 12 Sep 2025 16:45:04 +0200
> Robert Richter <rrichter@amd.com> wrote:
> 
> > Each region has a known host physical address (HPA) range it is
> > assigned to. Endpoint decoders assigned to a region share the same HPA
> > range. The region's address range is the system's physical address
> > (SPA) range.
> > 
> > Endpoint decoders in systems that need address translation use HPAs
> > which are not SPAs. To make the SPA range accessible to the endpoint
> > decoders, store and track the region's SPA range in struct cxl_region.
> > Introduce the @hpa_range member to the struct. Now, the SPA range of
> > an endpoint decoder can be determined based on its assigned region.
> > 
> > Patch is a prerequisite to implement address translation which uses
> > struct cxl_region to store all relevant region and interleaving
> > parameters.
> > 
> > Signed-off-by: Robert Richter <rrichter@amd.com>
> Trivial comment inline.
> 
> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
> 
> > ---
> >  drivers/cxl/core/region.c | 17 +++++++++++++++++
> >  drivers/cxl/cxl.h         |  2 ++
> >  2 files changed, 19 insertions(+)
> > 
> > diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
> > index 2c37c060d983..777d04870180 100644
> > --- a/drivers/cxl/core/region.c
> > +++ b/drivers/cxl/core/region.c
> > @@ -664,6 +664,11 @@ static int alloc_hpa(struct cxl_region *cxlr, resource_size_t size)
> >  		return PTR_ERR(res);
> >  	}
> >  
> > +	cxlr->hpa_range = (struct range) {
> > +		.start = res->start,
> > +		.end = res->end,
> > +	};
> > +
> >  	p->res = res;
> >  	p->state = CXL_CONFIG_INTERLEAVE_ACTIVE;
> >  
> > @@ -700,8 +705,14 @@ static int free_hpa(struct cxl_region *cxlr)
> >  	if (p->state >= CXL_CONFIG_ACTIVE)
> >  		return -EBUSY;
> >  
> > +	cxlr->hpa_range = (struct range) {
> > +		.start = 0,
> > +		.end = -1,
> > +	};
> 
> There is DEFINE_RANGE() which you could use here
> 	cxlr->hpa_range = DEFINE_RANGE(0, -1);
> 
> Not sure if it is worth bothering though.

It is pretty new. Given the wide range of users of DEFINE_RES_*, let's
start using this one too.

-Robert
Re: [PATCH v3 02/11] cxl/region: Store HPA range in struct cxl_region
Posted by Dave Jiang 2 weeks, 6 days ago

On 9/12/25 7:45 AM, Robert Richter wrote:
> Each region has a known host physical address (HPA) range it is
> assigned to. Endpoint decoders assigned to a region share the same HPA
> range. The region's address range is the system's physical address
> (SPA) range.
> 
> Endpoint decoders in systems that need address translation use HPAs
> which are not SPAs. To make the SPA range accessible to the endpoint
> decoders, store and track the region's SPA range in struct cxl_region.
> Introduce the @hpa_range member to the struct. Now, the SPA range of
> an endpoint decoder can be determined based on its assigned region.
> 
> Patch is a prerequisite to implement address translation which uses
> struct cxl_region to store all relevant region and interleaving
> parameters.
> 
> Signed-off-by: Robert Richter <rrichter@amd.com>

Just a nit below. Otherwise looks ok

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

> ---
>  drivers/cxl/core/region.c | 17 +++++++++++++++++
>  drivers/cxl/cxl.h         |  2 ++
>  2 files changed, 19 insertions(+)
> 
> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
> index 2c37c060d983..777d04870180 100644
> --- a/drivers/cxl/core/region.c
> +++ b/drivers/cxl/core/region.c
> @@ -664,6 +664,11 @@ static int alloc_hpa(struct cxl_region *cxlr, resource_size_t size)
>  		return PTR_ERR(res);
>  	}
>  
> +	cxlr->hpa_range = (struct range) {
> +		.start = res->start,
> +		.end = res->end,
> +	};
> +
>  	p->res = res;
>  	p->state = CXL_CONFIG_INTERLEAVE_ACTIVE;
>  
> @@ -700,8 +705,14 @@ static int free_hpa(struct cxl_region *cxlr)
>  	if (p->state >= CXL_CONFIG_ACTIVE)
>  		return -EBUSY;
>  
> +	cxlr->hpa_range = (struct range) {
> +		.start = 0,
> +		.end = -1,
> +	};
> +
>  	cxl_region_iomem_release(cxlr);
>  	p->state = CXL_CONFIG_IDLE;
> +

stray blank line
>  	return 0;
>  }
>  
> @@ -2400,6 +2411,11 @@ static void unregister_region(void *_cxlr)
>  	for (i = 0; i < p->interleave_ways; i++)
>  		detach_target(cxlr, i);
>  
> +	cxlr->hpa_range = (struct range) {
> +		.start = 0,
> +		.end = -1,
> +	};
> +
>  	cxl_region_iomem_release(cxlr);
>  	put_device(&cxlr->dev);
>  }
> @@ -3458,6 +3474,7 @@ static int __construct_region(struct cxl_region *cxlr,
>  	}
>  
>  	set_bit(CXL_REGION_F_AUTO, &cxlr->flags);
> +	cxlr->hpa_range = *hpa;
>  
>  	res = kmalloc(sizeof(*res), GFP_KERNEL);
>  	if (!res)
> diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
> index 350ccd6949b3..f182982f1c14 100644
> --- a/drivers/cxl/cxl.h
> +++ b/drivers/cxl/cxl.h
> @@ -518,6 +518,7 @@ enum cxl_partition_mode {
>   * @dev: This region's device
>   * @id: This region's id. Id is globally unique across all regions
>   * @cxlrd: Region's root decoder
> + * @hpa_range: Address range occupied by the region
>   * @mode: Operational mode of the mapped capacity
>   * @type: Endpoint decoder target type
>   * @cxl_nvb: nvdimm bridge for coordinating @cxlr_pmem setup / shutdown
> @@ -532,6 +533,7 @@ struct cxl_region {
>  	struct device dev;
>  	int id;
>  	struct cxl_root_decoder *cxlrd;
> +	struct range hpa_range;
>  	enum cxl_partition_mode mode;
>  	enum cxl_decoder_type type;
>  	struct cxl_nvdimm_bridge *cxl_nvb;
Re: [PATCH v3 02/11] cxl/region: Store HPA range in struct cxl_region
Posted by Robert Richter 2 weeks, 3 days ago
On 12.09.25 10:17:14, Dave Jiang wrote:
> 
> 
> On 9/12/25 7:45 AM, Robert Richter wrote:
> > Each region has a known host physical address (HPA) range it is
> > assigned to. Endpoint decoders assigned to a region share the same HPA
> > range. The region's address range is the system's physical address
> > (SPA) range.
> > 
> > Endpoint decoders in systems that need address translation use HPAs
> > which are not SPAs. To make the SPA range accessible to the endpoint
> > decoders, store and track the region's SPA range in struct cxl_region.
> > Introduce the @hpa_range member to the struct. Now, the SPA range of
> > an endpoint decoder can be determined based on its assigned region.
> > 
> > Patch is a prerequisite to implement address translation which uses
> > struct cxl_region to store all relevant region and interleaving
> > parameters.
> > 
> > Signed-off-by: Robert Richter <rrichter@amd.com>
> 
> Just a nit below. Otherwise looks ok
> 
> Reviewed-by: Dave Jiang <dave.jiang@intel.com>
> 
> > ---
> >  drivers/cxl/core/region.c | 17 +++++++++++++++++
> >  drivers/cxl/cxl.h         |  2 ++
> >  2 files changed, 19 insertions(+)
> > 
> > diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
> > index 2c37c060d983..777d04870180 100644
> > --- a/drivers/cxl/core/region.c
> > +++ b/drivers/cxl/core/region.c
> > @@ -664,6 +664,11 @@ static int alloc_hpa(struct cxl_region *cxlr, resource_size_t size)
> >  		return PTR_ERR(res);
> >  	}
> >  
> > +	cxlr->hpa_range = (struct range) {
> > +		.start = res->start,
> > +		.end = res->end,
> > +	};
> > +
> >  	p->res = res;
> >  	p->state = CXL_CONFIG_INTERLEAVE_ACTIVE;
> >  
> > @@ -700,8 +705,14 @@ static int free_hpa(struct cxl_region *cxlr)
> >  	if (p->state >= CXL_CONFIG_ACTIVE)
> >  		return -EBUSY;
> >  
> > +	cxlr->hpa_range = (struct range) {
> > +		.start = 0,
> > +		.end = -1,
> > +	};
> > +
> >  	cxl_region_iomem_release(cxlr);
> >  	p->state = CXL_CONFIG_IDLE;
> > +
> 
> stray blank line
> >  	return 0;
> >  }

This small cleanup was intended and separates the return from other
statements to better group the code in (sort of) blocks. It is not
worth separate patch and it is common practice to have small cleanups
in the area of code that is changed. That allows small style fixes to
the code while reworking it, but avoids separate code cleanups causing
extra efforts, conflicts and the risk of changing stable code.

Anyway, let me know if you want me remove the change.

Thanks,

-Robert
Re: [PATCH v3 02/11] cxl/region: Store HPA range in struct cxl_region
Posted by Dave Jiang 2 weeks, 3 days ago

On 9/15/25 12:19 AM, Robert Richter wrote:
> On 12.09.25 10:17:14, Dave Jiang wrote:
>>
>>
>> On 9/12/25 7:45 AM, Robert Richter wrote:
>>> Each region has a known host physical address (HPA) range it is
>>> assigned to. Endpoint decoders assigned to a region share the same HPA
>>> range. The region's address range is the system's physical address
>>> (SPA) range.
>>>
>>> Endpoint decoders in systems that need address translation use HPAs
>>> which are not SPAs. To make the SPA range accessible to the endpoint
>>> decoders, store and track the region's SPA range in struct cxl_region.
>>> Introduce the @hpa_range member to the struct. Now, the SPA range of
>>> an endpoint decoder can be determined based on its assigned region.
>>>
>>> Patch is a prerequisite to implement address translation which uses
>>> struct cxl_region to store all relevant region and interleaving
>>> parameters.
>>>
>>> Signed-off-by: Robert Richter <rrichter@amd.com>
>>
>> Just a nit below. Otherwise looks ok
>>
>> Reviewed-by: Dave Jiang <dave.jiang@intel.com>
>>
>>> ---
>>>  drivers/cxl/core/region.c | 17 +++++++++++++++++
>>>  drivers/cxl/cxl.h         |  2 ++
>>>  2 files changed, 19 insertions(+)
>>>
>>> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
>>> index 2c37c060d983..777d04870180 100644
>>> --- a/drivers/cxl/core/region.c
>>> +++ b/drivers/cxl/core/region.c
>>> @@ -664,6 +664,11 @@ static int alloc_hpa(struct cxl_region *cxlr, resource_size_t size)
>>>  		return PTR_ERR(res);
>>>  	}
>>>  
>>> +	cxlr->hpa_range = (struct range) {
>>> +		.start = res->start,
>>> +		.end = res->end,
>>> +	};
>>> +
>>>  	p->res = res;
>>>  	p->state = CXL_CONFIG_INTERLEAVE_ACTIVE;
>>>  
>>> @@ -700,8 +705,14 @@ static int free_hpa(struct cxl_region *cxlr)
>>>  	if (p->state >= CXL_CONFIG_ACTIVE)
>>>  		return -EBUSY;
>>>  
>>> +	cxlr->hpa_range = (struct range) {
>>> +		.start = 0,
>>> +		.end = -1,
>>> +	};
>>> +
>>>  	cxl_region_iomem_release(cxlr);
>>>  	p->state = CXL_CONFIG_IDLE;
>>> +
>>
>> stray blank line
>>>  	return 0;
>>>  }
> 
> This small cleanup was intended and separates the return from other
> statements to better group the code in (sort of) blocks. It is not
> worth separate patch and it is common practice to have small cleanups
> in the area of code that is changed. That allows small style fixes to
> the code while reworking it, but avoids separate code cleanups causing
> extra efforts, conflicts and the risk of changing stable code.
> 
> Anyway, let me know if you want me remove the change.

Yeah please just drop the change. While it's nice to have, it may potentially cause backport issues generally speaking. 

> 
> Thanks,
> 
> -Robert