* [PATCH] perf kvm/riscv: Fix event key collision between interrupts and exceptions
@ 2026-07-04 2:36 fangyu.yu
2026-07-04 2:44 ` sashiko-bot
0 siblings, 1 reply; 2+ messages in thread
From: fangyu.yu @ 2026-07-04 2:36 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim
Cc: Mark Rutland, Alexander Shishkin, Jiri Olsa, Ian Rogers,
Adrian Hunter, James Clark, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Alexandre Ghiti, Quan Zhou, Anup Patel,
linux-perf-users, linux-kernel, linux-riscv, guoren, Fangyu Yu
From: Fangyu Yu <fangyu.yu@linux.alibaba.com>
RISC-V scause encodes interrupts and exceptions in the same
cause field, with bit 63 on RV64 and bit 31 on RV32 used to
distinguish interrupts from exceptions. The lower cause bits
overlap between the two namespaces, so masking off the interrupt
bit makes distinct IRQ and exception events map to the same key.
This affects perf kvm stat exit-reason decoding. For example,
IRQ_S_TIMER and EXC_LOAD_ACCESS both use cause code 5, and can be
misreported as the wrong exit reason.
Fix this by using the full scause value as the lookup key in
event_get_key(). Also split TRAP() into TRAP_EXC() and
TRAP_IRQ() so interrupt entries are encoded with the
architecture-specific IRQ bit set, matching the value reported by
hardware.
Fixes: ceea279f9376 ("perf kvm stat: Remove use of the arch directory")
Signed-off-by: Fangyu Yu <fangyu.yu@linux.alibaba.com>
---
.../perf/util/kvm-stat-arch/kvm-stat-riscv.c | 4 +--
.../util/kvm-stat-arch/riscv_trap_types.h | 27 ++++++++++---------
2 files changed, 15 insertions(+), 16 deletions(-)
diff --git a/tools/perf/util/kvm-stat-arch/kvm-stat-riscv.c b/tools/perf/util/kvm-stat-arch/kvm-stat-riscv.c
index 967bba261a47..829096a41a3b 100644
--- a/tools/perf/util/kvm-stat-arch/kvm-stat-riscv.c
+++ b/tools/perf/util/kvm-stat-arch/kvm-stat-riscv.c
@@ -23,10 +23,8 @@ static const char * const __kvm_events_tp[] = {
static void event_get_key(struct perf_sample *sample,
struct event_key *key)
{
- int xlen = 64; // TODO: 32-bit support.
-
key->info = 0;
- key->key = perf_sample__intval(sample, kvm_exit_reason(EM_RISCV)) & ~CAUSE_IRQ_FLAG(xlen);
+ key->key = perf_sample__intval(sample, kvm_exit_reason(EM_RISCV));
key->exit_reasons = riscv_exit_reasons;
}
diff --git a/tools/perf/util/kvm-stat-arch/riscv_trap_types.h b/tools/perf/util/kvm-stat-arch/riscv_trap_types.h
index aa5d24fab4ee..da1f1ce55326 100644
--- a/tools/perf/util/kvm-stat-arch/riscv_trap_types.h
+++ b/tools/perf/util/kvm-stat-arch/riscv_trap_types.h
@@ -38,20 +38,21 @@
#define EXC_VIRTUAL_INST_FAULT 22
#define EXC_STORE_GUEST_PAGE_FAULT 23
-#define TRAP(x) { x, #x }
+#define TRAP_EXC(x) { x, #x }
+#define TRAP_IRQ(x) { (x) | CAUSE_IRQ_FLAG(__riscv_xlen), #x }
#define kvm_riscv_trap_class \
- TRAP(IRQ_S_SOFT), TRAP(IRQ_VS_SOFT), TRAP(IRQ_M_SOFT), \
- TRAP(IRQ_S_TIMER), TRAP(IRQ_VS_TIMER), TRAP(IRQ_M_TIMER), \
- TRAP(IRQ_S_EXT), TRAP(IRQ_VS_EXT), TRAP(IRQ_M_EXT), \
- TRAP(IRQ_S_GEXT), TRAP(IRQ_PMU_OVF), \
- TRAP(EXC_INST_MISALIGNED), TRAP(EXC_INST_ACCESS), TRAP(EXC_INST_ILLEGAL), \
- TRAP(EXC_BREAKPOINT), TRAP(EXC_LOAD_MISALIGNED), TRAP(EXC_LOAD_ACCESS), \
- TRAP(EXC_STORE_MISALIGNED), TRAP(EXC_STORE_ACCESS), TRAP(EXC_SYSCALL), \
- TRAP(EXC_HYPERVISOR_SYSCALL), TRAP(EXC_SUPERVISOR_SYSCALL), \
- TRAP(EXC_INST_PAGE_FAULT), TRAP(EXC_LOAD_PAGE_FAULT), \
- TRAP(EXC_STORE_PAGE_FAULT), TRAP(EXC_INST_GUEST_PAGE_FAULT), \
- TRAP(EXC_LOAD_GUEST_PAGE_FAULT), TRAP(EXC_VIRTUAL_INST_FAULT), \
- TRAP(EXC_STORE_GUEST_PAGE_FAULT)
+ TRAP_IRQ(IRQ_S_SOFT), TRAP_IRQ(IRQ_VS_SOFT), TRAP_IRQ(IRQ_M_SOFT), \
+ TRAP_IRQ(IRQ_S_TIMER), TRAP_IRQ(IRQ_VS_TIMER), TRAP_IRQ(IRQ_M_TIMER), \
+ TRAP_IRQ(IRQ_S_EXT), TRAP_IRQ(IRQ_VS_EXT), TRAP_IRQ(IRQ_M_EXT), \
+ TRAP_IRQ(IRQ_S_GEXT), TRAP_IRQ(IRQ_PMU_OVF), \
+ TRAP_EXC(EXC_INST_MISALIGNED), TRAP_EXC(EXC_INST_ACCESS), TRAP_EXC(EXC_INST_ILLEGAL), \
+ TRAP_EXC(EXC_BREAKPOINT), TRAP_EXC(EXC_LOAD_MISALIGNED), TRAP_EXC(EXC_LOAD_ACCESS), \
+ TRAP_EXC(EXC_STORE_MISALIGNED), TRAP_EXC(EXC_STORE_ACCESS), TRAP_EXC(EXC_SYSCALL), \
+ TRAP_EXC(EXC_HYPERVISOR_SYSCALL), TRAP_EXC(EXC_SUPERVISOR_SYSCALL), \
+ TRAP_EXC(EXC_INST_PAGE_FAULT), TRAP_EXC(EXC_LOAD_PAGE_FAULT), \
+ TRAP_EXC(EXC_STORE_PAGE_FAULT), TRAP_EXC(EXC_INST_GUEST_PAGE_FAULT), \
+ TRAP_EXC(EXC_LOAD_GUEST_PAGE_FAULT), TRAP_EXC(EXC_VIRTUAL_INST_FAULT), \
+ TRAP_EXC(EXC_STORE_GUEST_PAGE_FAULT)
#endif /* ARCH_PERF_RISCV_TRAP_TYPES_H */
--
2.50.1
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH] perf kvm/riscv: Fix event key collision between interrupts and exceptions
2026-07-04 2:36 [PATCH] perf kvm/riscv: Fix event key collision between interrupts and exceptions fangyu.yu
@ 2026-07-04 2:44 ` sashiko-bot
0 siblings, 0 replies; 2+ messages in thread
From: sashiko-bot @ 2026-07-04 2:44 UTC (permalink / raw)
To: fangyu.yu; +Cc: linux-perf-users
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Using the compiler predefined macro `__riscv_xlen` in a static array initializer causes build failures on non-RISC-V architectures and breaks cross-architecture analysis.
--
commit e5247b904831a2084b1e8757d98d388a7fc008c0
Author: Fangyu Yu <fangyu.yu@linux.alibaba.com>
perf kvm/riscv: Fix event key collision between interrupts and exceptions
This commit updates the RISC-V KVM stat exit-reason decoding to use the
full scause value, avoiding key collisions between interrupts and exceptions.
It splits the TRAP macro into TRAP_EXC and TRAP_IRQ to encode interrupts
with the architecture-specific IRQ bit matching the hardware value.
> diff --git a/tools/perf/util/kvm-stat-arch/kvm-stat-riscv.c b/tools/perf/util/kvm-stat-arch/kvm-stat-riscv.c
> index 967bba261a475..829096a41a3b2 100644
> --- a/tools/perf/util/kvm-stat-arch/kvm-stat-riscv.c
> +++ b/tools/perf/util/kvm-stat-arch/kvm-stat-riscv.c
> @@ -23,10 +23,8 @@ static const char * const __kvm_events_tp[] = {
> static void event_get_key(struct perf_sample *sample,
> struct event_key *key)
> {
> - int xlen = 64; // TODO: 32-bit support.
> -
> key->info = 0;
> - key->key = perf_sample__intval(sample, kvm_exit_reason(EM_RISCV)) & ~CAUSE_IRQ_FLAG(xlen);
> + key->key = perf_sample__intval(sample, kvm_exit_reason(EM_RISCV));
[Severity: Medium]
Does this code introduce a regression by preventing dynamic cross-architecture
bitness decoding when analyzing traces? With the dynamic mask removed here,
the lookup now depends entirely on the statically sized table.
[ ... ]
> diff --git a/tools/perf/util/kvm-stat-arch/riscv_trap_types.h b/tools/perf/util/kvm-stat-arch/riscv_trap_types.h
> index aa5d24fab4ee3..da1f1ce55326c 100644
> --- a/tools/perf/util/kvm-stat-arch/riscv_trap_types.h
> +++ b/tools/perf/util/kvm-stat-arch/riscv_trap_types.h
> @@ -38,20 +38,21 @@
> #define EXC_VIRTUAL_INST_FAULT 22
> #define EXC_STORE_GUEST_PAGE_FAULT 23
>
> -#define TRAP(x) { x, #x }
> +#define TRAP_EXC(x) { x, #x }
> +#define TRAP_IRQ(x) { (x) | CAUSE_IRQ_FLAG(__riscv_xlen), #x }
[Severity: Medium]
Does using the compiler predefined macro __riscv_xlen in this static array
initializer cause a regression by breaking the build on non-RISC-V
architectures?
When building perf cross-platform, this macro is not defined on hosts like
x86_64 or ARM64, and the static initialization in riscv_exit_reasons expands
this macro.
Also, does baking the host's compile-time word size into TRAP_IRQ introduce a
regression for cross-platform analysis? For example, if a 64-bit perf binary
processes a 32-bit KVM trace, it will expect bit 63 to be set for interrupts,
which would fail to decode 32-bit KVM events using bit 31.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260704023608.24971-1-fangyu.yu@linux.alibaba.com?part=1
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-07-04 2:44 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-04 2:36 [PATCH] perf kvm/riscv: Fix event key collision between interrupts and exceptions fangyu.yu
2026-07-04 2:44 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox