Skip to content

Commit 5bb5ccb

Browse files
zcxGGmuavpatel
authored andcommitted
riscv: perf: add guest vs host distinction
Introduce basic guest support in perf, enabling it to distinguish between PMU interrupts in the host or guest, and collect fundamental information. Signed-off-by: Quan Zhou <zhouquan@iscas.ac.cn> Reviewed-by: Andrew Jones <ajones@ventanamicro.com> Link: https://lore.kernel.org/r/a67d527dc1b11493fe11f7f53584772fdd983744.1728957131.git.zhouquan@iscas.ac.cn Signed-off-by: Anup Patel <anup@brainfault.org>
1 parent 8198375 commit 5bb5ccb

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

arch/riscv/include/asm/perf_event.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@
88
#ifndef _ASM_RISCV_PERF_EVENT_H
99
#define _ASM_RISCV_PERF_EVENT_H
1010

11+
#ifdef CONFIG_PERF_EVENTS
1112
#include <linux/perf_event.h>
13+
extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
14+
extern unsigned long perf_misc_flags(struct pt_regs *regs);
15+
#define perf_misc_flags(regs) perf_misc_flags(regs)
1216
#define perf_arch_bpf_user_pt_regs(regs) (struct user_regs_struct *)regs
1317

1418
#define perf_arch_fetch_caller_regs(regs, __ip) { \
@@ -17,4 +21,6 @@
1721
(regs)->sp = current_stack_pointer; \
1822
(regs)->status = SR_PP; \
1923
}
24+
#endif
25+
2026
#endif /* _ASM_RISCV_PERF_EVENT_H */

arch/riscv/kernel/perf_callchain.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,49 @@ static bool fill_callchain(void *entry, unsigned long pc)
2828
void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
2929
struct pt_regs *regs)
3030
{
31+
if (perf_guest_state()) {
32+
/* TODO: We don't support guest os callchain now */
33+
return;
34+
}
35+
3136
arch_stack_walk_user(fill_callchain, entry, regs);
3237
}
3338

3439
void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
3540
struct pt_regs *regs)
3641
{
42+
if (perf_guest_state()) {
43+
/* TODO: We don't support guest os callchain now */
44+
return;
45+
}
46+
3747
walk_stackframe(NULL, regs, fill_callchain, entry);
3848
}
49+
50+
unsigned long perf_instruction_pointer(struct pt_regs *regs)
51+
{
52+
if (perf_guest_state())
53+
return perf_guest_get_ip();
54+
55+
return instruction_pointer(regs);
56+
}
57+
58+
unsigned long perf_misc_flags(struct pt_regs *regs)
59+
{
60+
unsigned int guest_state = perf_guest_state();
61+
unsigned long misc = 0;
62+
63+
if (guest_state) {
64+
if (guest_state & PERF_GUEST_USER)
65+
misc |= PERF_RECORD_MISC_GUEST_USER;
66+
else
67+
misc |= PERF_RECORD_MISC_GUEST_KERNEL;
68+
} else {
69+
if (user_mode(regs))
70+
misc |= PERF_RECORD_MISC_USER;
71+
else
72+
misc |= PERF_RECORD_MISC_KERNEL;
73+
}
74+
75+
return misc;
76+
}

0 commit comments

Comments
 (0)