13e4196a5SMax Filippov /*
25fdf377dSMax Filippov * Kernel and userspace stack tracing.
33e4196a5SMax Filippov *
43e4196a5SMax Filippov * This file is subject to the terms and conditions of the GNU General Public
53e4196a5SMax Filippov * License. See the file "COPYING" in the main directory of this archive
63e4196a5SMax Filippov * for more details.
73e4196a5SMax Filippov *
83e4196a5SMax Filippov * Copyright (C) 2001 - 2013 Tensilica Inc.
95fdf377dSMax Filippov * Copyright (C) 2015 Cadence Design Systems Inc.
103e4196a5SMax Filippov */
113e4196a5SMax Filippov #include <linux/export.h>
123e4196a5SMax Filippov #include <linux/sched.h>
133e4196a5SMax Filippov #include <linux/stacktrace.h>
143e4196a5SMax Filippov
151b6ceeb9SRandy Dunlap #include <asm/ftrace.h>
16*ef31b464SMax Filippov #include <asm/sections.h>
173e4196a5SMax Filippov #include <asm/stacktrace.h>
183e4196a5SMax Filippov #include <asm/traps.h>
197c0f6ba6SLinus Torvalds #include <linux/uaccess.h>
205fdf377dSMax Filippov
21a848bf1dSViresh Kumar #if IS_ENABLED(CONFIG_PERF_EVENTS)
225fdf377dSMax Filippov
235fdf377dSMax Filippov /* Address of common_exception_return, used to check the
245fdf377dSMax Filippov * transition from kernel to user space.
255fdf377dSMax Filippov */
265fdf377dSMax Filippov extern int common_exception_return;
275fdf377dSMax Filippov
xtensa_backtrace_user(struct pt_regs * regs,unsigned int depth,int (* ufn)(struct stackframe * frame,void * data),void * data)285fdf377dSMax Filippov void xtensa_backtrace_user(struct pt_regs *regs, unsigned int depth,
295fdf377dSMax Filippov int (*ufn)(struct stackframe *frame, void *data),
305fdf377dSMax Filippov void *data)
315fdf377dSMax Filippov {
325fdf377dSMax Filippov unsigned long windowstart = regs->windowstart;
335fdf377dSMax Filippov unsigned long windowbase = regs->windowbase;
345fdf377dSMax Filippov unsigned long a0 = regs->areg[0];
355fdf377dSMax Filippov unsigned long a1 = regs->areg[1];
365fdf377dSMax Filippov unsigned long pc = regs->pc;
375fdf377dSMax Filippov struct stackframe frame;
385fdf377dSMax Filippov int index;
395fdf377dSMax Filippov
405fdf377dSMax Filippov if (!depth--)
415fdf377dSMax Filippov return;
425fdf377dSMax Filippov
435fdf377dSMax Filippov frame.pc = pc;
445fdf377dSMax Filippov frame.sp = a1;
455fdf377dSMax Filippov
465fdf377dSMax Filippov if (pc == 0 || pc >= TASK_SIZE || ufn(&frame, data))
475fdf377dSMax Filippov return;
485fdf377dSMax Filippov
4909f8a6dbSMax Filippov if (IS_ENABLED(CONFIG_USER_ABI_CALL0_ONLY) ||
5009f8a6dbSMax Filippov (IS_ENABLED(CONFIG_USER_ABI_CALL0_PROBE) &&
5109f8a6dbSMax Filippov !(regs->ps & PS_WOE_MASK)))
5209f8a6dbSMax Filippov return;
5309f8a6dbSMax Filippov
545fdf377dSMax Filippov /* Two steps:
555fdf377dSMax Filippov *
565fdf377dSMax Filippov * 1. Look through the register window for the
575fdf377dSMax Filippov * previous PCs in the call trace.
585fdf377dSMax Filippov *
595fdf377dSMax Filippov * 2. Look on the stack.
605fdf377dSMax Filippov */
615fdf377dSMax Filippov
625fdf377dSMax Filippov /* Step 1. */
635fdf377dSMax Filippov /* Rotate WINDOWSTART to move the bit corresponding to
645fdf377dSMax Filippov * the current window to the bit #0.
655fdf377dSMax Filippov */
665fdf377dSMax Filippov windowstart = (windowstart << WSBITS | windowstart) >> windowbase;
675fdf377dSMax Filippov
685fdf377dSMax Filippov /* Look for bits that are set, they correspond to
695fdf377dSMax Filippov * valid windows.
705fdf377dSMax Filippov */
715fdf377dSMax Filippov for (index = WSBITS - 1; (index > 0) && depth; depth--, index--)
725fdf377dSMax Filippov if (windowstart & (1 << index)) {
735fdf377dSMax Filippov /* Get the PC from a0 and a1. */
745fdf377dSMax Filippov pc = MAKE_PC_FROM_RA(a0, pc);
755fdf377dSMax Filippov /* Read a0 and a1 from the
765fdf377dSMax Filippov * corresponding position in AREGs.
775fdf377dSMax Filippov */
785fdf377dSMax Filippov a0 = regs->areg[index * 4];
795fdf377dSMax Filippov a1 = regs->areg[index * 4 + 1];
805fdf377dSMax Filippov
815fdf377dSMax Filippov frame.pc = pc;
825fdf377dSMax Filippov frame.sp = a1;
835fdf377dSMax Filippov
845fdf377dSMax Filippov if (pc == 0 || pc >= TASK_SIZE || ufn(&frame, data))
855fdf377dSMax Filippov return;
865fdf377dSMax Filippov }
875fdf377dSMax Filippov
885fdf377dSMax Filippov /* Step 2. */
895fdf377dSMax Filippov /* We are done with the register window, we need to
905fdf377dSMax Filippov * look through the stack.
915fdf377dSMax Filippov */
925fdf377dSMax Filippov if (!depth)
935fdf377dSMax Filippov return;
945fdf377dSMax Filippov
955fdf377dSMax Filippov /* Start from the a1 register. */
965fdf377dSMax Filippov /* a1 = regs->areg[1]; */
975fdf377dSMax Filippov while (a0 != 0 && depth--) {
98062b1c19SMax Filippov pc = MAKE_PC_FROM_RA(a0, pc);
995fdf377dSMax Filippov
1005fdf377dSMax Filippov /* Check if the region is OK to access. */
10196d4f267SLinus Torvalds if (!access_ok(&SPILL_SLOT(a1, 0), 8))
1025fdf377dSMax Filippov return;
1035fdf377dSMax Filippov /* Copy a1, a0 from user space stack frame. */
104062b1c19SMax Filippov if (__get_user(a0, &SPILL_SLOT(a1, 0)) ||
105062b1c19SMax Filippov __get_user(a1, &SPILL_SLOT(a1, 1)))
1065fdf377dSMax Filippov return;
1075fdf377dSMax Filippov
1085fdf377dSMax Filippov frame.pc = pc;
1095fdf377dSMax Filippov frame.sp = a1;
1105fdf377dSMax Filippov
1115fdf377dSMax Filippov if (pc == 0 || pc >= TASK_SIZE || ufn(&frame, data))
1125fdf377dSMax Filippov return;
1135fdf377dSMax Filippov }
1145fdf377dSMax Filippov }
1155fdf377dSMax Filippov EXPORT_SYMBOL(xtensa_backtrace_user);
1165fdf377dSMax Filippov
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)1175fdf377dSMax Filippov void xtensa_backtrace_kernel(struct pt_regs *regs, unsigned int depth,
1185fdf377dSMax Filippov int (*kfn)(struct stackframe *frame, void *data),
1195fdf377dSMax Filippov int (*ufn)(struct stackframe *frame, void *data),
1205fdf377dSMax Filippov void *data)
1215fdf377dSMax Filippov {
1225fdf377dSMax Filippov unsigned long pc = regs->depc > VALID_DOUBLE_EXCEPTION_ADDRESS ?
1235fdf377dSMax Filippov regs->depc : regs->pc;
1245fdf377dSMax Filippov unsigned long sp_start, sp_end;
1255fdf377dSMax Filippov unsigned long a0 = regs->areg[0];
1265fdf377dSMax Filippov unsigned long a1 = regs->areg[1];
1275fdf377dSMax Filippov
1285fdf377dSMax Filippov sp_start = a1 & ~(THREAD_SIZE - 1);
1295fdf377dSMax Filippov sp_end = sp_start + THREAD_SIZE;
1305fdf377dSMax Filippov
1315fdf377dSMax Filippov /* Spill the register window to the stack first. */
1325fdf377dSMax Filippov spill_registers();
1335fdf377dSMax Filippov
1345fdf377dSMax Filippov /* Read the stack frames one by one and create the PC
1355fdf377dSMax Filippov * from the a0 and a1 registers saved there.
1365fdf377dSMax Filippov */
1375fdf377dSMax Filippov while (a1 > sp_start && a1 < sp_end && depth--) {
1385fdf377dSMax Filippov struct stackframe frame;
1395fdf377dSMax Filippov
1405fdf377dSMax Filippov frame.pc = pc;
1415fdf377dSMax Filippov frame.sp = a1;
1425fdf377dSMax Filippov
1435fdf377dSMax Filippov if (kernel_text_address(pc) && kfn(&frame, data))
1445fdf377dSMax Filippov return;
1455fdf377dSMax Filippov
1465fdf377dSMax Filippov if (pc == (unsigned long)&common_exception_return) {
1475fdf377dSMax Filippov regs = (struct pt_regs *)a1;
1485fdf377dSMax Filippov if (user_mode(regs)) {
1495fdf377dSMax Filippov if (ufn == NULL)
1505fdf377dSMax Filippov return;
1515fdf377dSMax Filippov xtensa_backtrace_user(regs, depth, ufn, data);
1525fdf377dSMax Filippov return;
1535fdf377dSMax Filippov }
1545fdf377dSMax Filippov a0 = regs->areg[0];
1555fdf377dSMax Filippov a1 = regs->areg[1];
1565fdf377dSMax Filippov continue;
1575fdf377dSMax Filippov }
1585fdf377dSMax Filippov
1595fdf377dSMax Filippov sp_start = a1;
1605fdf377dSMax Filippov
1615fdf377dSMax Filippov pc = MAKE_PC_FROM_RA(a0, pc);
162062b1c19SMax Filippov a0 = SPILL_SLOT(a1, 0);
163062b1c19SMax Filippov a1 = SPILL_SLOT(a1, 1);
1645fdf377dSMax Filippov }
1655fdf377dSMax Filippov }
1665fdf377dSMax Filippov EXPORT_SYMBOL(xtensa_backtrace_kernel);
1675fdf377dSMax Filippov
1685fdf377dSMax Filippov #endif
1693e4196a5SMax Filippov
walk_stackframe(unsigned long * sp,int (* fn)(struct stackframe * frame,void * data),void * data)1703e4196a5SMax Filippov void walk_stackframe(unsigned long *sp,
1713e4196a5SMax Filippov int (*fn)(struct stackframe *frame, void *data),
1723e4196a5SMax Filippov void *data)
1733e4196a5SMax Filippov {
1743e4196a5SMax Filippov unsigned long a0, a1;
1753e4196a5SMax Filippov unsigned long sp_end;
1763e4196a5SMax Filippov
1773e4196a5SMax Filippov a1 = (unsigned long)sp;
1783e4196a5SMax Filippov sp_end = ALIGN(a1, THREAD_SIZE);
1793e4196a5SMax Filippov
1803e4196a5SMax Filippov spill_registers();
1813e4196a5SMax Filippov
1823e4196a5SMax Filippov while (a1 < sp_end) {
1833e4196a5SMax Filippov struct stackframe frame;
1843e4196a5SMax Filippov
1853e4196a5SMax Filippov sp = (unsigned long *)a1;
1863e4196a5SMax Filippov
187062b1c19SMax Filippov a0 = SPILL_SLOT(a1, 0);
188062b1c19SMax Filippov a1 = SPILL_SLOT(a1, 1);
1893e4196a5SMax Filippov
1903e4196a5SMax Filippov if (a1 <= (unsigned long)sp)
1913e4196a5SMax Filippov break;
1923e4196a5SMax Filippov
193*ef31b464SMax Filippov frame.pc = MAKE_PC_FROM_RA(a0, _text);
1943e4196a5SMax Filippov frame.sp = a1;
1953e4196a5SMax Filippov
1963e4196a5SMax Filippov if (fn(&frame, data))
1973e4196a5SMax Filippov return;
1983e4196a5SMax Filippov }
1993e4196a5SMax Filippov }
2003e4196a5SMax Filippov
2013e4196a5SMax Filippov #ifdef CONFIG_STACKTRACE
2023e4196a5SMax Filippov
2033e4196a5SMax Filippov struct stack_trace_data {
2043e4196a5SMax Filippov struct stack_trace *trace;
2053e4196a5SMax Filippov unsigned skip;
2063e4196a5SMax Filippov };
2073e4196a5SMax Filippov
stack_trace_cb(struct stackframe * frame,void * data)2083e4196a5SMax Filippov static int stack_trace_cb(struct stackframe *frame, void *data)
2093e4196a5SMax Filippov {
2103e4196a5SMax Filippov struct stack_trace_data *trace_data = data;
2113e4196a5SMax Filippov struct stack_trace *trace = trace_data->trace;
2123e4196a5SMax Filippov
2133e4196a5SMax Filippov if (trace_data->skip) {
2143e4196a5SMax Filippov --trace_data->skip;
2153e4196a5SMax Filippov return 0;
2163e4196a5SMax Filippov }
2173e4196a5SMax Filippov if (!kernel_text_address(frame->pc))
2183e4196a5SMax Filippov return 0;
2193e4196a5SMax Filippov
2203e4196a5SMax Filippov trace->entries[trace->nr_entries++] = frame->pc;
2213e4196a5SMax Filippov return trace->nr_entries >= trace->max_entries;
2223e4196a5SMax Filippov }
2233e4196a5SMax Filippov
save_stack_trace_tsk(struct task_struct * task,struct stack_trace * trace)2243e4196a5SMax Filippov void save_stack_trace_tsk(struct task_struct *task, struct stack_trace *trace)
2253e4196a5SMax Filippov {
2263e4196a5SMax Filippov struct stack_trace_data trace_data = {
2273e4196a5SMax Filippov .trace = trace,
2283e4196a5SMax Filippov .skip = trace->skip,
2293e4196a5SMax Filippov };
2303e4196a5SMax Filippov walk_stackframe(stack_pointer(task), stack_trace_cb, &trace_data);
2313e4196a5SMax Filippov }
2323e4196a5SMax Filippov EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
2333e4196a5SMax Filippov
save_stack_trace(struct stack_trace * trace)2343e4196a5SMax Filippov void save_stack_trace(struct stack_trace *trace)
2353e4196a5SMax Filippov {
2363e4196a5SMax Filippov save_stack_trace_tsk(current, trace);
2373e4196a5SMax Filippov }
2383e4196a5SMax Filippov EXPORT_SYMBOL_GPL(save_stack_trace);
2393e4196a5SMax Filippov
2403e4196a5SMax Filippov #endif
2413ae908c9SMax Filippov
2423ae908c9SMax Filippov struct return_addr_data {
2433ae908c9SMax Filippov unsigned long addr;
2443ae908c9SMax Filippov unsigned skip;
2453ae908c9SMax Filippov };
2463ae908c9SMax Filippov
return_address_cb(struct stackframe * frame,void * data)2473ae908c9SMax Filippov static int return_address_cb(struct stackframe *frame, void *data)
2483ae908c9SMax Filippov {
2493ae908c9SMax Filippov struct return_addr_data *r = data;
2503ae908c9SMax Filippov
2513ae908c9SMax Filippov if (r->skip) {
2523ae908c9SMax Filippov --r->skip;
2533ae908c9SMax Filippov return 0;
2543ae908c9SMax Filippov }
2553ae908c9SMax Filippov if (!kernel_text_address(frame->pc))
2563ae908c9SMax Filippov return 0;
2573ae908c9SMax Filippov r->addr = frame->pc;
2583ae908c9SMax Filippov return 1;
2593ae908c9SMax Filippov }
2603ae908c9SMax Filippov
261ada770b1SMax Filippov /*
262ada770b1SMax Filippov * level == 0 is for the return address from the caller of this function,
263ada770b1SMax Filippov * not from this function itself.
264ada770b1SMax Filippov */
return_address(unsigned level)2653ae908c9SMax Filippov unsigned long return_address(unsigned level)
2663ae908c9SMax Filippov {
2673ae908c9SMax Filippov struct return_addr_data r = {
268ada770b1SMax Filippov .skip = level,
2693ae908c9SMax Filippov };
2703ae908c9SMax Filippov walk_stackframe(stack_pointer(NULL), return_address_cb, &r);
2713ae908c9SMax Filippov return r.addr;
2723ae908c9SMax Filippov }
2733ae908c9SMax Filippov EXPORT_SYMBOL(return_address);
274