16fcbede3SAlexander van Heukelum /* 26fcbede3SAlexander van Heukelum * Copyright (C) 1991, 1992 Linus Torvalds 36fcbede3SAlexander van Heukelum * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs 46fcbede3SAlexander van Heukelum */ 56fcbede3SAlexander van Heukelum #include <linux/kallsyms.h> 66fcbede3SAlexander van Heukelum #include <linux/kprobes.h> 76fcbede3SAlexander van Heukelum #include <linux/uaccess.h> 86fcbede3SAlexander van Heukelum #include <linux/hardirq.h> 96fcbede3SAlexander van Heukelum #include <linux/kdebug.h> 10186f4360SPaul Gortmaker #include <linux/export.h> 116fcbede3SAlexander van Heukelum #include <linux/ptrace.h> 126fcbede3SAlexander van Heukelum #include <linux/kexec.h> 13b8030906SIngo Molnar #include <linux/sysfs.h> 146fcbede3SAlexander van Heukelum #include <linux/bug.h> 156fcbede3SAlexander van Heukelum #include <linux/nmi.h> 166fcbede3SAlexander van Heukelum 176fcbede3SAlexander van Heukelum #include <asm/stacktrace.h> 186fcbede3SAlexander van Heukelum 199c003907SJosh Poimboeuf static char *exception_stack_names[N_EXCEPTION_STACKS] = { 206fcbede3SAlexander van Heukelum [ DOUBLEFAULT_STACK-1 ] = "#DF", 219c003907SJosh Poimboeuf [ NMI_STACK-1 ] = "NMI", 229c003907SJosh Poimboeuf [ DEBUG_STACK-1 ] = "#DB", 236fcbede3SAlexander van Heukelum [ MCE_STACK-1 ] = "#MC", 249c003907SJosh Poimboeuf }; 259c003907SJosh Poimboeuf 269c003907SJosh Poimboeuf static unsigned long exception_stack_sizes[N_EXCEPTION_STACKS] = { 279c003907SJosh Poimboeuf [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STKSZ, 289c003907SJosh Poimboeuf [DEBUG_STACK - 1] = DEBUG_STKSZ 296fcbede3SAlexander van Heukelum }; 300406ca6dSFrederic Weisbecker 31cb76c939SJosh Poimboeuf void stack_type_str(enum stack_type type, const char **begin, const char **end) 320406ca6dSFrederic Weisbecker { 33cb76c939SJosh Poimboeuf BUILD_BUG_ON(N_EXCEPTION_STACKS != 4); 34cb76c939SJosh Poimboeuf 35cb76c939SJosh Poimboeuf switch (type) { 36cb76c939SJosh Poimboeuf case STACK_TYPE_IRQ: 37cb76c939SJosh Poimboeuf *begin = "IRQ"; 38cb76c939SJosh Poimboeuf *end = "EOI"; 39cb76c939SJosh Poimboeuf break; 40cb76c939SJosh Poimboeuf case STACK_TYPE_EXCEPTION ... STACK_TYPE_EXCEPTION_LAST: 41cb76c939SJosh Poimboeuf *begin = exception_stack_names[type - STACK_TYPE_EXCEPTION]; 42cb76c939SJosh Poimboeuf *end = "EOE"; 43cb76c939SJosh Poimboeuf break; 44cb76c939SJosh Poimboeuf default: 45cb76c939SJosh Poimboeuf *begin = NULL; 46cb76c939SJosh Poimboeuf *end = NULL; 47cb76c939SJosh Poimboeuf } 48cb76c939SJosh Poimboeuf } 49cb76c939SJosh Poimboeuf 50cb76c939SJosh Poimboeuf static bool in_exception_stack(unsigned long *stack, struct stack_info *info, 51cb76c939SJosh Poimboeuf unsigned long *visit_mask) 52cb76c939SJosh Poimboeuf { 53cb76c939SJosh Poimboeuf unsigned long *begin, *end; 54cb76c939SJosh Poimboeuf struct pt_regs *regs; 556fcbede3SAlexander van Heukelum unsigned k; 566fcbede3SAlexander van Heukelum 579c003907SJosh Poimboeuf BUILD_BUG_ON(N_EXCEPTION_STACKS != 4); 589c003907SJosh Poimboeuf 596fcbede3SAlexander van Heukelum for (k = 0; k < N_EXCEPTION_STACKS; k++) { 60cb76c939SJosh Poimboeuf end = (unsigned long *)raw_cpu_ptr(&orig_ist)->ist[k]; 61cb76c939SJosh Poimboeuf begin = end - (exception_stack_sizes[k] / sizeof(long)); 62cb76c939SJosh Poimboeuf regs = (struct pt_regs *)end - 1; 639c003907SJosh Poimboeuf 649c003907SJosh Poimboeuf if (stack < begin || stack >= end) 656fcbede3SAlexander van Heukelum continue; 669c003907SJosh Poimboeuf 676fcbede3SAlexander van Heukelum /* 68cb76c939SJosh Poimboeuf * Make sure we don't iterate through an exception stack more 69cb76c939SJosh Poimboeuf * than once. If it comes up a second time then there's 70cb76c939SJosh Poimboeuf * something wrong going on - just break out and report an 71cb76c939SJosh Poimboeuf * unknown stack type. 726fcbede3SAlexander van Heukelum */ 73cb76c939SJosh Poimboeuf if (*visit_mask & (1U << k)) 746fcbede3SAlexander van Heukelum break; 75cb76c939SJosh Poimboeuf *visit_mask |= 1U << k; 766fcbede3SAlexander van Heukelum 77cb76c939SJosh Poimboeuf info->type = STACK_TYPE_EXCEPTION + k; 78cb76c939SJosh Poimboeuf info->begin = begin; 79cb76c939SJosh Poimboeuf info->end = end; 80cb76c939SJosh Poimboeuf info->next_sp = (unsigned long *)regs->sp; 81cb76c939SJosh Poimboeuf 82cb76c939SJosh Poimboeuf return true; 836fcbede3SAlexander van Heukelum } 849c003907SJosh Poimboeuf 85cb76c939SJosh Poimboeuf return false; 866fcbede3SAlexander van Heukelum } 876fcbede3SAlexander van Heukelum 88cb76c939SJosh Poimboeuf static bool in_irq_stack(unsigned long *stack, struct stack_info *info) 89af2d8289SFrederic Weisbecker { 90cb76c939SJosh Poimboeuf unsigned long *end = (unsigned long *)this_cpu_read(irq_stack_ptr); 91cb76c939SJosh Poimboeuf unsigned long *begin = end - (IRQ_STACK_SIZE / sizeof(long)); 92cb76c939SJosh Poimboeuf 935fe599e0SJosh Poimboeuf /* 945fe599e0SJosh Poimboeuf * This is a software stack, so 'end' can be a valid stack pointer. 955fe599e0SJosh Poimboeuf * It just means the stack is empty. 965fe599e0SJosh Poimboeuf */ 975fe599e0SJosh Poimboeuf if (stack < begin || stack > end) 98cb76c939SJosh Poimboeuf return false; 99cb76c939SJosh Poimboeuf 100cb76c939SJosh Poimboeuf info->type = STACK_TYPE_IRQ; 101cb76c939SJosh Poimboeuf info->begin = begin; 102cb76c939SJosh Poimboeuf info->end = end; 103cb76c939SJosh Poimboeuf 104cb76c939SJosh Poimboeuf /* 105cb76c939SJosh Poimboeuf * The next stack pointer is the first thing pushed by the entry code 106cb76c939SJosh Poimboeuf * after switching to the irq stack. 107cb76c939SJosh Poimboeuf */ 108cb76c939SJosh Poimboeuf info->next_sp = (unsigned long *)*(end - 1); 109cb76c939SJosh Poimboeuf 110cb76c939SJosh Poimboeuf return true; 111af2d8289SFrederic Weisbecker } 112af2d8289SFrederic Weisbecker 113cb76c939SJosh Poimboeuf int get_stack_info(unsigned long *stack, struct task_struct *task, 114cb76c939SJosh Poimboeuf struct stack_info *info, unsigned long *visit_mask) 1152223f6f6SSteven Rostedt { 116cb76c939SJosh Poimboeuf if (!stack) 117cb76c939SJosh Poimboeuf goto unknown; 1182223f6f6SSteven Rostedt 119cb76c939SJosh Poimboeuf task = task ? : current; 1202223f6f6SSteven Rostedt 121cb76c939SJosh Poimboeuf if (in_task_stack(stack, task, info)) 122cb76c939SJosh Poimboeuf return 0; 1232223f6f6SSteven Rostedt 124cb76c939SJosh Poimboeuf if (task != current) 125cb76c939SJosh Poimboeuf goto unknown; 1262223f6f6SSteven Rostedt 127cb76c939SJosh Poimboeuf if (in_exception_stack(stack, info, visit_mask)) 128cb76c939SJosh Poimboeuf return 0; 1292223f6f6SSteven Rostedt 130cb76c939SJosh Poimboeuf if (in_irq_stack(stack, info)) 131cb76c939SJosh Poimboeuf return 0; 1322223f6f6SSteven Rostedt 133cb76c939SJosh Poimboeuf return 0; 134cb76c939SJosh Poimboeuf 135cb76c939SJosh Poimboeuf unknown: 136cb76c939SJosh Poimboeuf info->type = STACK_TYPE_UNKNOWN; 137cb76c939SJosh Poimboeuf return -EINVAL; 1382223f6f6SSteven Rostedt } 1392223f6f6SSteven Rostedt 140af2d8289SFrederic Weisbecker /* 1416fcbede3SAlexander van Heukelum * x86-64 can have up to three kernel stacks: 1426fcbede3SAlexander van Heukelum * process stack 1436fcbede3SAlexander van Heukelum * interrupt stack 1446fcbede3SAlexander van Heukelum * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack 1456fcbede3SAlexander van Heukelum */ 1466fcbede3SAlexander van Heukelum 147e8e999cfSNamhyung Kim void dump_trace(struct task_struct *task, struct pt_regs *regs, 148e8e999cfSNamhyung Kim unsigned long *stack, unsigned long bp, 1496fcbede3SAlexander van Heukelum const struct stacktrace_ops *ops, void *data) 1506fcbede3SAlexander van Heukelum { 151cb76c939SJosh Poimboeuf unsigned long visit_mask = 0; 152cb76c939SJosh Poimboeuf struct stack_info info; 1532223f6f6SSteven Rostedt int graph = 0; 1542223f6f6SSteven Rostedt int done = 0; 1556fcbede3SAlexander van Heukelum 1564b8afafbSJosh Poimboeuf task = task ? : current; 1574b8afafbSJosh Poimboeuf stack = stack ? : get_stack_pointer(task, regs); 1584b8afafbSJosh Poimboeuf bp = bp ? : (unsigned long)get_frame_pointer(task, regs); 1596fcbede3SAlexander van Heukelum 1606fcbede3SAlexander van Heukelum /* 1616fcbede3SAlexander van Heukelum * Print function call entries in all stacks, starting at the 1626fcbede3SAlexander van Heukelum * current stack address. If the stacks consist of nested 1636fcbede3SAlexander van Heukelum * exceptions 1646fcbede3SAlexander van Heukelum */ 1652223f6f6SSteven Rostedt while (!done) { 166cb76c939SJosh Poimboeuf const char *begin_str, *end_str; 1676fcbede3SAlexander van Heukelum 168cb76c939SJosh Poimboeuf get_stack_info(stack, task, &info, &visit_mask); 1692223f6f6SSteven Rostedt 1702223f6f6SSteven Rostedt /* Default finish unless specified to continue */ 1712223f6f6SSteven Rostedt done = 1; 1722223f6f6SSteven Rostedt 173cb76c939SJosh Poimboeuf switch (info.type) { 1742223f6f6SSteven Rostedt 1752223f6f6SSteven Rostedt /* Break out early if we are on the thread stack */ 176cb76c939SJosh Poimboeuf case STACK_TYPE_TASK: 1772223f6f6SSteven Rostedt break; 1782223f6f6SSteven Rostedt 179cb76c939SJosh Poimboeuf case STACK_TYPE_IRQ: 180cb76c939SJosh Poimboeuf case STACK_TYPE_EXCEPTION ... STACK_TYPE_EXCEPTION_LAST: 1812223f6f6SSteven Rostedt 182cb76c939SJosh Poimboeuf stack_type_str(info.type, &begin_str, &end_str); 183cb76c939SJosh Poimboeuf 184cb76c939SJosh Poimboeuf if (ops->stack(data, begin_str) < 0) 1856fcbede3SAlexander van Heukelum break; 1866fcbede3SAlexander van Heukelum 187da01e18aSLinus Torvalds bp = ops->walk_stack(task, stack, bp, ops, 188cb76c939SJosh Poimboeuf data, &info, &graph); 189cb76c939SJosh Poimboeuf 190cb76c939SJosh Poimboeuf ops->stack(data, end_str); 191cb76c939SJosh Poimboeuf 192cb76c939SJosh Poimboeuf stack = info.next_sp; 1932223f6f6SSteven Rostedt done = 0; 1942223f6f6SSteven Rostedt break; 1956fcbede3SAlexander van Heukelum 196cb76c939SJosh Poimboeuf default: 1972223f6f6SSteven Rostedt ops->stack(data, "UNK"); 1982223f6f6SSteven Rostedt break; 1992223f6f6SSteven Rostedt } 2006fcbede3SAlexander van Heukelum } 2016fcbede3SAlexander van Heukelum 2026fcbede3SAlexander van Heukelum /* 2036fcbede3SAlexander van Heukelum * This handles the process stack: 2046fcbede3SAlexander van Heukelum */ 205cb76c939SJosh Poimboeuf bp = ops->walk_stack(task, stack, bp, ops, data, &info, &graph); 2066fcbede3SAlexander van Heukelum } 2076fcbede3SAlexander van Heukelum EXPORT_SYMBOL(dump_trace); 2086fcbede3SAlexander van Heukelum 209878719e8SNeil Horman void 2106fcbede3SAlexander van Heukelum show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, 211e8e999cfSNamhyung Kim unsigned long *sp, unsigned long bp, char *log_lvl) 2126fcbede3SAlexander van Heukelum { 21367f2de0bSIngo Molnar unsigned long *irq_stack_end; 21467f2de0bSIngo Molnar unsigned long *irq_stack; 2156fcbede3SAlexander van Heukelum unsigned long *stack; 2166fcbede3SAlexander van Heukelum int i; 21767f2de0bSIngo Molnar 218cfeeed27SJosh Poimboeuf irq_stack_end = (unsigned long *)this_cpu_read(irq_stack_ptr); 2194950d6d4SJosh Poimboeuf irq_stack = irq_stack_end - (IRQ_STACK_SIZE / sizeof(long)); 2206fcbede3SAlexander van Heukelum 2214b8afafbSJosh Poimboeuf sp = sp ? : get_stack_pointer(task, regs); 2226fcbede3SAlexander van Heukelum 2236fcbede3SAlexander van Heukelum stack = sp; 2246fcbede3SAlexander van Heukelum for (i = 0; i < kstack_depth_to_print; i++) { 22598f30b12SAndy Lutomirski unsigned long word; 22698f30b12SAndy Lutomirski 22726f80bd6SBrian Gerst if (stack >= irq_stack && stack <= irq_stack_end) { 22826f80bd6SBrian Gerst if (stack == irq_stack_end) { 22926f80bd6SBrian Gerst stack = (unsigned long *) (irq_stack_end[-1]); 230c767a54bSJoe Perches pr_cont(" <EOI> "); 2316fcbede3SAlexander van Heukelum } 2326fcbede3SAlexander van Heukelum } else { 23304769ae3SAdrien Schildknecht if (kstack_end(stack)) 2346fcbede3SAlexander van Heukelum break; 2356fcbede3SAlexander van Heukelum } 23698f30b12SAndy Lutomirski 23798f30b12SAndy Lutomirski if (probe_kernel_address(stack, word)) 23898f30b12SAndy Lutomirski break; 23998f30b12SAndy Lutomirski 2401fc7f61cSAdrien Schildknecht if ((i % STACKSLOTS_PER_LINE) == 0) { 2411fc7f61cSAdrien Schildknecht if (i != 0) 242c767a54bSJoe Perches pr_cont("\n"); 24398f30b12SAndy Lutomirski printk("%s %016lx", log_lvl, word); 2441fc7f61cSAdrien Schildknecht } else 24598f30b12SAndy Lutomirski pr_cont(" %016lx", word); 24698f30b12SAndy Lutomirski 24798f30b12SAndy Lutomirski stack++; 2486fcbede3SAlexander van Heukelum touch_nmi_watchdog(); 2496fcbede3SAlexander van Heukelum } 25067f2de0bSIngo Molnar 251c767a54bSJoe Perches pr_cont("\n"); 252e8e999cfSNamhyung Kim show_trace_log_lvl(task, regs, sp, bp, log_lvl); 2536fcbede3SAlexander van Heukelum } 2546fcbede3SAlexander van Heukelum 25557da8b96SJan Beulich void show_regs(struct pt_regs *regs) 2566fcbede3SAlexander van Heukelum { 2576fcbede3SAlexander van Heukelum int i; 2586fcbede3SAlexander van Heukelum 259a43cb95dSTejun Heo show_regs_print_info(KERN_DEFAULT); 2606fcbede3SAlexander van Heukelum __show_regs(regs, 1); 2616fcbede3SAlexander van Heukelum 2626fcbede3SAlexander van Heukelum /* 2636fcbede3SAlexander van Heukelum * When in-kernel, we also print out the stack and code at the 2646fcbede3SAlexander van Heukelum * time of the fault.. 2656fcbede3SAlexander van Heukelum */ 2666fcbede3SAlexander van Heukelum if (!user_mode(regs)) { 2676fcbede3SAlexander van Heukelum unsigned int code_prologue = code_bytes * 43 / 64; 2686fcbede3SAlexander van Heukelum unsigned int code_len = code_bytes; 2696fcbede3SAlexander van Heukelum unsigned char c; 2706fcbede3SAlexander van Heukelum u8 *ip; 2716fcbede3SAlexander van Heukelum 272b0f4c4b3SPrarit Bhargava printk(KERN_DEFAULT "Stack:\n"); 2735a8ff54cSJosh Poimboeuf show_stack_log_lvl(NULL, regs, NULL, 0, KERN_DEFAULT); 2746fcbede3SAlexander van Heukelum 275b0f4c4b3SPrarit Bhargava printk(KERN_DEFAULT "Code: "); 2766fcbede3SAlexander van Heukelum 2776fcbede3SAlexander van Heukelum ip = (u8 *)regs->ip - code_prologue; 2786fcbede3SAlexander van Heukelum if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { 2798a541665SAlexander van Heukelum /* try starting at IP */ 2806fcbede3SAlexander van Heukelum ip = (u8 *)regs->ip; 2816fcbede3SAlexander van Heukelum code_len = code_len - code_prologue + 1; 2826fcbede3SAlexander van Heukelum } 2836fcbede3SAlexander van Heukelum for (i = 0; i < code_len; i++, ip++) { 2846fcbede3SAlexander van Heukelum if (ip < (u8 *)PAGE_OFFSET || 2856fcbede3SAlexander van Heukelum probe_kernel_address(ip, c)) { 286c767a54bSJoe Perches pr_cont(" Bad RIP value."); 2876fcbede3SAlexander van Heukelum break; 2886fcbede3SAlexander van Heukelum } 2896fcbede3SAlexander van Heukelum if (ip == (u8 *)regs->ip) 290c767a54bSJoe Perches pr_cont("<%02x> ", c); 2916fcbede3SAlexander van Heukelum else 292c767a54bSJoe Perches pr_cont("%02x ", c); 2936fcbede3SAlexander van Heukelum } 2946fcbede3SAlexander van Heukelum } 295c767a54bSJoe Perches pr_cont("\n"); 2966fcbede3SAlexander van Heukelum } 2976fcbede3SAlexander van Heukelum 2986fcbede3SAlexander van Heukelum int is_valid_bugaddr(unsigned long ip) 2996fcbede3SAlexander van Heukelum { 3006fcbede3SAlexander van Heukelum unsigned short ud2; 3016fcbede3SAlexander van Heukelum 3026fcbede3SAlexander van Heukelum if (__copy_from_user(&ud2, (const void __user *) ip, sizeof(ud2))) 3036fcbede3SAlexander van Heukelum return 0; 3046fcbede3SAlexander van Heukelum 3056fcbede3SAlexander van Heukelum return ud2 == 0x0b0f; 3066fcbede3SAlexander van Heukelum } 307