1c08098f2SVineet Gupta /* 2*44c8bb91SVineet Gupta * stacktrace.c : stacktracing APIs needed by rest of kernel 3*44c8bb91SVineet Gupta * (wrappers over ARC dwarf based unwinder) 4*44c8bb91SVineet Gupta * 5c08098f2SVineet Gupta * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) 6c08098f2SVineet Gupta * 7c08098f2SVineet Gupta * This program is free software; you can redistribute it and/or modify 8c08098f2SVineet Gupta * it under the terms of the GNU General Public License version 2 as 9c08098f2SVineet Gupta * published by the Free Software Foundation. 10*44c8bb91SVineet Gupta * 11*44c8bb91SVineet Gupta * vineetg: aug 2009 12*44c8bb91SVineet Gupta * -Implemented CONFIG_STACKTRACE APIs, primarily save_stack_trace_tsk( ) 13*44c8bb91SVineet Gupta * for displaying task's kernel mode call stack in /proc/<pid>/stack 14*44c8bb91SVineet Gupta * -Iterator based approach to have single copy of unwinding core and APIs 15*44c8bb91SVineet Gupta * needing unwinding, implement the logic in iterator regarding: 16*44c8bb91SVineet Gupta * = which frame onwards to start capture 17*44c8bb91SVineet Gupta * = which frame to stop capturing (wchan) 18*44c8bb91SVineet Gupta * = specifics of data structs where trace is saved(CONFIG_STACKTRACE etc) 19*44c8bb91SVineet Gupta * 20*44c8bb91SVineet Gupta * vineetg: March 2009 21*44c8bb91SVineet Gupta * -Implemented correct versions of thread_saved_pc() and get_wchan() 22*44c8bb91SVineet Gupta * 23*44c8bb91SVineet Gupta * rajeshwarr: 2008 24*44c8bb91SVineet Gupta * -Initial implementation 25c08098f2SVineet Gupta */ 26c08098f2SVineet Gupta 27c08098f2SVineet Gupta #include <linux/ptrace.h> 28c08098f2SVineet Gupta #include <linux/export.h> 29*44c8bb91SVineet Gupta #include <linux/stacktrace.h> 30*44c8bb91SVineet Gupta #include <linux/kallsyms.h> 31*44c8bb91SVineet Gupta #include <asm/arcregs.h> 32*44c8bb91SVineet Gupta #include <asm/unwind.h> 33*44c8bb91SVineet Gupta #include <asm/switch_to.h> 34*44c8bb91SVineet Gupta 35*44c8bb91SVineet Gupta /*------------------------------------------------------------------------- 36*44c8bb91SVineet Gupta * Unwinder Iterator 37*44c8bb91SVineet Gupta *------------------------------------------------------------------------- 38*44c8bb91SVineet Gupta */ 39*44c8bb91SVineet Gupta 40*44c8bb91SVineet Gupta #ifdef CONFIG_ARC_DW2_UNWIND 41*44c8bb91SVineet Gupta 42*44c8bb91SVineet Gupta static void seed_unwind_frame_info(struct task_struct *tsk, 43*44c8bb91SVineet Gupta struct pt_regs *regs, 44*44c8bb91SVineet Gupta struct unwind_frame_info *frame_info) 45*44c8bb91SVineet Gupta { 46*44c8bb91SVineet Gupta if (tsk == NULL && regs == NULL) { 47*44c8bb91SVineet Gupta unsigned long fp, sp, blink, ret; 48*44c8bb91SVineet Gupta frame_info->task = current; 49*44c8bb91SVineet Gupta 50*44c8bb91SVineet Gupta __asm__ __volatile__( 51*44c8bb91SVineet Gupta "mov %0,r27\n\t" 52*44c8bb91SVineet Gupta "mov %1,r28\n\t" 53*44c8bb91SVineet Gupta "mov %2,r31\n\t" 54*44c8bb91SVineet Gupta "mov %3,r63\n\t" 55*44c8bb91SVineet Gupta : "=r"(fp), "=r"(sp), "=r"(blink), "=r"(ret) 56*44c8bb91SVineet Gupta ); 57*44c8bb91SVineet Gupta 58*44c8bb91SVineet Gupta frame_info->regs.r27 = fp; 59*44c8bb91SVineet Gupta frame_info->regs.r28 = sp; 60*44c8bb91SVineet Gupta frame_info->regs.r31 = blink; 61*44c8bb91SVineet Gupta frame_info->regs.r63 = ret; 62*44c8bb91SVineet Gupta frame_info->call_frame = 0; 63*44c8bb91SVineet Gupta } else if (regs == NULL) { 64*44c8bb91SVineet Gupta 65*44c8bb91SVineet Gupta frame_info->task = tsk; 66*44c8bb91SVineet Gupta 67*44c8bb91SVineet Gupta frame_info->regs.r27 = KSTK_FP(tsk); 68*44c8bb91SVineet Gupta frame_info->regs.r28 = KSTK_ESP(tsk); 69*44c8bb91SVineet Gupta frame_info->regs.r31 = KSTK_BLINK(tsk); 70*44c8bb91SVineet Gupta frame_info->regs.r63 = (unsigned int)__switch_to; 71*44c8bb91SVineet Gupta 72*44c8bb91SVineet Gupta /* In the prologue of __switch_to, first FP is saved on stack 73*44c8bb91SVineet Gupta * and then SP is copied to FP. Dwarf assumes cfa as FP based 74*44c8bb91SVineet Gupta * but we didn't save FP. The value retrieved above is FP's 75*44c8bb91SVineet Gupta * state in previous frame. 76*44c8bb91SVineet Gupta * As a work around for this, we unwind from __switch_to start 77*44c8bb91SVineet Gupta * and adjust SP accordingly. The other limitation is that 78*44c8bb91SVineet Gupta * __switch_to macro is dwarf rules are not generated for inline 79*44c8bb91SVineet Gupta * assembly code 80*44c8bb91SVineet Gupta */ 81*44c8bb91SVineet Gupta frame_info->regs.r27 = 0; 82*44c8bb91SVineet Gupta frame_info->regs.r28 += 64; 83*44c8bb91SVineet Gupta frame_info->call_frame = 0; 84*44c8bb91SVineet Gupta 85*44c8bb91SVineet Gupta } else { 86*44c8bb91SVineet Gupta frame_info->task = tsk; 87*44c8bb91SVineet Gupta 88*44c8bb91SVineet Gupta frame_info->regs.r27 = regs->fp; 89*44c8bb91SVineet Gupta frame_info->regs.r28 = regs->sp; 90*44c8bb91SVineet Gupta frame_info->regs.r31 = regs->blink; 91*44c8bb91SVineet Gupta frame_info->regs.r63 = regs->ret; 92*44c8bb91SVineet Gupta frame_info->call_frame = 0; 93*44c8bb91SVineet Gupta } 94*44c8bb91SVineet Gupta } 95*44c8bb91SVineet Gupta 96*44c8bb91SVineet Gupta #endif 97*44c8bb91SVineet Gupta 98*44c8bb91SVineet Gupta static noinline unsigned int 99*44c8bb91SVineet Gupta arc_unwind_core(struct task_struct *tsk, struct pt_regs *regs, 100*44c8bb91SVineet Gupta int (*consumer_fn) (unsigned int, void *), void *arg) 101*44c8bb91SVineet Gupta { 102*44c8bb91SVineet Gupta #ifdef CONFIG_ARC_DW2_UNWIND 103*44c8bb91SVineet Gupta int ret = 0; 104*44c8bb91SVineet Gupta unsigned int address; 105*44c8bb91SVineet Gupta struct unwind_frame_info frame_info; 106*44c8bb91SVineet Gupta 107*44c8bb91SVineet Gupta seed_unwind_frame_info(tsk, regs, &frame_info); 108*44c8bb91SVineet Gupta 109*44c8bb91SVineet Gupta while (1) { 110*44c8bb91SVineet Gupta address = UNW_PC(&frame_info); 111*44c8bb91SVineet Gupta 112*44c8bb91SVineet Gupta if (address && __kernel_text_address(address)) { 113*44c8bb91SVineet Gupta if (consumer_fn(address, arg) == -1) 114*44c8bb91SVineet Gupta break; 115*44c8bb91SVineet Gupta } 116*44c8bb91SVineet Gupta 117*44c8bb91SVineet Gupta ret = arc_unwind(&frame_info); 118*44c8bb91SVineet Gupta 119*44c8bb91SVineet Gupta if (ret == 0) { 120*44c8bb91SVineet Gupta frame_info.regs.r63 = frame_info.regs.r31; 121*44c8bb91SVineet Gupta continue; 122*44c8bb91SVineet Gupta } else { 123*44c8bb91SVineet Gupta break; 124*44c8bb91SVineet Gupta } 125*44c8bb91SVineet Gupta } 126*44c8bb91SVineet Gupta 127*44c8bb91SVineet Gupta return address; /* return the last address it saw */ 128*44c8bb91SVineet Gupta #else 129*44c8bb91SVineet Gupta /* On ARC, only Dward based unwinder works. fp based backtracing is 130*44c8bb91SVineet Gupta * not possible (-fno-omit-frame-pointer) because of the way function 131*44c8bb91SVineet Gupta * prelogue is setup (callee regs saved and then fp set and not other 132*44c8bb91SVineet Gupta * way around 133*44c8bb91SVineet Gupta */ 134*44c8bb91SVineet Gupta pr_warn("CONFIG_ARC_DW2_UNWIND needs to be enabled\n"); 135*44c8bb91SVineet Gupta return 0; 136*44c8bb91SVineet Gupta 137*44c8bb91SVineet Gupta #endif 138*44c8bb91SVineet Gupta } 139*44c8bb91SVineet Gupta 140*44c8bb91SVineet Gupta /*------------------------------------------------------------------------- 141*44c8bb91SVineet Gupta * callbacks called by unwinder iterator to implement kernel APIs 142*44c8bb91SVineet Gupta * 143*44c8bb91SVineet Gupta * The callback can return -1 to force the iterator to stop, which by default 144*44c8bb91SVineet Gupta * keeps going till the bottom-most frame. 145*44c8bb91SVineet Gupta *------------------------------------------------------------------------- 146*44c8bb91SVineet Gupta */ 147*44c8bb91SVineet Gupta 148*44c8bb91SVineet Gupta /* Call-back which plugs into unwinding core to dump the stack in 149*44c8bb91SVineet Gupta * case of panic/OOPs/BUG etc 150*44c8bb91SVineet Gupta */ 151*44c8bb91SVineet Gupta static int __print_sym(unsigned int address, void *unused) 152*44c8bb91SVineet Gupta { 153*44c8bb91SVineet Gupta __print_symbol(" %s\n", address); 154*44c8bb91SVineet Gupta return 0; 155*44c8bb91SVineet Gupta } 156*44c8bb91SVineet Gupta 157*44c8bb91SVineet Gupta #ifdef CONFIG_STACKTRACE 158*44c8bb91SVineet Gupta 159*44c8bb91SVineet Gupta /* Call-back which plugs into unwinding core to capture the 160*44c8bb91SVineet Gupta * traces needed by kernel on /proc/<pid>/stack 161*44c8bb91SVineet Gupta */ 162*44c8bb91SVineet Gupta static int __collect_all(unsigned int address, void *arg) 163*44c8bb91SVineet Gupta { 164*44c8bb91SVineet Gupta struct stack_trace *trace = arg; 165*44c8bb91SVineet Gupta 166*44c8bb91SVineet Gupta if (trace->skip > 0) 167*44c8bb91SVineet Gupta trace->skip--; 168*44c8bb91SVineet Gupta else 169*44c8bb91SVineet Gupta trace->entries[trace->nr_entries++] = address; 170*44c8bb91SVineet Gupta 171*44c8bb91SVineet Gupta if (trace->nr_entries >= trace->max_entries) 172*44c8bb91SVineet Gupta return -1; 173*44c8bb91SVineet Gupta 174*44c8bb91SVineet Gupta return 0; 175*44c8bb91SVineet Gupta } 176*44c8bb91SVineet Gupta 177*44c8bb91SVineet Gupta static int __collect_all_but_sched(unsigned int address, void *arg) 178*44c8bb91SVineet Gupta { 179*44c8bb91SVineet Gupta struct stack_trace *trace = arg; 180*44c8bb91SVineet Gupta 181*44c8bb91SVineet Gupta if (in_sched_functions(address)) 182*44c8bb91SVineet Gupta return 0; 183*44c8bb91SVineet Gupta 184*44c8bb91SVineet Gupta if (trace->skip > 0) 185*44c8bb91SVineet Gupta trace->skip--; 186*44c8bb91SVineet Gupta else 187*44c8bb91SVineet Gupta trace->entries[trace->nr_entries++] = address; 188*44c8bb91SVineet Gupta 189*44c8bb91SVineet Gupta if (trace->nr_entries >= trace->max_entries) 190*44c8bb91SVineet Gupta return -1; 191*44c8bb91SVineet Gupta 192*44c8bb91SVineet Gupta return 0; 193*44c8bb91SVineet Gupta } 194*44c8bb91SVineet Gupta 195*44c8bb91SVineet Gupta #endif 196*44c8bb91SVineet Gupta 197*44c8bb91SVineet Gupta static int __get_first_nonsched(unsigned int address, void *unused) 198*44c8bb91SVineet Gupta { 199*44c8bb91SVineet Gupta if (in_sched_functions(address)) 200*44c8bb91SVineet Gupta return 0; 201*44c8bb91SVineet Gupta 202*44c8bb91SVineet Gupta return -1; 203*44c8bb91SVineet Gupta } 204c08098f2SVineet Gupta 205c08098f2SVineet Gupta /*------------------------------------------------------------------------- 206c08098f2SVineet Gupta * APIs expected by various kernel sub-systems 207c08098f2SVineet Gupta *------------------------------------------------------------------------- 208c08098f2SVineet Gupta */ 209c08098f2SVineet Gupta 210c08098f2SVineet Gupta noinline void show_stacktrace(struct task_struct *tsk, struct pt_regs *regs) 211c08098f2SVineet Gupta { 212*44c8bb91SVineet Gupta pr_info("\nStack Trace:\n"); 213*44c8bb91SVineet Gupta arc_unwind_core(tsk, regs, __print_sym, NULL); 214c08098f2SVineet Gupta } 215c08098f2SVineet Gupta EXPORT_SYMBOL(show_stacktrace); 216c08098f2SVineet Gupta 217c08098f2SVineet Gupta /* Expected by sched Code */ 218c08098f2SVineet Gupta void show_stack(struct task_struct *tsk, unsigned long *sp) 219c08098f2SVineet Gupta { 220c08098f2SVineet Gupta show_stacktrace(tsk, NULL); 221c08098f2SVineet Gupta } 222c08098f2SVineet Gupta 223c08098f2SVineet Gupta /* Expected by Rest of kernel code */ 224c08098f2SVineet Gupta void dump_stack(void) 225c08098f2SVineet Gupta { 226c08098f2SVineet Gupta show_stacktrace(NULL, NULL); 227c08098f2SVineet Gupta } 228c08098f2SVineet Gupta EXPORT_SYMBOL(dump_stack); 229c08098f2SVineet Gupta 230c08098f2SVineet Gupta /* Another API expected by schedular, shows up in "ps" as Wait Channel 231c08098f2SVineet Gupta * Ofcourse just returning schedule( ) would be pointless so unwind until 232c08098f2SVineet Gupta * the function is not in schedular code 233c08098f2SVineet Gupta */ 234c08098f2SVineet Gupta unsigned int get_wchan(struct task_struct *tsk) 235c08098f2SVineet Gupta { 236*44c8bb91SVineet Gupta return arc_unwind_core(tsk, NULL, __get_first_nonsched, NULL); 237c08098f2SVineet Gupta } 238*44c8bb91SVineet Gupta 239*44c8bb91SVineet Gupta #ifdef CONFIG_STACKTRACE 240*44c8bb91SVineet Gupta 241*44c8bb91SVineet Gupta /* 242*44c8bb91SVineet Gupta * API required by CONFIG_STACKTRACE, CONFIG_LATENCYTOP. 243*44c8bb91SVineet Gupta * A typical use is when /proc/<pid>/stack is queried by userland 244*44c8bb91SVineet Gupta */ 245*44c8bb91SVineet Gupta void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) 246*44c8bb91SVineet Gupta { 247*44c8bb91SVineet Gupta arc_unwind_core(tsk, NULL, __collect_all_but_sched, trace); 248*44c8bb91SVineet Gupta } 249*44c8bb91SVineet Gupta 250*44c8bb91SVineet Gupta void save_stack_trace(struct stack_trace *trace) 251*44c8bb91SVineet Gupta { 252*44c8bb91SVineet Gupta arc_unwind_core(current, NULL, __collect_all, trace); 253*44c8bb91SVineet Gupta } 254*44c8bb91SVineet Gupta #endif 255