Re: [PATCH v4 1/4] cxl/hdm: Reject switch decoder interleave ways that overflow targets

Alison Schofield <[email protected]>
Newsgroups org.kernel.vger.linux-cxl
Message-ID <[email protected]>
On Tue, Jul 21, 2026 at 02:27:27PM +0800, Li Ming wrote:
> 
> 在 2026/7/21 09:59, Alison Schofield 写道:

Thanks for the review Ming,

snip

> > diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
> > index 0c80b76a5f9b..d81df45d8005 100644
> > --- a/drivers/cxl/core/hdm.c
> > +++ b/drivers/cxl/core/hdm.c
> > @@ -76,6 +76,8 @@ static void parse_hdm_decoder_caps(struct cxl_hdm *cxlhdm)
> >   	hdm_cap = readl(cxlhdm->regs.hdm_decoder + CXL_HDM_DECODER_CAP_OFFSET);
> >   	cxlhdm->decoder_count = cxl_hdm_decoder_count(hdm_cap);
> > +
> > +	/* target_count is a direct count (1h..8h), not 0-based like decoder_count */
> >   	cxlhdm->target_count =
> >   		FIELD_GET(CXL_HDM_DECODER_TARGET_COUNT_MASK, hdm_cap);
> >   	if (FIELD_GET(CXL_HDM_DECODER_INTERLEAVE_11_8, hdm_cap))
> > @@ -1084,6 +1086,37 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
> >   		cxld->interleave_ways, cxld->interleave_granularity);
> >   	if (!cxled) {
> > +		struct cxl_switch_decoder *cxlsd =
> > +			to_cxl_switch_decoder(&cxld->dev);
> > +
> > +		if (cxlsd->nr_targets < 1) {
> > +			dev_err(&port->dev,
> > +				"decoder%d.%d: reports zero targets\n",
> > +				port->id, cxld->id);
> > +			return -ENXIO;
> > +		}
> I noticed cxl_switch_decoder_init() has a check for the value of given
> nr_targets before setting cxlsd->nr_targets, maybe we can move this check
> into cxl_switch_decoder_init()?

Done in v5.

Jonathan asked for same treatment of the target list capacity check,
so I moved that up to the port in devm_cxl_enumerate_decoders().


> > +
> > +		if (!committed) {
> > +			/* Ignore interleave ways until commit */
> > +			cxld->interleave_ways = 1;
> > +			return 0;
> > +		}
> The following part is related to a committed decoder( including target_map
> array updating), like my comment in patch #2, maybe it is worth a cleanup.
> > +

No, that part is not committed-only. Enumeration reads the interleave
fields for every decoder, and interleave_ways and interleave_granularity
report them to userspace. Gating the read on committed changes what
those attributes show, so patch 2 is dropped in v5 and the code stays
where it is. See my reply on patch 2.


> > +		if (cxld->interleave_ways > CXL_HDM_DECODER0_TL_TARGETS) {
> > +			dev_err(&port->dev,
> > +				"decoder%d.%d: interleave ways: %d exceeds target list capacity: %d\n",
> > +				port->id, cxld->id, cxld->interleave_ways,
> > +				CXL_HDM_DECODER0_TL_TARGETS);
> > +			return -ENXIO;
> > +		}
> > +		if (cxld->interleave_ways > cxlsd->nr_targets) {
> > +			dev_err(&port->dev,
> > +				"decoder%d.%d: interleave ways: %d exceeds targets: %d\n",
> > +				port->id, cxld->id, cxld->interleave_ways,
> > +				cxlsd->nr_targets);
> > +			return -ENXIO;
> > +		}
> > +
> >   		lo = readl(hdm + CXL_HDM_DECODER0_TL_LOW(which));
> >   		hi = readl(hdm + CXL_HDM_DECODER0_TL_HIGH(which));
> >   		target_list.value = (hi << 32) + lo;


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