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