1 /* 2 * Stack trace utility for OpenRISC 3 * 4 * Copyright (C) 2017 Stafford Horne <shorne@gmail.com> 5 * 6 * This file is licensed under the terms of the GNU General Public License 7 * version 2. This program is licensed "as is" without any warranty of any 8 * kind, whether express or implied. 9 * 10 * Losely based on work from sh and powerpc. 11 */ 12 13 #include <linux/export.h> 14 #include <linux/sched.h> 15 #include <linux/sched/debug.h> 16 #include <linux/stacktrace.h> 17 18 #include <asm/processor.h> 19 #include <asm/unwinder.h> 20 21 /* 22 * Save stack-backtrace addresses into a stack_trace buffer. 23 */ 24 static void 25 save_stack_address(void *data, unsigned long addr, int reliable) 26 { 27 struct stack_trace *trace = data; 28 29 if (!reliable) 30 return; 31 32 if (trace->skip > 0) { 33 trace->skip--; 34 return; 35 } 36 37 if (trace->nr_entries < trace->max_entries) 38 trace->entries[trace->nr_entries++] = addr; 39 } 40 41 void save_stack_trace(struct stack_trace *trace) 42 { 43 unwind_stack(trace, (unsigned long *) &trace, save_stack_address); 44 } 45 EXPORT_SYMBOL_GPL(save_stack_trace); 46 47 static void 48 save_stack_address_nosched(void *data, unsigned long addr, int reliable) 49 { 50 struct stack_trace *trace = (struct stack_trace *)data; 51 52 if (!reliable) 53 return; 54 55 if (in_sched_functions(addr)) 56 return; 57 58 if (trace->skip > 0) { 59 trace->skip--; 60 return; 61 } 62 63 if (trace->nr_entries < trace->max_entries) 64 trace->entries[trace->nr_entries++] = addr; 65 } 66 67 void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) 68 { 69 unsigned long *sp = NULL; 70 71 if (tsk == current) 72 sp = (unsigned long *) &sp; 73 else 74 sp = (unsigned long *) KSTK_ESP(tsk); 75 76 unwind_stack(trace, sp, save_stack_address_nosched); 77 } 78 EXPORT_SYMBOL_GPL(save_stack_trace_tsk); 79 80 void 81 save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace) 82 { 83 unwind_stack(trace, (unsigned long *) regs->sp, 84 save_stack_address_nosched); 85 } 86 EXPORT_SYMBOL_GPL(save_stack_trace_regs); 87