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