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

Alison Schofield <[email protected]>
Newsgroups org.kernel.vger.linux-cxl
Message-ID <[email protected]>
On Tue, Jul 21, 2026 at 02:26:57PM +0800, Li Ming wrote:
> 
> 在 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?

Restructuring not needed now that I've dropped the patch in v5. (but
good ideas ;))

Your v3 ask led me to add this patch, but in hindsight, I should have
just answered your question and not jumped to a code change. The driver
didn't need the values but userspace does, so they are left untouched.

The hardening the series keeps is in the bounds instead: P1 rejects a
decoder whose interleave ways exceed its target count, and a new P4
bounds the walks of cxlsd->target[].

-- Alison
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.