Re: [PATCH v4 2/4] cxl/hdm: Only interpret interleave settings on committed decoders

Li Ming <[email protected]>
Newsgroups org.kernel.vger.linux-cxl
Message-ID <[email protected]>
在 2026/7/21 09:59, Alison Schofield 写道:
> Decoder enumeration reads the interleave ways and granularity fields
> from the CTRL register unconditionally, then decodes and validates
> them for every decoder. On an uncommitted decoder these fields are
> stale. They hold whatever was last latched and are reprogrammed when
> the decoder is committed. Interpreting them serves no purpose, and
> rejecting enumeration on a reserved encoding in those stale bits can
> fail an otherwise usable decoder.
>
> Decode and validate interleave ways and granularity only when the
> decoder is committed. On an uncommitted decoder the stale register
> values are not interpreted. The interleave fields are set when the
> decoder is programmed at commit time.
>
>
> Reported-by: Li Ming <[email protected]>
> Closes: https://lore.kernel.org/all/[email protected]/
> Signed-off-by: Alison Schofield <[email protected]>
> ---
>   drivers/cxl/core/hdm.c | 33 ++++++++++++++++++---------------
>   1 file changed, 18 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
> index d81df45d8005..1f995191baf5 100644
> --- a/drivers/cxl/core/hdm.c
> +++ b/drivers/cxl/core/hdm.c
> @@ -1064,21 +1064,24 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
>   			writel(ctrl, hdm + CXL_HDM_DECODER0_CTRL_OFFSET(which));
>   		}
>   	}
> -	rc = eiw_to_ways(FIELD_GET(CXL_HDM_DECODER0_CTRL_IW_MASK, ctrl),
> -			  &cxld->interleave_ways);
> -	if (rc) {
> -		dev_warn(&port->dev,
> -			 "decoder%d.%d: Invalid interleave ways (ctrl: %#x)\n",
> -			 port->id, cxld->id, ctrl);
> -		return rc;
> -	}
> -	rc = eig_to_granularity(FIELD_GET(CXL_HDM_DECODER0_CTRL_IG_MASK, ctrl),
> -				 &cxld->interleave_granularity);
> -	if (rc) {
> -		dev_warn(&port->dev,
> -			 "decoder%d.%d: Invalid interleave granularity (ctrl: %#x)\n",
> -			 port->id, cxld->id, ctrl);
> -		return rc;
> +	/* Interleave settings are only valid on a committed decoder */
> +	if (committed) {
> +		rc = eiw_to_ways(FIELD_GET(CXL_HDM_DECODER0_CTRL_IW_MASK, ctrl),
> +				 &cxld->interleave_ways);
> +		if (rc) {
> +			dev_warn(&port->dev,
> +				 "decoder%d.%d: Invalid interleave ways (ctrl: %#x)\n",
> +				 port->id, cxld->id, ctrl);
> +			return rc;
> +		}
> +		rc = eig_to_granularity(FIELD_GET(CXL_HDM_DECODER0_CTRL_IG_MASK, ctrl),
> +					&cxld->interleave_granularity);
> +		if (rc) {
> +			dev_warn(&port->dev,
> +				 "decoder%d.%d: Invalid interleave granularity (ctrl: %#x)\n",
> +				 port->id, cxld->id, ctrl);
> +			return rc;
> +		}

There is a "if (committed) {}" block before these changes, maybe we can 
combine them into one.

Besides, there is a piece of codes related to a committed decoder 
handling in the end of init_hdm_decoder(), maybe we should put all 
committed decoder handling codes into one "if {}" block?

>   	}
>   
>   	dev_dbg(&port->dev, "decoder%d.%d: range: %#llx-%#llx iw: %d ig: %d\n",
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.