From: sashiko-bot@kernel.org
To: "Dave Jiang" <dave.jiang@intel.com>
Cc: linux-perf-users@vger.kernel.org, linux-cxl@vger.kernel.org
Subject: Re: [PATCH v3 3/9] perf/cxl: Fix the counter overflow delta fixup
Date: Fri, 31 Jul 2026 23:37:24 +0000 [thread overview]
Message-ID: <20260731233725.724FE1F00AC4@smtp.kernel.org> (raw)
In-Reply-To: <20260731232827.401447-4-dave.jiang@intel.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
Pre-existing issues:
- [Medium] A race condition between a polled read and the overflow IRQ handler causes a double-counting of a full period if the polled read executes after the counter wraps but before the IRQ handler.
- [Medium] Missing validation for `info->counter_width` allows a non-compliant or buggy CXL device to trigger Undefined Behavior when `GENMASK_ULL` is evaluated.
--
--- Patch [3]: [PATCH v3 3/9] perf/cxl: Fix the counter overflow delta fixup ---
commit 333d6be6b59d292e876b5c4888ab33d0abc8cc03
Author: Dave Jiang <dave.jiang@intel.com>
perf/cxl: Fix the counter overflow delta fixup
This commit alters the CXL PMU counter overflow logic to condition the fixup
on new_cnt >= prev_cnt, aiming to correctly handle cases where the subtraction
cannot express the span over a period boundary, while accommodating events
that increment by more than 1 per cycle. It also modifies the period addition
to use mask + 1 to avoid undefined behavior on 64-bit counters.
Link: https://sashiko.dev/#/patchset/20260715191454.459673-1-dave@stgolabs.net?part=1
> diff --git a/drivers/perf/cxl_pmu.c b/drivers/perf/cxl_pmu.c
> index b16e2e4090a39..3511d049aea40 100644
> --- a/drivers/perf/cxl_pmu.c
> +++ b/drivers/perf/cxl_pmu.c
> @@ -689,7 +689,7 @@ static void __cxl_pmu_read(struct perf_event *event, bool overflow)
> {
> struct cxl_pmu_info *info = pmu_to_cxl_pmu_info(event->pmu);
> struct hw_perf_event *hwc = &event->hw;
> - u64 new_cnt, prev_cnt, delta;
> + u64 new_cnt, prev_cnt, delta, mask;
>
> do {
> prev_cnt = local64_read(&hwc->prev_count);
[ ... ]
> /*
> - * If we know an overflow occur then take that into account.
> - * Note counter is not reset as that would lose events
> + * The mask discards exactly the bit that says the counter wrapped, so a
> + * delta of one whole period reads back as 0, the same as no events at
> + * all. Only the overflow status distinguishes them, and new_cnt >=
> + * prev_cnt is that case, so add the period back. mask + 1 is
> + * 2^counter_width, which is 0 for a 64-bit counter - the right value to
> + * add once the top bit is gone, and no undefined 1 << 64.
> */
> - delta = (new_cnt - prev_cnt) & GENMASK_ULL(info->counter_width - 1, 0);
> - if (overflow && delta < GENMASK_ULL(info->counter_width - 1, 0))
> - delta += (1UL << info->counter_width);
> + mask = GENMASK_ULL(info->counter_width - 1, 0);
[Severity: Medium]
This is a pre-existing issue, but could a buggy or malicious CXL device
reporting a counter width of 0 (or > 64) trigger Undefined Behavior here?
If the device reports 0 for the counter width in the capability registers,
the driver reads this into info->counter_width without bounds validation.
When GENMASK_ULL(info->counter_width - 1, 0) is evaluated, it results in a
negative shift amount which leads to Undefined Behavior and corrupted PMU
masks.
> + delta = (new_cnt - prev_cnt) & mask;
> + if (overflow && new_cnt >= prev_cnt)
> + delta += mask + 1;
[Severity: Medium]
This isn't a bug introduced by this patch, but does this sequence allow a
race condition between a polled read and the overflow IRQ handler to
double-count a full period?
If the hardware counter wraps, setting the overflow bit, a polled read
(such as via perf stat -I) might read the counter before the hardware IRQ
is delivered.
The polled read would compute the delta, correctly including the period
because new_cnt is wrapped and smaller than prev_cnt, and then update
prev_count to the small post-wrap value.
When the delayed overflow IRQ handler subsequently runs, it reads the
overflow bit and calls __cxl_pmu_read(event, true). Because prev_cnt is
now the small post-wrap value, new_cnt >= prev_cnt evaluates to true.
The handler would then execute delta += mask + 1, incorrectly adding a
second full period because it assumes the wrap wasn't already consumed.
>
> local64_add(delta, &event->count);
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260731232827.401447-1-dave.jiang@intel.com?part=3
next prev parent reply other threads:[~2026-07-31 23:37 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-31 23:28 [PATCH v3 0/9] perf/cxlpmu: Misc sashiko raised issues fixes Dave Jiang
2026-07-31 23:28 ` [PATCH v3 1/9] perf/cxl: Program the requested event group on configurable counters Dave Jiang
2026-07-31 23:38 ` sashiko-bot
2026-07-31 23:28 ` [PATCH v3 2/9] perf/cxl: Clear stale event fields before reprogramming a counter Dave Jiang
2026-07-31 23:40 ` sashiko-bot
2026-07-31 23:28 ` [PATCH v3 3/9] perf/cxl: Fix the counter overflow delta fixup Dave Jiang
2026-07-31 23:37 ` sashiko-bot [this message]
2026-07-31 23:28 ` [PATCH v3 4/9] perf/cxl: Split the MSI vector out of info->irq Dave Jiang
2026-07-31 23:45 ` sashiko-bot
2026-07-31 23:28 ` [PATCH v3 5/9] perf/cxl: Accept an overflow interrupt on MSI message number 0 Dave Jiang
2026-07-31 23:28 ` [PATCH v3 6/9] perf/cxl: Don't share the overflow interrupt, and keep it pinned Dave Jiang
2026-07-31 23:50 ` sashiko-bot
2026-07-31 23:28 ` [PATCH v3 7/9] perf/cxl: Unfreeze counters after handling an overflow interrupt Dave Jiang
2026-07-31 23:40 ` sashiko-bot
2026-07-31 23:28 ` [PATCH v3 8/9] perf/cxl: Validate the hardware-reported counter width Dave Jiang
2026-07-31 23:28 ` [PATCH v3 9/9] perf/cxl: Don't log through pmu.dev in the overflow interrupt handler Dave Jiang
2026-07-31 23:46 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260731233725.724FE1F00AC4@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=dave.jiang@intel.com \
--cc=linux-cxl@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox