From 467806b6a055fc074d1cf55d49fdc07a57a35ae7 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Wed, 23 Jan 2013 16:52:18 +0000 Subject: [PATCH] --- yaml --- r: 351195 b: refs/heads/master c: 75e424620a4f8247e8877c224d0457efadf88201 h: refs/heads/master i: 351193: 716802474b5372e35b04db22d1b59f2d4ecd8250 351191: 9062223415ebec50f8136b5f21aa8122b3539685 v: v3 --- [refs] | 2 +- trunk/arch/arm64/include/asm/perf_event.h | 7 ++++- trunk/arch/arm64/kernel/perf_event.c | 37 +++++++++++++++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index 8b6b322e90b3..dc44e6d5b9cc 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 10a3cc2f764038e388d6fc3510142ae7d23fb2d9 +refs/heads/master: 75e424620a4f8247e8877c224d0457efadf88201 diff --git a/trunk/arch/arm64/include/asm/perf_event.h b/trunk/arch/arm64/include/asm/perf_event.h index a6fffd511c5e..d26d1d53c0d7 100644 --- a/trunk/arch/arm64/include/asm/perf_event.h +++ b/trunk/arch/arm64/include/asm/perf_event.h @@ -17,6 +17,11 @@ #ifndef __ASM_PERF_EVENT_H #define __ASM_PERF_EVENT_H -/* It's quiet around here... */ +#ifdef CONFIG_HW_PERF_EVENTS +struct pt_regs; +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) +#endif #endif diff --git a/trunk/arch/arm64/kernel/perf_event.c b/trunk/arch/arm64/kernel/perf_event.c index f7073c7b1ca9..1e49e5eb81e9 100644 --- a/trunk/arch/arm64/kernel/perf_event.c +++ b/trunk/arch/arm64/kernel/perf_event.c @@ -1331,6 +1331,11 @@ void perf_callchain_user(struct perf_callchain_entry *entry, { struct frame_tail __user *tail; + if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { + /* We don't support guest os callchain now */ + return; + } + tail = (struct frame_tail __user *)regs->regs[29]; while (entry->nr < PERF_MAX_STACK_DEPTH && @@ -1355,8 +1360,40 @@ void perf_callchain_kernel(struct perf_callchain_entry *entry, { struct stackframe frame; + if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { + /* We don't support guest os callchain now */ + return; + } + frame.fp = regs->regs[29]; frame.sp = regs->sp; frame.pc = regs->pc; walk_stackframe(&frame, callchain_trace, entry); } + +unsigned long perf_instruction_pointer(struct pt_regs *regs) +{ + if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) + return perf_guest_cbs->get_guest_ip(); + + return instruction_pointer(regs); +} + +unsigned long perf_misc_flags(struct pt_regs *regs) +{ + int misc = 0; + + if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { + if (perf_guest_cbs->is_user_mode()) + 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; +}