2 * Kernel and userspace stack tracing.
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
8 * Copyright (C) 2001 - 2013 Tensilica Inc.
9 * Copyright (C) 2015 Cadence Design Systems Inc.
11 #include <linux/export.h>
12 #include <linux/sched.h>
13 #include <linux/stacktrace.h>
15 #include <asm/ftrace.h>
16 #include <asm/stacktrace.h>
17 #include <asm/traps.h>
18 #include <linux/uaccess.h>
20 #if IS_ENABLED(CONFIG_PERF_EVENTS)
22 /* Address of common_exception_return, used to check the
23 * transition from kernel to user space.
25 extern int common_exception_return;
27 void xtensa_backtrace_user(struct pt_regs *regs, unsigned int depth,
28 int (*ufn)(struct stackframe *frame, void *data),
31 unsigned long windowstart = regs->windowstart;
32 unsigned long windowbase = regs->windowbase;
33 unsigned long a0 = regs->areg[0];
34 unsigned long a1 = regs->areg[1];
35 unsigned long pc = regs->pc;
36 struct stackframe frame;
45 if (pc == 0 || pc >= TASK_SIZE || ufn(&frame, data))
48 if (IS_ENABLED(CONFIG_USER_ABI_CALL0_ONLY) ||
49 (IS_ENABLED(CONFIG_USER_ABI_CALL0_PROBE) &&
50 !(regs->ps & PS_WOE_MASK)))
55 * 1. Look through the register window for the
56 * previous PCs in the call trace.
58 * 2. Look on the stack.
62 /* Rotate WINDOWSTART to move the bit corresponding to
63 * the current window to the bit #0.
65 windowstart = (windowstart << WSBITS | windowstart) >> windowbase;
67 /* Look for bits that are set, they correspond to
70 for (index = WSBITS - 1; (index > 0) && depth; depth--, index--)
71 if (windowstart & (1 << index)) {
72 /* Get the PC from a0 and a1. */
73 pc = MAKE_PC_FROM_RA(a0, pc);
74 /* Read a0 and a1 from the
75 * corresponding position in AREGs.
77 a0 = regs->areg[index * 4];
78 a1 = regs->areg[index * 4 + 1];
83 if (pc == 0 || pc >= TASK_SIZE || ufn(&frame, data))
88 /* We are done with the register window, we need to
89 * look through the stack.
94 /* Start from the a1 register. */
95 /* a1 = regs->areg[1]; */
96 while (a0 != 0 && depth--) {
97 pc = MAKE_PC_FROM_RA(a0, pc);
99 /* Check if the region is OK to access. */
100 if (!access_ok(&SPILL_SLOT(a1, 0), 8))
102 /* Copy a1, a0 from user space stack frame. */
103 if (__get_user(a0, &SPILL_SLOT(a1, 0)) ||
104 __get_user(a1, &SPILL_SLOT(a1, 1)))
110 if (pc == 0 || pc >= TASK_SIZE || ufn(&frame, data))
114 EXPORT_SYMBOL(xtensa_backtrace_user);
116 void xtensa_backtrace_kernel(struct pt_regs *regs, unsigned int depth,
117 int (*kfn)(struct stackframe *frame, void *data),
118 int (*ufn)(struct stackframe *frame, void *data),
121 unsigned long pc = regs->depc > VALID_DOUBLE_EXCEPTION_ADDRESS ?
122 regs->depc : regs->pc;
123 unsigned long sp_start, sp_end;
124 unsigned long a0 = regs->areg[0];
125 unsigned long a1 = regs->areg[1];
127 sp_start = a1 & ~(THREAD_SIZE - 1);
128 sp_end = sp_start + THREAD_SIZE;
130 /* Spill the register window to the stack first. */
133 /* Read the stack frames one by one and create the PC
134 * from the a0 and a1 registers saved there.
136 while (a1 > sp_start && a1 < sp_end && depth--) {
137 struct stackframe frame;
142 if (kernel_text_address(pc) && kfn(&frame, data))
145 if (pc == (unsigned long)&common_exception_return) {
146 regs = (struct pt_regs *)a1;
147 if (user_mode(regs)) {
150 xtensa_backtrace_user(regs, depth, ufn, data);
160 pc = MAKE_PC_FROM_RA(a0, pc);
161 a0 = SPILL_SLOT(a1, 0);
162 a1 = SPILL_SLOT(a1, 1);
165 EXPORT_SYMBOL(xtensa_backtrace_kernel);
169 void walk_stackframe(unsigned long *sp,
170 int (*fn)(struct stackframe *frame, void *data),
173 unsigned long a0, a1;
174 unsigned long sp_end;
176 a1 = (unsigned long)sp;
177 sp_end = ALIGN(a1, THREAD_SIZE);
181 while (a1 < sp_end) {
182 struct stackframe frame;
184 sp = (unsigned long *)a1;
186 a0 = SPILL_SLOT(a1, 0);
187 a1 = SPILL_SLOT(a1, 1);
189 if (a1 <= (unsigned long)sp)
192 frame.pc = MAKE_PC_FROM_RA(a0, a1);
195 if (fn(&frame, data))
200 #ifdef CONFIG_STACKTRACE
202 struct stack_trace_data {
203 struct stack_trace *trace;
207 static int stack_trace_cb(struct stackframe *frame, void *data)
209 struct stack_trace_data *trace_data = data;
210 struct stack_trace *trace = trace_data->trace;
212 if (trace_data->skip) {
216 if (!kernel_text_address(frame->pc))
219 trace->entries[trace->nr_entries++] = frame->pc;
220 return trace->nr_entries >= trace->max_entries;
223 void save_stack_trace_tsk(struct task_struct *task, struct stack_trace *trace)
225 struct stack_trace_data trace_data = {
229 walk_stackframe(stack_pointer(task), stack_trace_cb, &trace_data);
231 EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
233 void save_stack_trace(struct stack_trace *trace)
235 save_stack_trace_tsk(current, trace);
237 EXPORT_SYMBOL_GPL(save_stack_trace);
241 struct return_addr_data {
246 static int return_address_cb(struct stackframe *frame, void *data)
248 struct return_addr_data *r = data;
254 if (!kernel_text_address(frame->pc))
261 * level == 0 is for the return address from the caller of this function,
262 * not from this function itself.
264 unsigned long return_address(unsigned level)
266 struct return_addr_data r = {
269 walk_stackframe(stack_pointer(NULL), return_address_cb, &r);
272 EXPORT_SYMBOL(return_address);