1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Stack tracing support 4 * 5 * Copyright (C) 2012 ARM Ltd. 6 */ 7 #include <linux/kernel.h> 8 #include <linux/export.h> 9 #include <linux/ftrace.h> 10 #include <linux/sched.h> 11 #include <linux/sched/debug.h> 12 #include <linux/sched/task_stack.h> 13 #include <linux/stacktrace.h> 14 15 #include <asm/irq.h> 16 #include <asm/stack_pointer.h> 17 #include <asm/stacktrace.h> 18 19 /* 20 * Start an unwind from a pt_regs. 21 * 22 * The unwind will begin at the PC within the regs. 23 * 24 * The regs must be on a stack currently owned by the calling task. 25 */ 26 static inline void unwind_init_from_regs(struct unwind_state *state, 27 struct pt_regs *regs) 28 { 29 unwind_init_common(state, current); 30 31 state->fp = regs->regs[29]; 32 state->pc = regs->pc; 33 } 34 35 /* 36 * Start an unwind from a caller. 37 * 38 * The unwind will begin at the caller of whichever function this is inlined 39 * into. 40 * 41 * The function which invokes this must be noinline. 42 */ 43 static __always_inline void unwind_init_from_caller(struct unwind_state *state) 44 { 45 unwind_init_common(state, current); 46 47 state->fp = (unsigned long)__builtin_frame_address(1); 48 state->pc = (unsigned long)__builtin_return_address(0); 49 } 50 51 /* 52 * Start an unwind from a blocked task. 53 * 54 * The unwind will begin at the blocked tasks saved PC (i.e. the caller of 55 * cpu_switch_to()). 56 * 57 * The caller should ensure the task is blocked in cpu_switch_to() for the 58 * duration of the unwind, or the unwind will be bogus. It is never valid to 59 * call this for the current task. 60 */ 61 static inline void unwind_init_from_task(struct unwind_state *state, 62 struct task_struct *task) 63 { 64 unwind_init_common(state, task); 65 66 state->fp = thread_saved_fp(task); 67 state->pc = thread_saved_pc(task); 68 } 69 70 static bool dump_backtrace_entry(void *arg, unsigned long where) 71 { 72 char *loglvl = arg; 73 printk("%s %pSb\n", loglvl, (void *)where); 74 return true; 75 } 76 77 void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk, 78 const char *loglvl) 79 { 80 pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk); 81 82 if (regs && user_mode(regs)) 83 return; 84 85 if (!tsk) 86 tsk = current; 87 88 if (!try_get_task_stack(tsk)) 89 return; 90 91 printk("%sCall trace:\n", loglvl); 92 arch_stack_walk(dump_backtrace_entry, (void *)loglvl, tsk, regs); 93 94 put_task_stack(tsk); 95 } 96 97 void show_stack(struct task_struct *tsk, unsigned long *sp, const char *loglvl) 98 { 99 dump_backtrace(NULL, tsk, loglvl); 100 barrier(); 101 } 102 103 noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry, 104 void *cookie, struct task_struct *task, 105 struct pt_regs *regs) 106 { 107 struct unwind_state state; 108 109 if (regs) { 110 if (task != current) 111 return; 112 unwind_init_from_regs(&state, regs); 113 } else if (task == current) { 114 unwind_init_from_caller(&state); 115 } else { 116 unwind_init_from_task(&state, task); 117 } 118 119 unwind(&state, consume_entry, cookie); 120 } 121