0001
0002
0003
0004
0005
0006
0007 #include <linux/kernel.h>
0008 #include <linux/sched.h>
0009 #include <linux/perf_event.h>
0010 #include <linux/percpu.h>
0011 #include <linux/uaccess.h>
0012 #include <linux/mm.h>
0013 #include <asm/ptrace.h>
0014 #include <asm/sigcontext.h>
0015 #include <asm/ucontext.h>
0016 #include <asm/vdso.h>
0017 #include <asm/pte-walk.h>
0018
0019 #include "callchain.h"
0020
0021 static int read_user_stack_64(const unsigned long __user *ptr, unsigned long *ret)
0022 {
0023 return __read_user_stack(ptr, ret, sizeof(*ret));
0024 }
0025
0026
0027
0028
0029 struct signal_frame_64 {
0030 char dummy[__SIGNAL_FRAMESIZE];
0031 struct ucontext uc;
0032 unsigned long unused[2];
0033 unsigned int tramp[6];
0034 struct siginfo *pinfo;
0035 void *puc;
0036 struct siginfo info;
0037 char abigap[288];
0038 };
0039
0040 static int is_sigreturn_64_address(unsigned long nip, unsigned long fp)
0041 {
0042 if (nip == fp + offsetof(struct signal_frame_64, tramp))
0043 return 1;
0044 if (current->mm->context.vdso &&
0045 nip == VDSO64_SYMBOL(current->mm->context.vdso, sigtramp_rt64))
0046 return 1;
0047 return 0;
0048 }
0049
0050
0051
0052
0053
0054 static int sane_signal_64_frame(unsigned long sp)
0055 {
0056 struct signal_frame_64 __user *sf;
0057 unsigned long pinfo, puc;
0058
0059 sf = (struct signal_frame_64 __user *) sp;
0060 if (read_user_stack_64((unsigned long __user *) &sf->pinfo, &pinfo) ||
0061 read_user_stack_64((unsigned long __user *) &sf->puc, &puc))
0062 return 0;
0063 return pinfo == (unsigned long) &sf->info &&
0064 puc == (unsigned long) &sf->uc;
0065 }
0066
0067 void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry,
0068 struct pt_regs *regs)
0069 {
0070 unsigned long sp, next_sp;
0071 unsigned long next_ip;
0072 unsigned long lr;
0073 long level = 0;
0074 struct signal_frame_64 __user *sigframe;
0075 unsigned long __user *fp, *uregs;
0076
0077 next_ip = perf_instruction_pointer(regs);
0078 lr = regs->link;
0079 sp = regs->gpr[1];
0080 perf_callchain_store(entry, next_ip);
0081
0082 while (entry->nr < entry->max_stack) {
0083 fp = (unsigned long __user *) sp;
0084 if (invalid_user_sp(sp) || read_user_stack_64(fp, &next_sp))
0085 return;
0086 if (level > 0 && read_user_stack_64(&fp[2], &next_ip))
0087 return;
0088
0089
0090
0091
0092
0093
0094
0095 if (next_sp - sp >= sizeof(struct signal_frame_64) &&
0096 (is_sigreturn_64_address(next_ip, sp) ||
0097 (level <= 1 && is_sigreturn_64_address(lr, sp))) &&
0098 sane_signal_64_frame(sp)) {
0099
0100
0101
0102 sigframe = (struct signal_frame_64 __user *) sp;
0103 uregs = sigframe->uc.uc_mcontext.gp_regs;
0104 if (read_user_stack_64(&uregs[PT_NIP], &next_ip) ||
0105 read_user_stack_64(&uregs[PT_LNK], &lr) ||
0106 read_user_stack_64(&uregs[PT_R1], &sp))
0107 return;
0108 level = 0;
0109 perf_callchain_store_context(entry, PERF_CONTEXT_USER);
0110 perf_callchain_store(entry, next_ip);
0111 continue;
0112 }
0113
0114 if (level == 0)
0115 next_ip = lr;
0116 perf_callchain_store(entry, next_ip);
0117 ++level;
0118 sp = next_sp;
0119 }
0120 }