[PATCH v1 24/29] cxl/region: Use endpoint's SPA range to check a region

Robert Richter posted 29 patches 8 months, 1 week ago
[PATCH v1 24/29] cxl/region: Use endpoint's SPA range to check a region
Posted by Robert Richter 8 months, 1 week ago
Endpoints or switches requiring address translation might not be aware
of the system's interleaving configuration. Then, the configured
endpoint's address range might not match the expected range. In
contrast, the SPA range of an endpoint is calculated applying platform
specific address translation. That range is correct and can be used to
check a region range.

Adjust the region range check and use the endpoint's SPA range to
check it.

Signed-off-by: Robert Richter <rrichter@amd.com>
---
 drivers/cxl/core/region.c | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index c3322bae05b9..1dae7d36d37c 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -1516,22 +1516,26 @@ static int cxl_port_setup_targets(struct cxl_port *port,
 	if (test_bit(CXL_REGION_F_AUTO, &cxlr->flags)) {
 		if (cxld->interleave_ways != iw ||
 		    cxld->interleave_granularity != ig ||
-		    cxld->hpa_range.start != p->res->start ||
-		    cxld->hpa_range.end != p->res->end ||
+		    cxled->spa_range.start != p->res->start ||
+		    cxled->spa_range.end != p->res->end ||
 		    ((cxld->flags & CXL_DECODER_F_ENABLE) == 0)) {
 			dev_err(&cxlr->dev,
 				"%s:%s %s expected iw: %d ig: %d %pr\n",
 				dev_name(port->uport_dev), dev_name(&port->dev),
 				__func__, iw, ig, p->res);
 			dev_err(&cxlr->dev,
-				"%s:%s %s got iw: %d ig: %d state: %s %#llx:%#llx\n",
+				"%s:%s %s got iw: %d ig: %d state: %s %#llx-%#llx:%#llx-%#llx(%s):%#llx-%#llx(%s)\n",
 				dev_name(port->uport_dev), dev_name(&port->dev),
 				__func__, cxld->interleave_ways,
 				cxld->interleave_granularity,
 				(cxld->flags & CXL_DECODER_F_ENABLE) ?
 					"enabled" :
 					"disabled",
-				cxld->hpa_range.start, cxld->hpa_range.end);
+				p->res->start, p->res->end,
+				cxled->spa_range.start, cxled->spa_range.end,
+				dev_name(&cxled->cxld.dev),
+				cxld->hpa_range.start, cxld->hpa_range.end,
+				dev_name(&cxld->dev));
 			return -ENXIO;
 		}
 	} else {
@@ -2051,13 +2055,12 @@ static int cxl_region_attach(struct cxl_region *cxlr,
 		return -ENXIO;
 	}
 
-	if (resource_size(cxled->dpa_res) * p->interleave_ways !=
-	    resource_size(p->res)) {
+	if (range_len(&cxled->spa_range) != resource_size(p->res)) {
 		dev_dbg(&cxlr->dev,
-			"%s:%s: decoder-size-%#llx * ways-%d != region-size-%#llx\n",
+			"%s:%s: SPA size mismatch: %#llx-%#llx:%#llx-%#llx\n",
 			dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev),
-			(u64)resource_size(cxled->dpa_res), p->interleave_ways,
-			(u64)resource_size(p->res));
+			p->res->start, p->res->end,
+			cxled->spa_range.start, cxled->spa_range.end);
 		return -EINVAL;
 	}
 
-- 
2.39.5
Re: [PATCH v1 24/29] cxl/region: Use endpoint's SPA range to check a region
Posted by Alison Schofield 8 months ago
On Tue, Jan 07, 2025 at 03:10:10PM +0100, Robert Richter wrote:
> Endpoints or switches requiring address translation might not be aware
> of the system's interleaving configuration. Then, the configured
> endpoint's address range might not match the expected range. In
> contrast, the SPA range of an endpoint is calculated applying platform
> specific address translation. That range is correct and can be used to
> check a region range.
> 
> Adjust the region range check and use the endpoint's SPA range to
> check it.
> 
> Signed-off-by: Robert Richter <rrichter@amd.com>
> ---
>  drivers/cxl/core/region.c | 21 ++++++++++++---------
>  1 file changed, 12 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
> index c3322bae05b9..1dae7d36d37c 100644
> --- a/drivers/cxl/core/region.c
> +++ b/drivers/cxl/core/region.c
> @@ -1516,22 +1516,26 @@ static int cxl_port_setup_targets(struct cxl_port *port,
>  	if (test_bit(CXL_REGION_F_AUTO, &cxlr->flags)) {
>  		if (cxld->interleave_ways != iw ||
>  		    cxld->interleave_granularity != ig ||
> -		    cxld->hpa_range.start != p->res->start ||
> -		    cxld->hpa_range.end != p->res->end ||
> +		    cxled->spa_range.start != p->res->start ||
> +		    cxled->spa_range.end != p->res->end ||
>  		    ((cxld->flags & CXL_DECODER_F_ENABLE) == 0)) {
>  			dev_err(&cxlr->dev,
>  				"%s:%s %s expected iw: %d ig: %d %pr\n",
>  				dev_name(port->uport_dev), dev_name(&port->dev),
>  				__func__, iw, ig, p->res);
>  			dev_err(&cxlr->dev,
> -				"%s:%s %s got iw: %d ig: %d state: %s %#llx:%#llx\n",
> +				"%s:%s %s got iw: %d ig: %d state: %s %#llx-%#llx:%#llx-%#llx(%s):%#llx-%#llx(%s)\n",
>  				dev_name(port->uport_dev), dev_name(&port->dev),
>  				__func__, cxld->interleave_ways,
>  				cxld->interleave_granularity,
>  				(cxld->flags & CXL_DECODER_F_ENABLE) ?
>  					"enabled" :
>  					"disabled",
> -				cxld->hpa_range.start, cxld->hpa_range.end);
> +				p->res->start, p->res->end,
> +				cxled->spa_range.start, cxled->spa_range.end,
> +				dev_name(&cxled->cxld.dev),
> +				cxld->hpa_range.start, cxld->hpa_range.end,
> +				dev_name(&cxld->dev));
>  			return -ENXIO;
>  		}
>  	} else {
> @@ -2051,13 +2055,12 @@ static int cxl_region_attach(struct cxl_region *cxlr,
>  		return -ENXIO;
>  	}
>  
> -	if (resource_size(cxled->dpa_res) * p->interleave_ways !=
> -	    resource_size(p->res)) {
> +	if (range_len(&cxled->spa_range) != resource_size(p->res)) {
>  		dev_dbg(&cxlr->dev,
> -			"%s:%s: decoder-size-%#llx * ways-%d != region-size-%#llx\n",
> +			"%s:%s: SPA size mismatch: %#llx-%#llx:%#llx-%#llx\n",

The cxled->spa_range is only set in the auto region path, yet this
path is taken by both auto and user created regions. User created regions
die here.


>  			dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev),
> -			(u64)resource_size(cxled->dpa_res), p->interleave_ways,
> -			(u64)resource_size(p->res));
> +			p->res->start, p->res->end,
> +			cxled->spa_range.start, cxled->spa_range.end);
>  		return -EINVAL;
>  	}
>  
> -- 
> 2.39.5
>
Re: [PATCH v1 24/29] cxl/region: Use endpoint's SPA range to check a region
Posted by Robert Richter 7 months ago
On 13.01.25 09:38:04, Alison Schofield wrote:
> On Tue, Jan 07, 2025 at 03:10:10PM +0100, Robert Richter wrote:

> > @@ -2051,13 +2055,12 @@ static int cxl_region_attach(struct cxl_region *cxlr,
> >  		return -ENXIO;
> >  	}
> >  
> > -	if (resource_size(cxled->dpa_res) * p->interleave_ways !=
> > -	    resource_size(p->res)) {
> > +	if (range_len(&cxled->spa_range) != resource_size(p->res)) {
> >  		dev_dbg(&cxlr->dev,
> > -			"%s:%s: decoder-size-%#llx * ways-%d != region-size-%#llx\n",
> > +			"%s:%s: SPA size mismatch: %#llx-%#llx:%#llx-%#llx\n",
> 
> The cxled->spa_range is only set in the auto region path, yet this
> path is taken by both auto and user created regions. User created regions
> die here.

The original check at this point should still work and .spa_range will
not be needed then. Fixed in next version.

-Robert