Re: [PATCH v9 2/3] cxl/hdm: Allow zero sized HDM decoders
[email protected] Wed, 05 Aug 2026 06:09:09 +0000
| Newsgroups | org.kernel.vger.linux-cxl |
|---|---|
| Message-ID | <[email protected]> |
Thank you for your contribution! Sashiko AI review found 3 potential issue(= s) to consider: New issues: - [High] The teardown logic for 0-sized decoders is broken by an early retu= rn, causing a resource leak and permanently breaking the DPA LIFO state mac= hine. - [Medium] The poison scan for the skip range of an out-of-bounds empty dec= oder is bypassed, missing hardware error queries. Pre-existing issues: - [High] The unmapped poison scan aborts prematurely, missing hardware erro= r queries for subsequent partitions. -- --- Patch [2]: [PATCH v9 2/3] cxl/hdm: Allow zero sized HDM decoders --- commit 129bd5c21519972c027d6ca212a8591b5cea7517 Author: Richard Cheng <[email protected]> cxl/hdm: Allow zero sized HDM decoders This commit allows the kernel to accept and process zero-sized HDM decoders= =20 instead of rejecting them during enumeration. It backs them with a kmalloc'= d=20 resource and guards paths that do not apply to empty decoders. > diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c > index 0c80b76a5f9b4..3b3cfa0f25074 100644 > --- a/drivers/cxl/core/hdm.c > +++ b/drivers/cxl/core/hdm.c [ ... ] > @@ -545,7 +572,7 @@ int cxl_dpa_free(struct cxl_endpoint_decoder *cxled) > struct device *dev =3D &cxled->cxld.dev; > =20 > guard(rwsem_write)(&cxl_rwsem.dpa); > - if (!cxled->dpa_res) > + if (cxled_empty(cxled)) > return 0; [Severity: High] Does returning 0 here for 0-sized decoders bypass the release action? If devm_cxl_dpa_release() is not called for 0-sized decoders, it appears this would leak the reservation and prevent port->hdm_end from being=20 decremented, permanently breaking the DPA LIFO state machine for future=20 teardowns. [ ... ] > diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c > index 45536909cc17d..e6929feb63786 100644 > --- a/drivers/cxl/core/region.c > +++ b/drivers/cxl/core/region.c [ ... ] > @@ -2969,24 +2969,31 @@ static int poison_by_decoder(struct device *dev, = void *arg) > if (!cxled->dpa_res) > return 0; > =20 > - cxlmd =3D cxled_to_memdev(cxled); > - cxlds =3D cxlmd->cxlds; > - mode =3D cxlds->part[cxled->part].mode; > + /* > + * Handle the degenerate case of a device with only empty decoders. An > + * empty decoder can still map a non-zero skip range, so advance the > + * walk to commit_end either way. > + */ > + if (cxled->part >=3D 0) { [Severity: Medium] Will this condition skip checking poison in a valid skip range?=20 If firmware commits an empty decoder at an out-of-bounds base, cxled->part= =20 would be -1. However, if its skip range is large enough to intersect a=20 valid partition, skipping this block seems to prevent querying the skipped= =20 DPA space for hardware poison. > + cxlmd =3D cxled_to_memdev(cxled); > + cxlds =3D cxlmd->cxlds; > + mode =3D cxlds->part[cxled->part].mode; > =20 > - if (cxled->skip) { > - offset =3D cxled->dpa_res->start - cxled->skip; > - length =3D cxled->skip; > - rc =3D cxl_mem_get_poison(cxlmd, offset, length, NULL); > + if (cxled->skip) { > + offset =3D cxled->dpa_res->start - cxled->skip; > + length =3D cxled->skip; > + rc =3D cxl_mem_get_poison(cxlmd, offset, length, NULL); > + if (rc && !poison_efault_forgiven(rc, mode)) > + return rc; > + } [ ... ] > @@ -3008,9 +3015,17 @@ int cxl_get_poison_by_endpoint(struct cxl_port *po= rt) > }; > =20 > rc =3D device_for_each_child(&port->dev, &ctx, poison_by_decoder); > - if (rc =3D=3D 1) > + if (rc =3D=3D 1) { > + /* > + * No decoder with a sized DPA reservation was walked > + * (every committed decoder is zero-size): scan all > + * partitions in full. > + */ > + if (ctx.part < 0) > + ctx.part =3D 0; > rc =3D cxl_get_poison_unmapped(to_cxl_memdev(port->uport_dev), > &ctx); [Severity: High] This is a pre-existing issue, but does cxl_get_poison_unmapped() abort=20 prematurely during its scan? If a preceding partition is fully mapped, length evaluates to 0. In=20 cxl_get_poison_unmapped(): for (int i =3D ctx->part; i < cxlds->nr_partitions; i++) { ... length =3D res->end - offset + 1; if (!length) break; Using break instead of continue here aborts the loop entirely. Does this=20 incorrectly skip hardware error queries for any subsequent unmapped=20 partitions (like PMEM)? > + } > =20 > return rc; > } --=20 Sashiko AI review =C2=B7 https://sashiko.dev/#/patchset/20260805055524.2231= [email protected]?part=3D2