* [PATCH v2] cxl/cdat: Fix uninitialized stack use in endpoint bandwidth gathering
@ 2026-08-12 6:09 Guixin Liu
2026-08-12 6:22 ` sashiko-bot
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Guixin Liu @ 2026-08-12 6:09 UTC (permalink / raw)
To: Davidlohr Bueso, Jonathan Cameron, Dave Jiang, Alison Schofield,
Vishal Verma, Dan Williams, Ira Weiny, Li Ming
Cc: linux-cxl
cxl_endpoint_gather_bandwidth() declares three access_coordinate arrays on
the stack - pci_coord, sw_coord and ep_coord - without initializing them,
and relies on its helpers to fill every member. None of them does.
cxl_pci_get_bandwidth() and cxl_port_get_switch_dport_bandwidth() assign
only read_bandwidth and write_bandwidth, and
__cxl_coordinates_combine() assigns an output bandwidth only when both
input bandwidths are non-zero. Every member a producer declines to set is
read back as whatever was on the stack.
Both cases occur on real topologies. The latency members of pci_coord and
sw_coord are never written, yet __cxl_coordinates_combine() sums them
unconditionally, so the latency reads are undefined on every call. And a
device whose CDAT DSLBIS reports no bandwidth for an access class leaves
perf->cdat_coord zero for that class, which is exactly the condition that
makes __cxl_coordinates_combine() skip the bandwidth assignment and leave
the ep_coord entry untouched.
The ep_coord case escapes the function: cxl_bandwidth_add() accumulates it
into the per-upstream-port aggregate that is published through the region's
access coordinate sysfs attributes, so stack contents are reported to
userspace as a bandwidth figure. The latency sums are discarded by
cxl_bandwidth_add() rather than published, but they are still computed from
uninitialized memory.
Zero initialize the three arrays. Zero is already the value this code uses
for "not reported" - both the __cxl_coordinates_combine() guard and
coordinates_valid() test for it - so a member no producer sets now reads
back as unknown rather than as a plausible number.
Fixes: a5ab0de0ebaa ("cxl: Calculate region bandwidth of targets with shared upstream link")
Signed-off-by: Guixin Liu <kanie@linux.alibaba.com>
---
This was patch 6/8 of the "cxl: Assorted fixes" series [1]. Per review
feedback that series is not being reworked as a whole; the fixes are resent
individually instead. Patches 1, 2 and 7 of the series are dropped, as those
issues are already fixed in cxl/next.
v1->v2:
- rebase onto cxl/next
- rewrite the commit message to describe the behaviour rather than narrate
the code change (Alison Schofield)
[1] https://lore.kernel.org/linux-cxl/20260811113608.2815625-1-kanie@linux.alibaba.com/
drivers/cxl/core/cdat.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c
index 5c9f07262513..3c6a1537f89b 100644
--- a/drivers/cxl/core/cdat.c
+++ b/drivers/cxl/core/cdat.c
@@ -633,9 +633,9 @@ static int cxl_endpoint_gather_bandwidth(struct cxl_region *cxlr,
struct cxl_port *endpoint = to_cxl_port(cxled->cxld.dev.parent);
struct cxl_port *parent_port = to_cxl_port(endpoint->dev.parent);
struct cxl_port *gp_port = to_cxl_port(parent_port->dev.parent);
- struct access_coordinate pci_coord[ACCESS_COORDINATE_MAX];
- struct access_coordinate sw_coord[ACCESS_COORDINATE_MAX];
- struct access_coordinate ep_coord[ACCESS_COORDINATE_MAX];
+ struct access_coordinate pci_coord[ACCESS_COORDINATE_MAX] = { };
+ struct access_coordinate sw_coord[ACCESS_COORDINATE_MAX] = { };
+ struct access_coordinate ep_coord[ACCESS_COORDINATE_MAX] = { };
struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
struct cxl_dev_state *cxlds = cxlmd->cxlds;
struct pci_dev *pdev = to_pci_dev(cxlds->dev);
base-commit: 7098e9cd98a05c0c5de2fae0c2465f9d966fdd07
--
2.43.7
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH v2] cxl/cdat: Fix uninitialized stack use in endpoint bandwidth gathering 2026-08-12 6:09 [PATCH v2] cxl/cdat: Fix uninitialized stack use in endpoint bandwidth gathering Guixin Liu @ 2026-08-12 6:22 ` sashiko-bot 2026-08-12 6:44 ` Guixin Liu 2026-08-12 8:17 ` Richard Cheng 2026-08-12 11:44 ` Li Ming 2 siblings, 1 reply; 6+ messages in thread From: sashiko-bot @ 2026-08-12 6:22 UTC (permalink / raw) To: Guixin Liu; +Cc: linux-cxl Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider: Pre-existing issues: - [High] Uninitialized stack memory use in cxl_switch_gather_bandwidth() during access coordinate combination. - [High] Uninitialized stack memory leak into QoS class calculation for Restricted CXL Devices (RCDs). - [Medium] Pointer aliasing in `cxl_coordinates_combine()` causes bandwidth calculations to incorrectly ignore zero bandwidths from downstream hops. -- --- Patch [1]: [PATCH v2] cxl/cdat: Fix uninitialized stack use in endpoint bandwidth gathering --- commit 1627473a040a741d578311d820959582436220a3 Author: Guixin Liu <kanie@linux.alibaba.com> cxl/cdat: Fix uninitialized stack use in endpoint bandwidth gathering cxl_endpoint_gather_bandwidth() declares three access_coordinate arrays on the stack - pci_coord, sw_coord and ep_coord - without initializing them, and relies on its helpers to fill every member. None of them does. Link: https://lore.kernel.org/linux-cxl/20260811113608.2815625-1-kanie@linux.alibaba.com/ > diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c > index 5c9f072625135..3c6a1537f89b8 100644 > --- a/drivers/cxl/core/cdat.c > +++ b/drivers/cxl/core/cdat.c > @@ -633,9 +633,9 @@ static int cxl_endpoint_gather_bandwidth(struct cxl_region *cxlr, > struct cxl_port *endpoint = to_cxl_port(cxled->cxld.dev.parent); > struct cxl_port *parent_port = to_cxl_port(endpoint->dev.parent); > struct cxl_port *gp_port = to_cxl_port(parent_port->dev.parent); > - struct access_coordinate pci_coord[ACCESS_COORDINATE_MAX]; > - struct access_coordinate sw_coord[ACCESS_COORDINATE_MAX]; > - struct access_coordinate ep_coord[ACCESS_COORDINATE_MAX]; > + struct access_coordinate pci_coord[ACCESS_COORDINATE_MAX] = { }; > + struct access_coordinate sw_coord[ACCESS_COORDINATE_MAX] = { }; > + struct access_coordinate ep_coord[ACCESS_COORDINATE_MAX] = { }; > struct cxl_memdev *cxlmd = cxled_to_memdev(cxled); [Severity: High] This is a pre-existing issue, but cxl_switch_gather_bandwidth() has a similar uninitialized stack array: drivers/cxl/core/cdat.c:cxl_switch_gather_bandwidth() { ... struct access_coordinate coords[ACCESS_COORDINATE_MAX]; ... rc = cxl_pci_get_bandwidth(pdev, coords); ... cxl_coordinates_combine(coords, coords, ctx->coord); ... } cxl_pci_get_bandwidth() leaves latency members uninitialized, and then cxl_coordinates_combine() unconditionally sums them. Should coords be zero-initialized here as well to prevent reading uninitialized memory? [Severity: High] This is a pre-existing issue, but uninitialized stack memory can leak into QoS calculations for Restricted CXL Devices (RCDs): drivers/cxl/core/cdat.c:cxl_port_perf_data_calculate() { struct access_coordinate ep_c[ACCESS_COORDINATE_MAX]; ... rc = cxl_endpoint_get_perf_coordinates(port, ep_c); ... cxl_coordinates_combine(dent->coord, dent->cdat_coord, ep_c); ... } For RCDs, cxl_endpoint_get_perf_coordinates() returns 0 early without modifying the array: drivers/cxl/core/port.c:cxl_endpoint_get_perf_coordinates() { ... if (cxlmd->cxlds->rcd) return 0; ... } This causes cxl_coordinates_combine() to merge uninitialized stack data into the region's coordinates, which is later passed to QoS class calculation and exported to userspace sysfs. Should ep_c also be zero-initialized? [Severity: Medium] This is a pre-existing issue, but does pointer aliasing in cxl_coordinates_combine() cause bandwidth calculations to ignore zero bandwidths from downstream hops? drivers/cxl/core/cdat.c:__cxl_coordinates_combine() { if (c1->write_bandwidth && c2->write_bandwidth) out->write_bandwidth = min(c1->write_bandwidth, c2->write_bandwidth); } When called with aliased pointers in cxl_endpoint_gather_bandwidth() and cxl_switch_gather_bandwidth(): cxl_coordinates_combine(ep_coord, ep_coord, sw_coord); If sw_coord has 0 bandwidth, the operation is skipped, and ep_coord retains its previous non-zero bandwidth instead of being updated to 0. Should the bandwidth be updated when one of the inputs has 0 bandwidth, or is retaining the previous value intended? > struct cxl_dev_state *cxlds = cxlmd->cxlds; > struct pci_dev *pdev = to_pci_dev(cxlds->dev); -- Sashiko AI review · https://sashiko.dev/#/patchset/20260812060912.54932-1-kanie@linux.alibaba.com?part=1 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] cxl/cdat: Fix uninitialized stack use in endpoint bandwidth gathering 2026-08-12 6:22 ` sashiko-bot @ 2026-08-12 6:44 ` Guixin Liu 0 siblings, 0 replies; 6+ messages in thread From: Guixin Liu @ 2026-08-12 6:44 UTC (permalink / raw) To: sashiko-reviews; +Cc: linux-cxl 在 2026/8/12 14:22, sashiko-bot@kernel.org 写道: > Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider: > > Pre-existing issues: > - [High] Uninitialized stack memory use in cxl_switch_gather_bandwidth() during access coordinate combination. > - [High] Uninitialized stack memory leak into QoS class calculation for Restricted CXL Devices (RCDs). > - [Medium] Pointer aliasing in `cxl_coordinates_combine()` causes bandwidth calculations to incorrectly ignore zero bandwidths from downstream hops. > -- > > --- Patch [1]: [PATCH v2] cxl/cdat: Fix uninitialized stack use in endpoint bandwidth gathering --- > commit 1627473a040a741d578311d820959582436220a3 > Author: Guixin Liu <kanie@linux.alibaba.com> > > cxl/cdat: Fix uninitialized stack use in endpoint bandwidth gathering > > cxl_endpoint_gather_bandwidth() declares three access_coordinate arrays on > the stack - pci_coord, sw_coord and ep_coord - without initializing them, > and relies on its helpers to fill every member. None of them does. > > Link: https://lore.kernel.org/linux-cxl/20260811113608.2815625-1-kanie@linux.alibaba.com/ > >> diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c >> index 5c9f072625135..3c6a1537f89b8 100644 >> --- a/drivers/cxl/core/cdat.c >> +++ b/drivers/cxl/core/cdat.c >> @@ -633,9 +633,9 @@ static int cxl_endpoint_gather_bandwidth(struct cxl_region *cxlr, >> struct cxl_port *endpoint = to_cxl_port(cxled->cxld.dev.parent); >> struct cxl_port *parent_port = to_cxl_port(endpoint->dev.parent); >> struct cxl_port *gp_port = to_cxl_port(parent_port->dev.parent); >> - struct access_coordinate pci_coord[ACCESS_COORDINATE_MAX]; >> - struct access_coordinate sw_coord[ACCESS_COORDINATE_MAX]; >> - struct access_coordinate ep_coord[ACCESS_COORDINATE_MAX]; >> + struct access_coordinate pci_coord[ACCESS_COORDINATE_MAX] = { }; >> + struct access_coordinate sw_coord[ACCESS_COORDINATE_MAX] = { }; >> + struct access_coordinate ep_coord[ACCESS_COORDINATE_MAX] = { }; >> struct cxl_memdev *cxlmd = cxled_to_memdev(cxled); > [Severity: High] > This is a pre-existing issue, but cxl_switch_gather_bandwidth() has a similar > uninitialized stack array: > > drivers/cxl/core/cdat.c:cxl_switch_gather_bandwidth() { > ... > struct access_coordinate coords[ACCESS_COORDINATE_MAX]; > ... > rc = cxl_pci_get_bandwidth(pdev, coords); > ... > cxl_coordinates_combine(coords, coords, ctx->coord); > ... > } > > cxl_pci_get_bandwidth() leaves latency members uninitialized, and then > cxl_coordinates_combine() unconditionally sums them. > > Should coords be zero-initialized here as well to prevent reading > uninitialized memory? Yes, will be changed too in v3. > > [Severity: High] > This is a pre-existing issue, but uninitialized stack memory can leak into QoS > calculations for Restricted CXL Devices (RCDs): > > drivers/cxl/core/cdat.c:cxl_port_perf_data_calculate() { > struct access_coordinate ep_c[ACCESS_COORDINATE_MAX]; > ... > rc = cxl_endpoint_get_perf_coordinates(port, ep_c); > ... > cxl_coordinates_combine(dent->coord, dent->cdat_coord, ep_c); > ... > } > > For RCDs, cxl_endpoint_get_perf_coordinates() returns 0 early without > modifying the array: > > drivers/cxl/core/port.c:cxl_endpoint_get_perf_coordinates() { > ... > if (cxlmd->cxlds->rcd) > return 0; > ... > } > > This causes cxl_coordinates_combine() to merge uninitialized stack data into > the region's coordinates, which is later passed to QoS class calculation and > exported to userspace sysfs. > > Should ep_c also be zero-initialized? Yes, changed too in v3. > > [Severity: Medium] > This is a pre-existing issue, but does pointer aliasing in > cxl_coordinates_combine() cause bandwidth calculations to ignore zero > bandwidths from downstream hops? > > drivers/cxl/core/cdat.c:__cxl_coordinates_combine() { > if (c1->write_bandwidth && c2->write_bandwidth) > out->write_bandwidth = min(c1->write_bandwidth, > c2->write_bandwidth); > } > > When called with aliased pointers in cxl_endpoint_gather_bandwidth() and > cxl_switch_gather_bandwidth(): > > cxl_coordinates_combine(ep_coord, ep_coord, sw_coord); > > If sw_coord has 0 bandwidth, the operation is skipped, and ep_coord retains > its previous non-zero bandwidth instead of being updated to 0. > > Should the bandwidth be updated when one of the inputs has 0 bandwidth, or is > retaining the previous value intended? It is intended. Best Regards, Guixin Liu >> struct cxl_dev_state *cxlds = cxlmd->cxlds; >> struct pci_dev *pdev = to_pci_dev(cxlds->dev); ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] cxl/cdat: Fix uninitialized stack use in endpoint bandwidth gathering 2026-08-12 6:09 [PATCH v2] cxl/cdat: Fix uninitialized stack use in endpoint bandwidth gathering Guixin Liu 2026-08-12 6:22 ` sashiko-bot @ 2026-08-12 8:17 ` Richard Cheng 2026-08-12 8:45 ` Guixin Liu 2026-08-12 11:44 ` Li Ming 2 siblings, 1 reply; 6+ messages in thread From: Richard Cheng @ 2026-08-12 8:17 UTC (permalink / raw) To: Guixin Liu Cc: Davidlohr Bueso, Jonathan Cameron, Dave Jiang, Alison Schofield, Vishal Verma, Dan Williams, Ira Weiny, Li Ming, linux-cxl On Wed, Aug 12, 2026 at 02:09:12PM +0800, Guixin Liu wrote: > cxl_endpoint_gather_bandwidth() declares three access_coordinate arrays on > the stack - pci_coord, sw_coord and ep_coord - without initializing them, > and relies on its helpers to fill every member. None of them does. > cxl_pci_get_bandwidth() and cxl_port_get_switch_dport_bandwidth() assign > only read_bandwidth and write_bandwidth, and > __cxl_coordinates_combine() assigns an output bandwidth only when both > input bandwidths are non-zero. Every member a producer declines to set is > read back as whatever was on the stack. > > Both cases occur on real topologies. The latency members of pci_coord and > sw_coord are never written, yet __cxl_coordinates_combine() sums them > unconditionally, so the latency reads are undefined on every call. And a > device whose CDAT DSLBIS reports no bandwidth for an access class leaves > perf->cdat_coord zero for that class, which is exactly the condition that > makes __cxl_coordinates_combine() skip the bandwidth assignment and leave > the ep_coord entry untouched. > > The ep_coord case escapes the function: cxl_bandwidth_add() accumulates it > into the per-upstream-port aggregate that is published through the region's > access coordinate sysfs attributes, so stack contents are reported to > userspace as a bandwidth figure. The latency sums are discarded by > cxl_bandwidth_add() rather than published, but they are still computed from > uninitialized memory. > > Zero initialize the three arrays. Zero is already the value this code uses > for "not reported" - both the __cxl_coordinates_combine() guard and > coordinates_valid() test for it - so a member no producer sets now reads > back as unknown rather than as a plausible number. > > Fixes: a5ab0de0ebaa ("cxl: Calculate region bandwidth of targets with shared upstream link") > Signed-off-by: Guixin Liu <kanie@linux.alibaba.com> > --- > This was patch 6/8 of the "cxl: Assorted fixes" series [1]. Per review > feedback that series is not being reworked as a whole; the fixes are resent > individually instead. Patches 1, 2 and 7 of the series are dropped, as those > issues are already fixed in cxl/next. > > v1->v2: > - rebase onto cxl/next > - rewrite the commit message to describe the behaviour rather than narrate > the code change (Alison Schofield) > > [1] https://lore.kernel.org/linux-cxl/20260811113608.2815625-1-kanie@linux.alibaba.com/ > > drivers/cxl/core/cdat.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c > index 5c9f07262513..3c6a1537f89b 100644 > --- a/drivers/cxl/core/cdat.c > +++ b/drivers/cxl/core/cdat.c > @@ -633,9 +633,9 @@ static int cxl_endpoint_gather_bandwidth(struct cxl_region *cxlr, > struct cxl_port *endpoint = to_cxl_port(cxled->cxld.dev.parent); > struct cxl_port *parent_port = to_cxl_port(endpoint->dev.parent); > struct cxl_port *gp_port = to_cxl_port(parent_port->dev.parent); > - struct access_coordinate pci_coord[ACCESS_COORDINATE_MAX]; > - struct access_coordinate sw_coord[ACCESS_COORDINATE_MAX]; > - struct access_coordinate ep_coord[ACCESS_COORDINATE_MAX]; > + struct access_coordinate pci_coord[ACCESS_COORDINATE_MAX] = { }; > + struct access_coordinate sw_coord[ACCESS_COORDINATE_MAX] = { }; > + struct access_coordinate ep_coord[ACCESS_COORDINATE_MAX] = { }; > struct cxl_memdev *cxlmd = cxled_to_memdev(cxled); > struct cxl_dev_state *cxlds = cxlmd->cxlds; > struct pci_dev *pdev = to_pci_dev(cxlds->dev); > > base-commit: 7098e9cd98a05c0c5de2fae0c2465f9d966fdd07 > -- > 2.43.7 > > Code changes looks sane to me, but I'm curious what compiler did you use and what level of optimization did you open ? Normally compiler can figure what whether to init them on their own. But perhaps since the arrays are passed to the helpers in other source files, in this scenario the compiler can't initialize them reliably, not sure about this. Otherwise I have no issue. Reviewed-by: Richard Cheng <icheng@nvidia.com> Best regards, Richard Cheng. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] cxl/cdat: Fix uninitialized stack use in endpoint bandwidth gathering 2026-08-12 8:17 ` Richard Cheng @ 2026-08-12 8:45 ` Guixin Liu 0 siblings, 0 replies; 6+ messages in thread From: Guixin Liu @ 2026-08-12 8:45 UTC (permalink / raw) To: Richard Cheng Cc: Davidlohr Bueso, Jonathan Cameron, Dave Jiang, Alison Schofield, Vishal Verma, Dan Williams, Ira Weiny, Li Ming, linux-cxl 在 2026/8/12 16:17, Richard Cheng 写道: > On Wed, Aug 12, 2026 at 02:09:12PM +0800, Guixin Liu wrote: >> cxl_endpoint_gather_bandwidth() declares three access_coordinate arrays on >> the stack - pci_coord, sw_coord and ep_coord - without initializing them, >> and relies on its helpers to fill every member. None of them does. >> cxl_pci_get_bandwidth() and cxl_port_get_switch_dport_bandwidth() assign >> only read_bandwidth and write_bandwidth, and >> __cxl_coordinates_combine() assigns an output bandwidth only when both >> input bandwidths are non-zero. Every member a producer declines to set is >> read back as whatever was on the stack. >> >> Both cases occur on real topologies. The latency members of pci_coord and >> sw_coord are never written, yet __cxl_coordinates_combine() sums them >> unconditionally, so the latency reads are undefined on every call. And a >> device whose CDAT DSLBIS reports no bandwidth for an access class leaves >> perf->cdat_coord zero for that class, which is exactly the condition that >> makes __cxl_coordinates_combine() skip the bandwidth assignment and leave >> the ep_coord entry untouched. >> >> The ep_coord case escapes the function: cxl_bandwidth_add() accumulates it >> into the per-upstream-port aggregate that is published through the region's >> access coordinate sysfs attributes, so stack contents are reported to >> userspace as a bandwidth figure. The latency sums are discarded by >> cxl_bandwidth_add() rather than published, but they are still computed from >> uninitialized memory. >> >> Zero initialize the three arrays. Zero is already the value this code uses >> for "not reported" - both the __cxl_coordinates_combine() guard and >> coordinates_valid() test for it - so a member no producer sets now reads >> back as unknown rather than as a plausible number. >> >> Fixes: a5ab0de0ebaa ("cxl: Calculate region bandwidth of targets with shared upstream link") >> Signed-off-by: Guixin Liu <kanie@linux.alibaba.com> >> --- >> This was patch 6/8 of the "cxl: Assorted fixes" series [1]. Per review >> feedback that series is not being reworked as a whole; the fixes are resent >> individually instead. Patches 1, 2 and 7 of the series are dropped, as those >> issues are already fixed in cxl/next. >> >> v1->v2: >> - rebase onto cxl/next >> - rewrite the commit message to describe the behaviour rather than narrate >> the code change (Alison Schofield) >> >> [1] https://lore.kernel.org/linux-cxl/20260811113608.2815625-1-kanie@linux.alibaba.com/ >> >> drivers/cxl/core/cdat.c | 6 +++--- >> 1 file changed, 3 insertions(+), 3 deletions(-) >> >> diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c >> index 5c9f07262513..3c6a1537f89b 100644 >> --- a/drivers/cxl/core/cdat.c >> +++ b/drivers/cxl/core/cdat.c >> @@ -633,9 +633,9 @@ static int cxl_endpoint_gather_bandwidth(struct cxl_region *cxlr, >> struct cxl_port *endpoint = to_cxl_port(cxled->cxld.dev.parent); >> struct cxl_port *parent_port = to_cxl_port(endpoint->dev.parent); >> struct cxl_port *gp_port = to_cxl_port(parent_port->dev.parent); >> - struct access_coordinate pci_coord[ACCESS_COORDINATE_MAX]; >> - struct access_coordinate sw_coord[ACCESS_COORDINATE_MAX]; >> - struct access_coordinate ep_coord[ACCESS_COORDINATE_MAX]; >> + struct access_coordinate pci_coord[ACCESS_COORDINATE_MAX] = { }; >> + struct access_coordinate sw_coord[ACCESS_COORDINATE_MAX] = { }; >> + struct access_coordinate ep_coord[ACCESS_COORDINATE_MAX] = { }; >> struct cxl_memdev *cxlmd = cxled_to_memdev(cxled); >> struct cxl_dev_state *cxlds = cxlmd->cxlds; >> struct pci_dev *pdev = to_pci_dev(cxlds->dev); >> >> base-commit: 7098e9cd98a05c0c5de2fae0c2465f9d966fdd07 >> -- >> 2.43.7 >> >> > Code changes looks sane to me, but I'm curious what compiler did you use > and what level of optimization did you open ? > Normally compiler can figure what whether to init them on their own. Thanks for the review. gcc 10.2.1, with the kernel's usual -O2, but the optimisation level does not really enter into it: C does not initialise automatic storage at any level, so an uninitialised array just holds whatever the previous frame left on the stack. There is no point at which the compiler is entitled to zero it. What does change the observable behaviour is CONFIG_INIT_STACK_ALL_ZERO, which turns on -ftrivial-auto-var-init=zero and is the default choice whenever the compiler supports it (security/Kconfig.hardening). With that enabled the arrays read back as zero, so the bug presents as bandwidth and latency being reported as 0 instead of as stack residue. My build has CONFIG_INIT_STACK_NONE=y, where the values are genuinely leftover stack contents, and they reach userspace through the access coordinate sysfs attributes either way. > But perhaps since the arrays are passed to the helpers in other source > files, in this scenario the compiler can't initialize them reliably, not sure > about this. Your hunch is right as far as the diagnostic goes: the arrays have their address taken and are handed to functions in other translation units, and gcc's uninitialised-use analysis gives up once the pointer escapes, so -Wmaybe-uninitialized stays quiet. That is why this one is not caught by a build warning. > > Otherwise I have no issue. > > Reviewed-by: Richard Cheng <icheng@nvidia.com> One thing to flag: I have posted v3 in the meantime, as "[PATCH v3 0/2] cxl: Fix uninitialized access coordinates". Patch 1 there is this patch plus one additional hunk, since the coords[] array in cxl_switch_gather_bandwidth() has the same defect, and patch 2 handles the RCD case where cxl_endpoint_get_perf_coordinates() returns 0 without writing the caller's array at all. I did not carry your Reviewed-by across, as the patch grew - could you have a look at v3 and add it there if it still looks good to you? Best Regards, Guixin Liu > > Best regards, > Richard Cheng. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] cxl/cdat: Fix uninitialized stack use in endpoint bandwidth gathering 2026-08-12 6:09 [PATCH v2] cxl/cdat: Fix uninitialized stack use in endpoint bandwidth gathering Guixin Liu 2026-08-12 6:22 ` sashiko-bot 2026-08-12 8:17 ` Richard Cheng @ 2026-08-12 11:44 ` Li Ming 2 siblings, 0 replies; 6+ messages in thread From: Li Ming @ 2026-08-12 11:44 UTC (permalink / raw) To: Guixin Liu, Davidlohr Bueso, Jonathan Cameron, Dave Jiang, Alison Schofield, Vishal Verma, Dan Williams, Ira Weiny Cc: linux-cxl 在 2026/8/12 14:09, Guixin Liu 写道: > cxl_endpoint_gather_bandwidth() declares three access_coordinate arrays on > the stack - pci_coord, sw_coord and ep_coord - without initializing them, > and relies on its helpers to fill every member. None of them does. > cxl_pci_get_bandwidth() and cxl_port_get_switch_dport_bandwidth() assign > only read_bandwidth and write_bandwidth, and > __cxl_coordinates_combine() assigns an output bandwidth only when both > input bandwidths are non-zero. Every member a producer declines to set is > read back as whatever was on the stack. > > Both cases occur on real topologies. The latency members of pci_coord and > sw_coord are never written, yet __cxl_coordinates_combine() sums them > unconditionally, so the latency reads are undefined on every call. And a > device whose CDAT DSLBIS reports no bandwidth for an access class leaves > perf->cdat_coord zero for that class, which is exactly the condition that > makes __cxl_coordinates_combine() skip the bandwidth assignment and leave > the ep_coord entry untouched. > > The ep_coord case escapes the function: cxl_bandwidth_add() accumulates it > into the per-upstream-port aggregate that is published through the region's > access coordinate sysfs attributes, so stack contents are reported to > userspace as a bandwidth figure. The latency sums are discarded by > cxl_bandwidth_add() rather than published, but they are still computed from > uninitialized memory. > > Zero initialize the three arrays. Zero is already the value this code uses > for "not reported" - both the __cxl_coordinates_combine() guard and > coordinates_valid() test for it - so a member no producer sets now reads > back as unknown rather than as a plausible number. > > Fixes: a5ab0de0ebaa ("cxl: Calculate region bandwidth of targets with shared upstream link") > Signed-off-by: Guixin Liu <kanie@linux.alibaba.com> Reviewed-by: Li Ming <ming.li@zohomail.com> > --- > This was patch 6/8 of the "cxl: Assorted fixes" series [1]. Per review > feedback that series is not being reworked as a whole; the fixes are resent > individually instead. Patches 1, 2 and 7 of the series are dropped, as those > issues are already fixed in cxl/next. > > v1->v2: > - rebase onto cxl/next > - rewrite the commit message to describe the behaviour rather than narrate > the code change (Alison Schofield) > > [1] https://lore.kernel.org/linux-cxl/20260811113608.2815625-1-kanie@linux.alibaba.com/ > > drivers/cxl/core/cdat.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c > index 5c9f07262513..3c6a1537f89b 100644 > --- a/drivers/cxl/core/cdat.c > +++ b/drivers/cxl/core/cdat.c > @@ -633,9 +633,9 @@ static int cxl_endpoint_gather_bandwidth(struct cxl_region *cxlr, > struct cxl_port *endpoint = to_cxl_port(cxled->cxld.dev.parent); > struct cxl_port *parent_port = to_cxl_port(endpoint->dev.parent); > struct cxl_port *gp_port = to_cxl_port(parent_port->dev.parent); > - struct access_coordinate pci_coord[ACCESS_COORDINATE_MAX]; > - struct access_coordinate sw_coord[ACCESS_COORDINATE_MAX]; > - struct access_coordinate ep_coord[ACCESS_COORDINATE_MAX]; > + struct access_coordinate pci_coord[ACCESS_COORDINATE_MAX] = { }; > + struct access_coordinate sw_coord[ACCESS_COORDINATE_MAX] = { }; > + struct access_coordinate ep_coord[ACCESS_COORDINATE_MAX] = { }; > struct cxl_memdev *cxlmd = cxled_to_memdev(cxled); > struct cxl_dev_state *cxlds = cxlmd->cxlds; > struct pci_dev *pdev = to_pci_dev(cxlds->dev); > > base-commit: 7098e9cd98a05c0c5de2fae0c2465f9d966fdd07 ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-08-12 11:44 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-08-12 6:09 [PATCH v2] cxl/cdat: Fix uninitialized stack use in endpoint bandwidth gathering Guixin Liu 2026-08-12 6:22 ` sashiko-bot 2026-08-12 6:44 ` Guixin Liu 2026-08-12 8:17 ` Richard Cheng 2026-08-12 8:45 ` Guixin Liu 2026-08-12 11:44 ` Li Ming
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.