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 #ifdef CONFIG_PPC64
0022 #include "../kernel/ppc32.h"
0023 #else
0024
0025 #define __SIGNAL_FRAMESIZE32 __SIGNAL_FRAMESIZE
0026 #define sigcontext32 sigcontext
0027 #define mcontext32 mcontext
0028 #define ucontext32 ucontext
0029 #define compat_siginfo_t struct siginfo
0030
0031 #endif
0032
0033 static int read_user_stack_32(const unsigned int __user *ptr, unsigned int *ret)
0034 {
0035 return __read_user_stack(ptr, ret, sizeof(*ret));
0036 }
0037
0038
0039
0040
0041 struct signal_frame_32 {
0042 char dummy[__SIGNAL_FRAMESIZE32];
0043 struct sigcontext32 sctx;
0044 struct mcontext32 mctx;
0045 int abigap[56];
0046 };
0047
0048
0049
0050
0051 struct rt_signal_frame_32 {
0052 char dummy[__SIGNAL_FRAMESIZE32 + 16];
0053 compat_siginfo_t info;
0054 struct ucontext32 uc;
0055 int abigap[56];
0056 };
0057
0058 static int is_sigreturn_32_address(unsigned int nip, unsigned int fp)
0059 {
0060 if (nip == fp + offsetof(struct signal_frame_32, mctx.mc_pad))
0061 return 1;
0062 if (current->mm->context.vdso &&
0063 nip == VDSO32_SYMBOL(current->mm->context.vdso, sigtramp32))
0064 return 1;
0065 return 0;
0066 }
0067
0068 static int is_rt_sigreturn_32_address(unsigned int nip, unsigned int fp)
0069 {
0070 if (nip == fp + offsetof(struct rt_signal_frame_32,
0071 uc.uc_mcontext.mc_pad))
0072 return 1;
0073 if (current->mm->context.vdso &&
0074 nip == VDSO32_SYMBOL(current->mm->context.vdso, sigtramp_rt32))
0075 return 1;
0076 return 0;
0077 }
0078
0079 static int sane_signal_32_frame(unsigned int sp)
0080 {
0081 struct signal_frame_32 __user *sf;
0082 unsigned int regs;
0083
0084 sf = (struct signal_frame_32 __user *) (unsigned long) sp;
0085 if (read_user_stack_32((unsigned int __user *) &sf->sctx.regs, ®s))
0086 return 0;
0087 return regs == (unsigned long) &sf->mctx;
0088 }
0089
0090 static int sane_rt_signal_32_frame(unsigned int sp)
0091 {
0092 struct rt_signal_frame_32 __user *sf;
0093 unsigned int regs;
0094
0095 sf = (struct rt_signal_frame_32 __user *) (unsigned long) sp;
0096 if (read_user_stack_32((unsigned int __user *) &sf->uc.uc_regs, ®s))
0097 return 0;
0098 return regs == (unsigned long) &sf->uc.uc_mcontext;
0099 }
0100
0101 static unsigned int __user *signal_frame_32_regs(unsigned int sp,
0102 unsigned int next_sp, unsigned int next_ip)
0103 {
0104 struct mcontext32 __user *mctx = NULL;
0105 struct signal_frame_32 __user *sf;
0106 struct rt_signal_frame_32 __user *rt_sf;
0107
0108
0109
0110
0111
0112
0113
0114 if (next_sp - sp >= sizeof(struct signal_frame_32) &&
0115 is_sigreturn_32_address(next_ip, sp) &&
0116 sane_signal_32_frame(sp)) {
0117 sf = (struct signal_frame_32 __user *) (unsigned long) sp;
0118 mctx = &sf->mctx;
0119 }
0120
0121 if (!mctx && next_sp - sp >= sizeof(struct rt_signal_frame_32) &&
0122 is_rt_sigreturn_32_address(next_ip, sp) &&
0123 sane_rt_signal_32_frame(sp)) {
0124 rt_sf = (struct rt_signal_frame_32 __user *) (unsigned long) sp;
0125 mctx = &rt_sf->uc.uc_mcontext;
0126 }
0127
0128 if (!mctx)
0129 return NULL;
0130 return mctx->mc_gregs;
0131 }
0132
0133 void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
0134 struct pt_regs *regs)
0135 {
0136 unsigned int sp, next_sp;
0137 unsigned int next_ip;
0138 unsigned int lr;
0139 long level = 0;
0140 unsigned int __user *fp, *uregs;
0141
0142 next_ip = perf_instruction_pointer(regs);
0143 lr = regs->link;
0144 sp = regs->gpr[1];
0145 perf_callchain_store(entry, next_ip);
0146
0147 while (entry->nr < entry->max_stack) {
0148 fp = (unsigned int __user *) (unsigned long) sp;
0149 if (invalid_user_sp(sp) || read_user_stack_32(fp, &next_sp))
0150 return;
0151 if (level > 0 && read_user_stack_32(&fp[1], &next_ip))
0152 return;
0153
0154 uregs = signal_frame_32_regs(sp, next_sp, next_ip);
0155 if (!uregs && level <= 1)
0156 uregs = signal_frame_32_regs(sp, next_sp, lr);
0157 if (uregs) {
0158
0159
0160
0161
0162 if (read_user_stack_32(&uregs[PT_NIP], &next_ip) ||
0163 read_user_stack_32(&uregs[PT_LNK], &lr) ||
0164 read_user_stack_32(&uregs[PT_R1], &sp))
0165 return;
0166 level = 0;
0167 perf_callchain_store_context(entry, PERF_CONTEXT_USER);
0168 perf_callchain_store(entry, next_ip);
0169 continue;
0170 }
0171
0172 if (level == 0)
0173 next_ip = lr;
0174 perf_callchain_store(entry, next_ip);
0175 ++level;
0176 sp = next_sp;
0177 }
0178 }