1/* 2 * Kernel and userspace stack tracing. 3 * 4 * This file is subject to the terms and conditions of the GNU General Public 5 * License. See the file "COPYING" in the main directory of this archive 6 * for more details. 7 * 8 * Copyright (C) 2001 - 2013 Tensilica Inc. 9 * Copyright (C) 2015 Cadence Design Systems Inc. 10 */ 11#include <linux/export.h> 12#include <linux/sched.h> 13#include <linux/stacktrace.h> 14 15#include <asm/stacktrace.h> 16#include <asm/traps.h> 17#include <asm/uaccess.h> 18 19#if IS_ENABLED(CONFIG_OPROFILE) || IS_ENABLED(CONFIG_PERF_EVENTS) 20 21/* Address of common_exception_return, used to check the 22 * transition from kernel to user space. 23 */ 24extern int common_exception_return; 25 26/* A struct that maps to the part of the frame containing the a0 and 27 * a1 registers. 28 */ 29struct frame_start { 30 unsigned long a0; 31 unsigned long a1; 32}; 33 34void xtensa_backtrace_user(struct pt_regs *regs, unsigned int depth, 35 int (*ufn)(struct stackframe *frame, void *data), 36 void *data) 37{ 38 unsigned long windowstart = regs->windowstart; 39 unsigned long windowbase = regs->windowbase; 40 unsigned long a0 = regs->areg[0]; 41 unsigned long a1 = regs->areg[1]; 42 unsigned long pc = regs->pc; 43 struct stackframe frame; 44 int index; 45 46 if (!depth--) 47 return; 48 49 frame.pc = pc; 50 frame.sp = a1; 51 52 if (pc == 0 || pc >= TASK_SIZE || ufn(&frame, data)) 53 return; 54 55 /* Two steps: 56 * 57 * 1. Look through the register window for the 58 * previous PCs in the call trace. 59 * 60 * 2. Look on the stack. 61 */ 62 63 /* Step 1. */ 64 /* Rotate WINDOWSTART to move the bit corresponding to 65 * the current window to the bit #0. 66 */ 67 windowstart = (windowstart << WSBITS | windowstart) >> windowbase; 68 69 /* Look for bits that are set, they correspond to 70 * valid windows. 71 */ 72 for (index = WSBITS - 1; (index > 0) && depth; depth--, index--) 73 if (windowstart & (1 << index)) { 74 /* Get the PC from a0 and a1. */ 75 pc = MAKE_PC_FROM_RA(a0, pc); 76 /* Read a0 and a1 from the 77 * corresponding position in AREGs. 78 */ 79 a0 = regs->areg[index * 4]; 80 a1 = regs->areg[index * 4 + 1]; 81 82 frame.pc = pc; 83 frame.sp = a1; 84 85 if (pc == 0 || pc >= TASK_SIZE || ufn(&frame, data)) 86 return; 87 } 88 89 /* Step 2. */ 90 /* We are done with the register window, we need to 91 * look through the stack. 92 */ 93 if (!depth) 94 return; 95 96 /* Start from the a1 register. */ 97 /* a1 = regs->areg[1]; */ 98 while (a0 != 0 && depth--) { 99 struct frame_start frame_start; 100 /* Get the location for a1, a0 for the 101 * previous frame from the current a1. 102 */ 103 unsigned long *psp = (unsigned long *)a1; 104 105 psp -= 4; 106 107 /* Check if the region is OK to access. */ 108 if (!access_ok(VERIFY_READ, psp, sizeof(frame_start))) 109 return; 110 /* Copy a1, a0 from user space stack frame. */ 111 if (__copy_from_user_inatomic(&frame_start, psp, 112 sizeof(frame_start))) 113 return; 114 115 pc = MAKE_PC_FROM_RA(a0, pc); 116 a0 = frame_start.a0; 117 a1 = frame_start.a1; 118 119 frame.pc = pc; 120 frame.sp = a1; 121 122 if (pc == 0 || pc >= TASK_SIZE || ufn(&frame, data)) 123 return; 124 } 125} 126EXPORT_SYMBOL(xtensa_backtrace_user); 127 128void xtensa_backtrace_kernel(struct pt_regs *regs, unsigned int depth, 129 int (*kfn)(struct stackframe *frame, void *data), 130 int (*ufn)(struct stackframe *frame, void *data), 131 void *data) 132{ 133 unsigned long pc = regs->depc > VALID_DOUBLE_EXCEPTION_ADDRESS ? 134 regs->depc : regs->pc; 135 unsigned long sp_start, sp_end; 136 unsigned long a0 = regs->areg[0]; 137 unsigned long a1 = regs->areg[1]; 138 139 sp_start = a1 & ~(THREAD_SIZE - 1); 140 sp_end = sp_start + THREAD_SIZE; 141 142 /* Spill the register window to the stack first. */ 143 spill_registers(); 144 145 /* Read the stack frames one by one and create the PC 146 * from the a0 and a1 registers saved there. 147 */ 148 while (a1 > sp_start && a1 < sp_end && depth--) { 149 struct stackframe frame; 150 unsigned long *psp = (unsigned long *)a1; 151 152 frame.pc = pc; 153 frame.sp = a1; 154 155 if (kernel_text_address(pc) && kfn(&frame, data)) 156 return; 157 158 if (pc == (unsigned long)&common_exception_return) { 159 regs = (struct pt_regs *)a1; 160 if (user_mode(regs)) { 161 if (ufn == NULL) 162 return; 163 xtensa_backtrace_user(regs, depth, ufn, data); 164 return; 165 } 166 a0 = regs->areg[0]; 167 a1 = regs->areg[1]; 168 continue; 169 } 170 171 sp_start = a1; 172 173 pc = MAKE_PC_FROM_RA(a0, pc); 174 a0 = *(psp - 4); 175 a1 = *(psp - 3); 176 } 177} 178EXPORT_SYMBOL(xtensa_backtrace_kernel); 179 180#endif 181 182void walk_stackframe(unsigned long *sp, 183 int (*fn)(struct stackframe *frame, void *data), 184 void *data) 185{ 186 unsigned long a0, a1; 187 unsigned long sp_end; 188 189 a1 = (unsigned long)sp; 190 sp_end = ALIGN(a1, THREAD_SIZE); 191 192 spill_registers(); 193 194 while (a1 < sp_end) { 195 struct stackframe frame; 196 197 sp = (unsigned long *)a1; 198 199 a0 = *(sp - 4); 200 a1 = *(sp - 3); 201 202 if (a1 <= (unsigned long)sp) 203 break; 204 205 frame.pc = MAKE_PC_FROM_RA(a0, a1); 206 frame.sp = a1; 207 208 if (fn(&frame, data)) 209 return; 210 } 211} 212 213#ifdef CONFIG_STACKTRACE 214 215struct stack_trace_data { 216 struct stack_trace *trace; 217 unsigned skip; 218}; 219 220static int stack_trace_cb(struct stackframe *frame, void *data) 221{ 222 struct stack_trace_data *trace_data = data; 223 struct stack_trace *trace = trace_data->trace; 224 225 if (trace_data->skip) { 226 --trace_data->skip; 227 return 0; 228 } 229 if (!kernel_text_address(frame->pc)) 230 return 0; 231 232 trace->entries[trace->nr_entries++] = frame->pc; 233 return trace->nr_entries >= trace->max_entries; 234} 235 236void save_stack_trace_tsk(struct task_struct *task, struct stack_trace *trace) 237{ 238 struct stack_trace_data trace_data = { 239 .trace = trace, 240 .skip = trace->skip, 241 }; 242 walk_stackframe(stack_pointer(task), stack_trace_cb, &trace_data); 243} 244EXPORT_SYMBOL_GPL(save_stack_trace_tsk); 245 246void save_stack_trace(struct stack_trace *trace) 247{ 248 save_stack_trace_tsk(current, trace); 249} 250EXPORT_SYMBOL_GPL(save_stack_trace); 251 252#endif 253 254#ifdef CONFIG_FRAME_POINTER 255 256struct return_addr_data { 257 unsigned long addr; 258 unsigned skip; 259}; 260 261static int return_address_cb(struct stackframe *frame, void *data) 262{ 263 struct return_addr_data *r = data; 264 265 if (r->skip) { 266 --r->skip; 267 return 0; 268 } 269 if (!kernel_text_address(frame->pc)) 270 return 0; 271 r->addr = frame->pc; 272 return 1; 273} 274 275unsigned long return_address(unsigned level) 276{ 277 struct return_addr_data r = { 278 .skip = level + 1, 279 }; 280 walk_stackframe(stack_pointer(NULL), return_address_cb, &r); 281 return r.addr; 282} 283EXPORT_SYMBOL(return_address); 284 285#endif 286