mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-18 19:39:04 -04:00
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>
This commit is contained in:
@@ -8,7 +8,11 @@
|
||||
#ifndef _ASM_RISCV_PERF_EVENT_H
|
||||
#define _ASM_RISCV_PERF_EVENT_H
|
||||
|
||||
#ifdef CONFIG_PERF_EVENTS
|
||||
#include <linux/perf_event.h>
|
||||
extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
|
||||
extern unsigned long perf_misc_flags(struct pt_regs *regs);
|
||||
#define perf_misc_flags(regs) perf_misc_flags(regs)
|
||||
#define perf_arch_bpf_user_pt_regs(regs) (struct user_regs_struct *)regs
|
||||
|
||||
#define perf_arch_fetch_caller_regs(regs, __ip) { \
|
||||
@@ -17,4 +21,6 @@
|
||||
(regs)->sp = current_stack_pointer; \
|
||||
(regs)->status = SR_PP; \
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_RISCV_PERF_EVENT_H */
|
||||
|
||||
@@ -28,11 +28,49 @@ static bool fill_callchain(void *entry, unsigned long pc)
|
||||
void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
if (perf_guest_state()) {
|
||||
/* TODO: We don't support guest os callchain now */
|
||||
return;
|
||||
}
|
||||
|
||||
arch_stack_walk_user(fill_callchain, entry, regs);
|
||||
}
|
||||
|
||||
void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
if (perf_guest_state()) {
|
||||
/* TODO: We don't support guest os callchain now */
|
||||
return;
|
||||
}
|
||||
|
||||
walk_stackframe(NULL, regs, fill_callchain, entry);
|
||||
}
|
||||
|
||||
unsigned long perf_instruction_pointer(struct pt_regs *regs)
|
||||
{
|
||||
if (perf_guest_state())
|
||||
return perf_guest_get_ip();
|
||||
|
||||
return instruction_pointer(regs);
|
||||
}
|
||||
|
||||
unsigned long perf_misc_flags(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int guest_state = perf_guest_state();
|
||||
unsigned long misc = 0;
|
||||
|
||||
if (guest_state) {
|
||||
if (guest_state & PERF_GUEST_USER)
|
||||
misc |= PERF_RECORD_MISC_GUEST_USER;
|
||||
else
|
||||
misc |= PERF_RECORD_MISC_GUEST_KERNEL;
|
||||
} else {
|
||||
if (user_mode(regs))
|
||||
misc |= PERF_RECORD_MISC_USER;
|
||||
else
|
||||
misc |= PERF_RECORD_MISC_KERNEL;
|
||||
}
|
||||
|
||||
return misc;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user