1457c8996SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2ecea4ab6SPaul Gortmaker #include <linux/export.h> 3fed240d9SMasami Hiramatsu #include <linux/kprobes.h> 4f16fb1ecSRussell King #include <linux/sched.h> 5b17b0153SIngo Molnar #include <linux/sched/debug.h> 6f16fb1ecSRussell King #include <linux/stacktrace.h> 7f16fb1ecSRussell King 8c6089061SRussell King #include <asm/sections.h> 92d7c11bfSCatalin Marinas #include <asm/stacktrace.h> 1007b40341SRussell King #include <asm/traps.h> 11f16fb1ecSRussell King 125854e4d8SLi Huafei #include "reboot.h" 135854e4d8SLi Huafei 142d7c11bfSCatalin Marinas #if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) 152d7c11bfSCatalin Marinas /* 162d7c11bfSCatalin Marinas * Unwind the current stack frame and store the new register values in the 172d7c11bfSCatalin Marinas * structure passed as argument. Unwinding is equivalent to a function return, 182d7c11bfSCatalin Marinas * hence the new PC value rather than LR should be used for backtrace. 192d7c11bfSCatalin Marinas * 202d7c11bfSCatalin Marinas * With framepointer enabled, a simple function prologue looks like this: 212d7c11bfSCatalin Marinas * mov ip, sp 222d7c11bfSCatalin Marinas * stmdb sp!, {fp, ip, lr, pc} 232d7c11bfSCatalin Marinas * sub fp, ip, #4 242d7c11bfSCatalin Marinas * 252d7c11bfSCatalin Marinas * A simple function epilogue looks like this: 262d7c11bfSCatalin Marinas * ldm sp, {fp, sp, pc} 272d7c11bfSCatalin Marinas * 28b4d5ec9bSNathan Huckleberry * When compiled with clang, pc and sp are not pushed. A simple function 29b4d5ec9bSNathan Huckleberry * prologue looks like this when built with clang: 30b4d5ec9bSNathan Huckleberry * 31b4d5ec9bSNathan Huckleberry * stmdb {..., fp, lr} 32b4d5ec9bSNathan Huckleberry * add fp, sp, #x 33b4d5ec9bSNathan Huckleberry * sub sp, sp, #y 34b4d5ec9bSNathan Huckleberry * 35b4d5ec9bSNathan Huckleberry * A simple function epilogue looks like this when built with clang: 36b4d5ec9bSNathan Huckleberry * 37b4d5ec9bSNathan Huckleberry * sub sp, fp, #x 38b4d5ec9bSNathan Huckleberry * ldm {..., fp, pc} 39b4d5ec9bSNathan Huckleberry * 40b4d5ec9bSNathan Huckleberry * 412d7c11bfSCatalin Marinas * Note that with framepointer enabled, even the leaf functions have the same 422d7c11bfSCatalin Marinas * prologue and epilogue, therefore we can ignore the LR value in this case. 432d7c11bfSCatalin Marinas */ 445854e4d8SLi Huafei 455854e4d8SLi Huafei extern unsigned long call_with_stack_end; 465854e4d8SLi Huafei 475854e4d8SLi Huafei static int frame_pointer_check(struct stackframe *frame) 482d7c11bfSCatalin Marinas { 492d7c11bfSCatalin Marinas unsigned long high, low; 502d7c11bfSCatalin Marinas unsigned long fp = frame->fp; 515854e4d8SLi Huafei unsigned long pc = frame->pc; 525854e4d8SLi Huafei 535854e4d8SLi Huafei /* 545854e4d8SLi Huafei * call_with_stack() is the only place we allow SP to jump from one 555854e4d8SLi Huafei * stack to another, with FP and SP pointing to different stacks, 565854e4d8SLi Huafei * skipping the FP boundary check at this point. 575854e4d8SLi Huafei */ 585854e4d8SLi Huafei if (pc >= (unsigned long)&call_with_stack && 595854e4d8SLi Huafei pc < (unsigned long)&call_with_stack_end) 605854e4d8SLi Huafei return 0; 612d7c11bfSCatalin Marinas 622d7c11bfSCatalin Marinas /* only go to a higher address on the stack */ 632d7c11bfSCatalin Marinas low = frame->sp; 64d33aadbfSWill Deacon high = ALIGN(low, THREAD_SIZE); 652d7c11bfSCatalin Marinas 66b4d5ec9bSNathan Huckleberry /* check current frame pointer is within bounds */ 675854e4d8SLi Huafei #ifdef CONFIG_CC_IS_CLANG 68b4d5ec9bSNathan Huckleberry if (fp < low + 4 || fp > high - 4) 69b4d5ec9bSNathan Huckleberry return -EINVAL; 705854e4d8SLi Huafei #else 715854e4d8SLi Huafei if (fp < low + 12 || fp > high - 4) 725854e4d8SLi Huafei return -EINVAL; 735854e4d8SLi Huafei #endif 74b4d5ec9bSNathan Huckleberry 755854e4d8SLi Huafei return 0; 765854e4d8SLi Huafei } 775854e4d8SLi Huafei 785854e4d8SLi Huafei int notrace unwind_frame(struct stackframe *frame) 795854e4d8SLi Huafei { 805854e4d8SLi Huafei unsigned long fp = frame->fp; 815854e4d8SLi Huafei 825854e4d8SLi Huafei if (frame_pointer_check(frame)) 835854e4d8SLi Huafei return -EINVAL; 845854e4d8SLi Huafei 85752ec621SLi Huafei /* 86752ec621SLi Huafei * When we unwind through an exception stack, include the saved PC 87752ec621SLi Huafei * value into the stack trace. 88752ec621SLi Huafei */ 89752ec621SLi Huafei if (frame->ex_frame) { 90752ec621SLi Huafei struct pt_regs *regs = (struct pt_regs *)frame->sp; 91752ec621SLi Huafei 92752ec621SLi Huafei /* 93752ec621SLi Huafei * We check that 'regs + sizeof(struct pt_regs)' (that is, 94752ec621SLi Huafei * ®s[1]) does not exceed the bottom of the stack to avoid 95752ec621SLi Huafei * accessing data outside the task's stack. This may happen 96752ec621SLi Huafei * when frame->ex_frame is a false positive. 97752ec621SLi Huafei */ 98752ec621SLi Huafei if ((unsigned long)®s[1] > ALIGN(frame->sp, THREAD_SIZE)) 99752ec621SLi Huafei return -EINVAL; 100752ec621SLi Huafei 101752ec621SLi Huafei frame->pc = regs->ARM_pc; 102752ec621SLi Huafei frame->ex_frame = false; 103752ec621SLi Huafei return 0; 104752ec621SLi Huafei } 105752ec621SLi Huafei 1065854e4d8SLi Huafei /* restore the registers from the stack frame */ 1075854e4d8SLi Huafei #ifdef CONFIG_CC_IS_CLANG 108b4d5ec9bSNathan Huckleberry frame->sp = frame->fp; 1099be4c88bSlinyujun frame->fp = READ_ONCE_NOCHECK(*(unsigned long *)(fp)); 1109be4c88bSlinyujun frame->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp + 4)); 111b4d5ec9bSNathan Huckleberry #else 1129be4c88bSlinyujun frame->fp = READ_ONCE_NOCHECK(*(unsigned long *)(fp - 12)); 1139be4c88bSlinyujun frame->sp = READ_ONCE_NOCHECK(*(unsigned long *)(fp - 8)); 1149be4c88bSlinyujun frame->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp - 4)); 115b4d5ec9bSNathan Huckleberry #endif 116fed240d9SMasami Hiramatsu #ifdef CONFIG_KRETPROBES 117fed240d9SMasami Hiramatsu if (is_kretprobe_trampoline(frame->pc)) 118fed240d9SMasami Hiramatsu frame->pc = kretprobe_find_ret_addr(frame->tsk, 119fed240d9SMasami Hiramatsu (void *)frame->fp, &frame->kr_cur); 120fed240d9SMasami Hiramatsu #endif 1212d7c11bfSCatalin Marinas 122752ec621SLi Huafei if (in_entry_text(frame->pc)) 123752ec621SLi Huafei frame->ex_frame = true; 124752ec621SLi Huafei 1252d7c11bfSCatalin Marinas return 0; 1262d7c11bfSCatalin Marinas } 1272d7c11bfSCatalin Marinas #endif 1282d7c11bfSCatalin Marinas 1294bf1fa5aSUwe Kleine-König void notrace walk_stackframe(struct stackframe *frame, 130*70ccc7c0SLi Huafei bool (*fn)(void *, unsigned long), void *data) 131f16fb1ecSRussell King { 1322d7c11bfSCatalin Marinas while (1) { 1332d7c11bfSCatalin Marinas int ret; 134f16fb1ecSRussell King 135*70ccc7c0SLi Huafei if (!fn(data, frame->pc)) 136f16fb1ecSRussell King break; 1372d7c11bfSCatalin Marinas ret = unwind_frame(frame); 1382d7c11bfSCatalin Marinas if (ret < 0) 1392d7c11bfSCatalin Marinas break; 1402d7c11bfSCatalin Marinas } 141f16fb1ecSRussell King } 1427b104bcbSAl Viro EXPORT_SYMBOL(walk_stackframe); 143f16fb1ecSRussell King 144f16fb1ecSRussell King #ifdef CONFIG_STACKTRACE 145f16fb1ecSRussell King struct stack_trace_data { 146f16fb1ecSRussell King struct stack_trace *trace; 147f76e9154SNicolas Pitre unsigned int no_sched_functions; 148f16fb1ecSRussell King unsigned int skip; 149f16fb1ecSRussell King }; 150f16fb1ecSRussell King 151*70ccc7c0SLi Huafei static bool save_trace(void *d, unsigned long addr) 152f16fb1ecSRussell King { 153f16fb1ecSRussell King struct stack_trace_data *data = d; 154f16fb1ecSRussell King struct stack_trace *trace = data->trace; 155f16fb1ecSRussell King 156f76e9154SNicolas Pitre if (data->no_sched_functions && in_sched_functions(addr)) 157*70ccc7c0SLi Huafei return true; 158f16fb1ecSRussell King if (data->skip) { 159f16fb1ecSRussell King data->skip--; 160*70ccc7c0SLi Huafei return true; 161f16fb1ecSRussell King } 162f16fb1ecSRussell King 163f76e9154SNicolas Pitre trace->entries[trace->nr_entries++] = addr; 164*70ccc7c0SLi Huafei return trace->nr_entries < trace->max_entries; 165f16fb1ecSRussell King } 166f16fb1ecSRussell King 1673683f44cSRussell King /* This must be noinline to so that our skip calculation works correctly */ 1683683f44cSRussell King static noinline void __save_stack_trace(struct task_struct *tsk, 1693683f44cSRussell King struct stack_trace *trace, unsigned int nosched) 170f16fb1ecSRussell King { 171f16fb1ecSRussell King struct stack_trace_data data; 1722d7c11bfSCatalin Marinas struct stackframe frame; 173f16fb1ecSRussell King 174f16fb1ecSRussell King data.trace = trace; 175f16fb1ecSRussell King data.skip = trace->skip; 1763683f44cSRussell King data.no_sched_functions = nosched; 177f76e9154SNicolas Pitre 178f76e9154SNicolas Pitre if (tsk != current) { 179f76e9154SNicolas Pitre #ifdef CONFIG_SMP 180f76e9154SNicolas Pitre /* 181d5996b2fSRussell King * What guarantees do we have here that 'tsk' is not 182d5996b2fSRussell King * running on another CPU? For now, ignore it as we 183d5996b2fSRussell King * can't guarantee we won't explode. 184f76e9154SNicolas Pitre */ 185d5996b2fSRussell King return; 186f76e9154SNicolas Pitre #else 1872d7c11bfSCatalin Marinas frame.fp = thread_saved_fp(tsk); 1882d7c11bfSCatalin Marinas frame.sp = thread_saved_sp(tsk); 1892d7c11bfSCatalin Marinas frame.lr = 0; /* recovered from the stack */ 1902d7c11bfSCatalin Marinas frame.pc = thread_saved_pc(tsk); 191f76e9154SNicolas Pitre #endif 192f76e9154SNicolas Pitre } else { 1933683f44cSRussell King /* We don't want this function nor the caller */ 1943683f44cSRussell King data.skip += 2; 1952d7c11bfSCatalin Marinas frame.fp = (unsigned long)__builtin_frame_address(0); 19674dbeee0SBehan Webster frame.sp = current_stack_pointer; 1972d7c11bfSCatalin Marinas frame.lr = (unsigned long)__builtin_return_address(0); 198c46c2c9bSRussell King (Oracle) here: 199c46c2c9bSRussell King (Oracle) frame.pc = (unsigned long)&&here; 200f76e9154SNicolas Pitre } 201fed240d9SMasami Hiramatsu #ifdef CONFIG_KRETPROBES 202fed240d9SMasami Hiramatsu frame.kr_cur = NULL; 203fed240d9SMasami Hiramatsu frame.tsk = tsk; 204fed240d9SMasami Hiramatsu #endif 205752ec621SLi Huafei #ifdef CONFIG_UNWINDER_FRAME_POINTER 206752ec621SLi Huafei frame.ex_frame = false; 207752ec621SLi Huafei #endif 208f16fb1ecSRussell King 2092d7c11bfSCatalin Marinas walk_stackframe(&frame, save_trace, &data); 210f76e9154SNicolas Pitre } 211f76e9154SNicolas Pitre 2129c986661SLin Yongting void save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace) 2139c986661SLin Yongting { 2149c986661SLin Yongting struct stack_trace_data data; 2159c986661SLin Yongting struct stackframe frame; 2169c986661SLin Yongting 2179c986661SLin Yongting data.trace = trace; 2189c986661SLin Yongting data.skip = trace->skip; 2199c986661SLin Yongting data.no_sched_functions = 0; 2209c986661SLin Yongting 2219c986661SLin Yongting frame.fp = regs->ARM_fp; 2229c986661SLin Yongting frame.sp = regs->ARM_sp; 2239c986661SLin Yongting frame.lr = regs->ARM_lr; 2249c986661SLin Yongting frame.pc = regs->ARM_pc; 225fed240d9SMasami Hiramatsu #ifdef CONFIG_KRETPROBES 226fed240d9SMasami Hiramatsu frame.kr_cur = NULL; 227fed240d9SMasami Hiramatsu frame.tsk = current; 228fed240d9SMasami Hiramatsu #endif 229752ec621SLi Huafei #ifdef CONFIG_UNWINDER_FRAME_POINTER 230752ec621SLi Huafei frame.ex_frame = in_entry_text(frame.pc); 231752ec621SLi Huafei #endif 2329c986661SLin Yongting 2339c986661SLin Yongting walk_stackframe(&frame, save_trace, &data); 2349c986661SLin Yongting } 2359c986661SLin Yongting 2363683f44cSRussell King void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) 2373683f44cSRussell King { 2383683f44cSRussell King __save_stack_trace(tsk, trace, 1); 2393683f44cSRussell King } 2409a3dc318SDustin Brown EXPORT_SYMBOL(save_stack_trace_tsk); 2413683f44cSRussell King 242f76e9154SNicolas Pitre void save_stack_trace(struct stack_trace *trace) 243f76e9154SNicolas Pitre { 2443683f44cSRussell King __save_stack_trace(current, trace, 0); 245f16fb1ecSRussell King } 2467b4c9505SIngo Molnar EXPORT_SYMBOL_GPL(save_stack_trace); 247f16fb1ecSRussell King #endif 248