From: sashiko-bot@kernel.org
To: "Xixin Liu" <liuxixin@kylinos.cn>
Cc: linux-perf-users@vger.kernel.org
Subject: Re: [PATCH] perf: RISC-V: check cpu_hw_evt before dereference in overflow IRQ
Date: Fri, 07 Aug 2026 03:46:08 +0000 [thread overview]
Message-ID: <20260807034608.D4E841F000E9@smtp.kernel.org> (raw)
In-Reply-To: <prp0001riscv.1786064390.git.liuxixin@kylinos.cn>
Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
Pre-existing issues:
- [High] This problem wasn't introduced by this patch, but skipping non-sampling events during overflow handling fails to clear their hardware overflow state, causing an interrupt storm.
- [High] This problem wasn't introduced by this patch, but the `BIT()` macro is improperly used with 64-bit masks, causing undefined behavior and corruption on RV32 systems when counter indices are >= 32.
- [High] This problem wasn't introduced by this patch, but incorrect interrupt pending bit clearance bypasses alternative instructions, causing interrupt storms on custom PMUs (e.g., Andes).
- [High] This problem wasn't introduced by this patch, but global variable `cmask` is defined as a 32-bit `unsigned long` on RV32 but is processed as a 64-bit bitmap, causing out-of-bounds memory reads.
- [High] This problem wasn't introduced by this patch, but restarting overflowed hardware counters incorrectly mixes `unsigned long` arrays with `u64` masks, breaking counter isolation for indices >= 32 on RV32 systems.
--
--- Patch [1]: [PATCH] perf: RISC-V: check cpu_hw_evt before dereference in overflow IRQ ---
commit 4fa941d0eec411e362522077608e4fec275e7349
Author: Xixin Liu <liuxixin@kylinos.cn>
perf: RISC-V: check cpu_hw_evt before dereference in overflow IRQ
The overflow IRQ handler dereferences cpu_hw_evt before the null check.
Move the check first. Defensive only; the cookie is valid on the normal
path today.
> diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
> index 50220f7b46d9b..cb7148d0c87ad 100644
> --- a/drivers/perf/riscv_pmu_sbi.c
> +++ b/drivers/perf/riscv_pmu_sbi.c
> @@ -1050,11 +1050,13 @@ static irqreturn_t pmu_sbi_ovf_handler(int irq, void *dev)
> u64 overflowed_ctrs = 0;
> struct cpu_hw_events *cpu_hw_evt = dev;
> u64 start_clock = sched_clock();
> - struct riscv_pmu_snapshot_data *sdata = cpu_hw_evt->snapshot_addr;
> + struct riscv_pmu_snapshot_data *sdata;
>
> if (WARN_ON_ONCE(!cpu_hw_evt))
> return IRQ_NONE;
>
> + sdata = cpu_hw_evt->snapshot_addr;
> +
> /* Firmware counter don't support overflow yet */
> fidx = find_first_bit(cpu_hw_evt->used_hw_ctrs, RISCV_MAX_COUNTERS);
> if (fidx == RISCV_MAX_COUNTERS) {
[Severity: High]
This isn't a bug introduced by this patch, but does clearing the interrupt
pending bit manually here bypass alternative instructions?
For the Andes custom PMU, riscv_pmu_irq_num evaluates to 274. Using
BIT(274) on a 64-bit integer overflows and wraps to BIT(18), which would
erroneously clear bit 18 in the standard CSR_SIP register instead of using
the custom register.
Could this cause an interrupt storm on custom PMUs like Andes?
[Severity: High]
This problem wasn't introduced by this patch, but looking further down in
pmu_sbi_ovf_handler(), does skipping non-sampling events during overflow
handling fail to clear their hardware overflow state?
drivers/perf/riscv_pmu_sbi.c:pmu_sbi_ovf_handler() {
...
/* Skip if invalid event or user did not request a sampling */
if (!event || !is_sampling_event(event))
continue;
...
}
When a non-sampling counting event overflows, its bit isn't added to
overflowed_ctrs.
Consequently, when restarting the counter, the
SBI_PMU_START_FLAG_SET_INIT_VALUE flag isn't set, which means the hardware
overflow state (scountovf) isn't cleared and the interrupt is immediately
re-asserted.
Will this cause an interrupt storm?
[Severity: High]
This is a pre-existing issue, but does using the BIT() macro against 64-bit
variables like overflow and overflowed_ctrs cause undefined behavior on
32-bit RISC-V systems?
drivers/perf/riscv_pmu_sbi.c:pmu_sbi_ovf_handler() {
...
/* check if the corresponding bit is set in scountovf or overflow mask in shmem */
if (!(overflow & BIT(hidx)))
continue;
/*
* Keep a track of overflowed counters so that they can be started
* with updated initial value.
*/
overflowed_ctrs |= BIT(lidx);
...
}
On RV32, BIT() resolves to a 32-bit unsigned long, so shifting by 32 or more
results in truncation or wrapping.
Should this use BIT_ULL() instead?
[Severity: High]
This problem wasn't introduced by this patch, but is cmask undersized
for a 64-bit bitmap on 32-bit architectures?
drivers/perf/riscv_pmu_sbi.c:
...
static unsigned long cmask;
...
drivers/perf/riscv_pmu_sbi.c:pmu_sbi_event_map() {
...
for_each_set_bit(i, &cmask, RISCV_MAX_COUNTERS) {
...
}
On RV32, unsigned long is 4 bytes, but for_each_set_bit() with
RISCV_MAX_COUNTERS (64) expects an 8-byte buffer, which would cause an
out-of-bounds read into adjacent memory.
Should this be defined using DECLARE_BITMAP(cmask, RISCV_MAX_COUNTERS)?
[Severity: High]
This is a pre-existing issue, but does this bitwise operation incorrectly mix
a 32-bit unsigned long element (on RV32) with a 64-bit u64 mask?
drivers/perf/riscv_pmu_sbi.c:pmu_sbi_start_ovf_ctrs_sbi() {
...
ctr_start_mask = cpu_hw_evt->used_hw_ctrs[i] & ~ctr_ovf_mask;
...
}
For i=1 (handling counters 32-63), the 64-bit result is truncated when
assigned to the 32-bit ctr_start_mask, erroneously evaluating against the
lower 32 bits of ctr_ovf_mask instead of the upper 32 bits.
Could this break counter isolation for indices >= 32?
--
Sashiko AI review · https://sashiko.dev/#/patchset/prp0001riscv.1786064390.git.liuxixin@kylinos.cn?part=1
next prev parent reply other threads:[~2026-08-07 3:46 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-07 0:59 [PATCH] perf: RISC-V: check cpu_hw_evt before dereference in overflow IRQ Xixin Liu
2026-08-07 0:59 ` Xixin Liu
2026-08-07 3:46 ` sashiko-bot [this message]
2026-08-08 0:45 ` Paul Walmsley
2026-08-08 0:45 ` Paul Walmsley
2026-08-11 3:51 ` [PATCH v2 0/1] " Xixin Liu
2026-08-11 3:51 ` Xixin Liu
2026-08-11 3:51 ` [PATCH v2 1/1] " Xixin Liu
2026-08-11 3:51 ` Xixin Liu
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=20260807034608.D4E841F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=liuxixin@kylinos.cn \
--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 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.