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> 106fcbede3SAlexander van Heukelum #include <linux/module.h> 116fcbede3SAlexander van Heukelum #include <linux/ptrace.h> 126fcbede3SAlexander van Heukelum #include <linux/kexec.h> 136fcbede3SAlexander van Heukelum #include <linux/bug.h> 146fcbede3SAlexander van Heukelum #include <linux/nmi.h> 15ae87221dSAndrew Morton #include <linux/sysfs.h> 166fcbede3SAlexander van Heukelum 176fcbede3SAlexander van Heukelum #include <asm/stacktrace.h> 186fcbede3SAlexander van Heukelum 19878719e8SNeil Horman #include "dumpstack.h" 206fcbede3SAlexander van Heukelum 210406ca6dSFrederic Weisbecker 220406ca6dSFrederic Weisbecker static char x86_stack_ids[][8] = { 236fcbede3SAlexander van Heukelum [DEBUG_STACK - 1] = "#DB", 246fcbede3SAlexander van Heukelum [NMI_STACK - 1] = "NMI", 256fcbede3SAlexander van Heukelum [DOUBLEFAULT_STACK - 1] = "#DF", 266fcbede3SAlexander van Heukelum [STACKFAULT_STACK - 1] = "#SS", 276fcbede3SAlexander van Heukelum [MCE_STACK - 1] = "#MC", 286fcbede3SAlexander van Heukelum #if DEBUG_STKSZ > EXCEPTION_STKSZ 296fcbede3SAlexander van Heukelum [N_EXCEPTION_STACKS ... 306fcbede3SAlexander van Heukelum N_EXCEPTION_STACKS + DEBUG_STKSZ / EXCEPTION_STKSZ - 2] = "#DB[?]" 316fcbede3SAlexander van Heukelum #endif 326fcbede3SAlexander van Heukelum }; 330406ca6dSFrederic Weisbecker 340406ca6dSFrederic Weisbecker int x86_is_stack_id(int id, char *name) 350406ca6dSFrederic Weisbecker { 360406ca6dSFrederic Weisbecker return x86_stack_ids[id - 1] == name; 370406ca6dSFrederic Weisbecker } 380406ca6dSFrederic Weisbecker 390406ca6dSFrederic Weisbecker static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, 400406ca6dSFrederic Weisbecker unsigned *usedp, char **idp) 410406ca6dSFrederic Weisbecker { 426fcbede3SAlexander van Heukelum unsigned k; 436fcbede3SAlexander van Heukelum 446fcbede3SAlexander van Heukelum /* 456fcbede3SAlexander van Heukelum * Iterate over all exception stacks, and figure out whether 466fcbede3SAlexander van Heukelum * 'stack' is in one of them: 476fcbede3SAlexander van Heukelum */ 486fcbede3SAlexander van Heukelum for (k = 0; k < N_EXCEPTION_STACKS; k++) { 496fcbede3SAlexander van Heukelum unsigned long end = per_cpu(orig_ist, cpu).ist[k]; 506fcbede3SAlexander van Heukelum /* 516fcbede3SAlexander van Heukelum * Is 'stack' above this exception frame's end? 526fcbede3SAlexander van Heukelum * If yes then skip to the next frame. 536fcbede3SAlexander van Heukelum */ 546fcbede3SAlexander van Heukelum if (stack >= end) 556fcbede3SAlexander van Heukelum continue; 566fcbede3SAlexander van Heukelum /* 576fcbede3SAlexander van Heukelum * Is 'stack' above this exception frame's start address? 586fcbede3SAlexander van Heukelum * If yes then we found the right frame. 596fcbede3SAlexander van Heukelum */ 606fcbede3SAlexander van Heukelum if (stack >= end - EXCEPTION_STKSZ) { 616fcbede3SAlexander van Heukelum /* 626fcbede3SAlexander van Heukelum * Make sure we only iterate through an exception 636fcbede3SAlexander van Heukelum * stack once. If it comes up for the second time 646fcbede3SAlexander van Heukelum * then there's something wrong going on - just 656fcbede3SAlexander van Heukelum * break out and return NULL: 666fcbede3SAlexander van Heukelum */ 676fcbede3SAlexander van Heukelum if (*usedp & (1U << k)) 686fcbede3SAlexander van Heukelum break; 696fcbede3SAlexander van Heukelum *usedp |= 1U << k; 700406ca6dSFrederic Weisbecker *idp = x86_stack_ids[k]; 716fcbede3SAlexander van Heukelum return (unsigned long *)end; 726fcbede3SAlexander van Heukelum } 736fcbede3SAlexander van Heukelum /* 746fcbede3SAlexander van Heukelum * If this is a debug stack, and if it has a larger size than 756fcbede3SAlexander van Heukelum * the usual exception stacks, then 'stack' might still 766fcbede3SAlexander van Heukelum * be within the lower portion of the debug stack: 776fcbede3SAlexander van Heukelum */ 786fcbede3SAlexander van Heukelum #if DEBUG_STKSZ > EXCEPTION_STKSZ 796fcbede3SAlexander van Heukelum if (k == DEBUG_STACK - 1 && stack >= end - DEBUG_STKSZ) { 806fcbede3SAlexander van Heukelum unsigned j = N_EXCEPTION_STACKS - 1; 816fcbede3SAlexander van Heukelum 826fcbede3SAlexander van Heukelum /* 836fcbede3SAlexander van Heukelum * Black magic. A large debug stack is composed of 846fcbede3SAlexander van Heukelum * multiple exception stack entries, which we 856fcbede3SAlexander van Heukelum * iterate through now. Dont look: 866fcbede3SAlexander van Heukelum */ 876fcbede3SAlexander van Heukelum do { 886fcbede3SAlexander van Heukelum ++j; 896fcbede3SAlexander van Heukelum end -= EXCEPTION_STKSZ; 900406ca6dSFrederic Weisbecker x86_stack_ids[j][4] = '1' + 910406ca6dSFrederic Weisbecker (j - N_EXCEPTION_STACKS); 926fcbede3SAlexander van Heukelum } while (stack < end - EXCEPTION_STKSZ); 936fcbede3SAlexander van Heukelum if (*usedp & (1U << j)) 946fcbede3SAlexander van Heukelum break; 956fcbede3SAlexander van Heukelum *usedp |= 1U << j; 960406ca6dSFrederic Weisbecker *idp = x86_stack_ids[j]; 976fcbede3SAlexander van Heukelum return (unsigned long *)end; 986fcbede3SAlexander van Heukelum } 996fcbede3SAlexander van Heukelum #endif 1006fcbede3SAlexander van Heukelum } 1016fcbede3SAlexander van Heukelum return NULL; 1026fcbede3SAlexander van Heukelum } 1036fcbede3SAlexander van Heukelum 104af2d8289SFrederic Weisbecker static inline int 105af2d8289SFrederic Weisbecker in_irq_stack(unsigned long *stack, unsigned long *irq_stack, 106af2d8289SFrederic Weisbecker unsigned long *irq_stack_end) 107af2d8289SFrederic Weisbecker { 108af2d8289SFrederic Weisbecker return (stack >= irq_stack && stack < irq_stack_end); 109af2d8289SFrederic Weisbecker } 110af2d8289SFrederic Weisbecker 111af2d8289SFrederic Weisbecker /* 112af2d8289SFrederic Weisbecker * We are returning from the irq stack and go to the previous one. 113af2d8289SFrederic Weisbecker * If the previous stack is also in the irq stack, then bp in the first 114af2d8289SFrederic Weisbecker * frame of the irq stack points to the previous, interrupted one. 115af2d8289SFrederic Weisbecker * Otherwise we have another level of indirection: We first save 116af2d8289SFrederic Weisbecker * the bp of the previous stack, then we switch the stack to the irq one 117af2d8289SFrederic Weisbecker * and save a new bp that links to the previous one. 118af2d8289SFrederic Weisbecker * (See save_args()) 119af2d8289SFrederic Weisbecker */ 120af2d8289SFrederic Weisbecker static inline unsigned long 121af2d8289SFrederic Weisbecker fixup_bp_irq_link(unsigned long bp, unsigned long *stack, 122af2d8289SFrederic Weisbecker unsigned long *irq_stack, unsigned long *irq_stack_end) 123af2d8289SFrederic Weisbecker { 124af2d8289SFrederic Weisbecker #ifdef CONFIG_FRAME_POINTER 125af2d8289SFrederic Weisbecker struct stack_frame *frame = (struct stack_frame *)bp; 126af2d8289SFrederic Weisbecker 127af2d8289SFrederic Weisbecker if (!in_irq_stack(stack, irq_stack, irq_stack_end)) 128af2d8289SFrederic Weisbecker return (unsigned long)frame->next_frame; 129af2d8289SFrederic Weisbecker #endif 130af2d8289SFrederic Weisbecker return bp; 131af2d8289SFrederic Weisbecker } 132af2d8289SFrederic Weisbecker 1336fcbede3SAlexander van Heukelum /* 1346fcbede3SAlexander van Heukelum * x86-64 can have up to three kernel stacks: 1356fcbede3SAlexander van Heukelum * process stack 1366fcbede3SAlexander van Heukelum * interrupt stack 1376fcbede3SAlexander van Heukelum * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack 1386fcbede3SAlexander van Heukelum */ 1396fcbede3SAlexander van Heukelum 1406fcbede3SAlexander van Heukelum void dump_trace(struct task_struct *task, struct pt_regs *regs, 1416fcbede3SAlexander van Heukelum unsigned long *stack, unsigned long bp, 1426fcbede3SAlexander van Heukelum const struct stacktrace_ops *ops, void *data) 1436fcbede3SAlexander van Heukelum { 1446fcbede3SAlexander van Heukelum const unsigned cpu = get_cpu(); 14526f80bd6SBrian Gerst unsigned long *irq_stack_end = 14626f80bd6SBrian Gerst (unsigned long *)per_cpu(irq_stack_ptr, cpu); 1476fcbede3SAlexander van Heukelum unsigned used = 0; 1486fcbede3SAlexander van Heukelum struct thread_info *tinfo; 1497ee991fbSSteven Rostedt int graph = 0; 1506fcbede3SAlexander van Heukelum 1516fcbede3SAlexander van Heukelum if (!task) 1526fcbede3SAlexander van Heukelum task = current; 1536fcbede3SAlexander van Heukelum 1546fcbede3SAlexander van Heukelum if (!stack) { 1556fcbede3SAlexander van Heukelum unsigned long dummy; 1566fcbede3SAlexander van Heukelum stack = &dummy; 1576fcbede3SAlexander van Heukelum if (task && task != current) 1586fcbede3SAlexander van Heukelum stack = (unsigned long *)task->thread.sp; 1596fcbede3SAlexander van Heukelum } 1606fcbede3SAlexander van Heukelum 1616fcbede3SAlexander van Heukelum #ifdef CONFIG_FRAME_POINTER 1626fcbede3SAlexander van Heukelum if (!bp) { 1636fcbede3SAlexander van Heukelum if (task == current) { 1646fcbede3SAlexander van Heukelum /* Grab bp right from our regs */ 1658a541665SAlexander van Heukelum get_bp(bp); 1666fcbede3SAlexander van Heukelum } else { 1676fcbede3SAlexander van Heukelum /* bp is the last reg pushed by switch_to */ 1686fcbede3SAlexander van Heukelum bp = *(unsigned long *) task->thread.sp; 1696fcbede3SAlexander van Heukelum } 1706fcbede3SAlexander van Heukelum } 1716fcbede3SAlexander van Heukelum #endif 1726fcbede3SAlexander van Heukelum 1736fcbede3SAlexander van Heukelum /* 1746fcbede3SAlexander van Heukelum * Print function call entries in all stacks, starting at the 1756fcbede3SAlexander van Heukelum * current stack address. If the stacks consist of nested 1766fcbede3SAlexander van Heukelum * exceptions 1776fcbede3SAlexander van Heukelum */ 1786fcbede3SAlexander van Heukelum tinfo = task_thread_info(task); 1796fcbede3SAlexander van Heukelum for (;;) { 1806fcbede3SAlexander van Heukelum char *id; 1816fcbede3SAlexander van Heukelum unsigned long *estack_end; 1826fcbede3SAlexander van Heukelum estack_end = in_exception_stack(cpu, (unsigned long)stack, 1836fcbede3SAlexander van Heukelum &used, &id); 1846fcbede3SAlexander van Heukelum 1856fcbede3SAlexander van Heukelum if (estack_end) { 1866fcbede3SAlexander van Heukelum if (ops->stack(data, id) < 0) 1876fcbede3SAlexander van Heukelum break; 1886fcbede3SAlexander van Heukelum 1896fcbede3SAlexander van Heukelum bp = print_context_stack(tinfo, stack, bp, ops, 1907ee991fbSSteven Rostedt data, estack_end, &graph); 1916fcbede3SAlexander van Heukelum ops->stack(data, "<EOE>"); 1926fcbede3SAlexander van Heukelum /* 1936fcbede3SAlexander van Heukelum * We link to the next stack via the 1946fcbede3SAlexander van Heukelum * second-to-last pointer (index -2 to end) in the 1956fcbede3SAlexander van Heukelum * exception stack: 1966fcbede3SAlexander van Heukelum */ 1976fcbede3SAlexander van Heukelum stack = (unsigned long *) estack_end[-2]; 1986fcbede3SAlexander van Heukelum continue; 1996fcbede3SAlexander van Heukelum } 20026f80bd6SBrian Gerst if (irq_stack_end) { 20126f80bd6SBrian Gerst unsigned long *irq_stack; 20226f80bd6SBrian Gerst irq_stack = irq_stack_end - 20326f80bd6SBrian Gerst (IRQ_STACK_SIZE - 64) / sizeof(*irq_stack); 2046fcbede3SAlexander van Heukelum 205af2d8289SFrederic Weisbecker if (in_irq_stack(stack, irq_stack, irq_stack_end)) { 2066fcbede3SAlexander van Heukelum if (ops->stack(data, "IRQ") < 0) 2076fcbede3SAlexander van Heukelum break; 2086fcbede3SAlexander van Heukelum bp = print_context_stack(tinfo, stack, bp, 20926f80bd6SBrian Gerst ops, data, irq_stack_end, &graph); 2106fcbede3SAlexander van Heukelum /* 2116fcbede3SAlexander van Heukelum * We link to the next stack (which would be 2126fcbede3SAlexander van Heukelum * the process stack normally) the last 2136fcbede3SAlexander van Heukelum * pointer (index -1 to end) in the IRQ stack: 2146fcbede3SAlexander van Heukelum */ 21526f80bd6SBrian Gerst stack = (unsigned long *) (irq_stack_end[-1]); 216af2d8289SFrederic Weisbecker bp = fixup_bp_irq_link(bp, stack, irq_stack, 217af2d8289SFrederic Weisbecker irq_stack_end); 21826f80bd6SBrian Gerst irq_stack_end = NULL; 2196fcbede3SAlexander van Heukelum ops->stack(data, "EOI"); 2206fcbede3SAlexander van Heukelum continue; 2216fcbede3SAlexander van Heukelum } 2226fcbede3SAlexander van Heukelum } 2236fcbede3SAlexander van Heukelum break; 2246fcbede3SAlexander van Heukelum } 2256fcbede3SAlexander van Heukelum 2266fcbede3SAlexander van Heukelum /* 2276fcbede3SAlexander van Heukelum * This handles the process stack: 2286fcbede3SAlexander van Heukelum */ 2297ee991fbSSteven Rostedt bp = print_context_stack(tinfo, stack, bp, ops, data, NULL, &graph); 2306fcbede3SAlexander van Heukelum put_cpu(); 2316fcbede3SAlexander van Heukelum } 2326fcbede3SAlexander van Heukelum EXPORT_SYMBOL(dump_trace); 2336fcbede3SAlexander van Heukelum 234878719e8SNeil Horman void 2356fcbede3SAlexander van Heukelum show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, 2366fcbede3SAlexander van Heukelum unsigned long *sp, unsigned long bp, char *log_lvl) 2376fcbede3SAlexander van Heukelum { 2386fcbede3SAlexander van Heukelum unsigned long *stack; 2396fcbede3SAlexander van Heukelum int i; 2406fcbede3SAlexander van Heukelum const int cpu = smp_processor_id(); 24126f80bd6SBrian Gerst unsigned long *irq_stack_end = 24226f80bd6SBrian Gerst (unsigned long *)(per_cpu(irq_stack_ptr, cpu)); 24326f80bd6SBrian Gerst unsigned long *irq_stack = 24426f80bd6SBrian Gerst (unsigned long *)(per_cpu(irq_stack_ptr, cpu) - IRQ_STACK_SIZE); 2456fcbede3SAlexander van Heukelum 2466fcbede3SAlexander van Heukelum /* 2476fcbede3SAlexander van Heukelum * debugging aid: "show_stack(NULL, NULL);" prints the 2486fcbede3SAlexander van Heukelum * back trace for this cpu. 2496fcbede3SAlexander van Heukelum */ 2506fcbede3SAlexander van Heukelum 2516fcbede3SAlexander van Heukelum if (sp == NULL) { 2526fcbede3SAlexander van Heukelum if (task) 2536fcbede3SAlexander van Heukelum sp = (unsigned long *)task->thread.sp; 2546fcbede3SAlexander van Heukelum else 2556fcbede3SAlexander van Heukelum sp = (unsigned long *)&sp; 2566fcbede3SAlexander van Heukelum } 2576fcbede3SAlexander van Heukelum 2586fcbede3SAlexander van Heukelum stack = sp; 2596fcbede3SAlexander van Heukelum for (i = 0; i < kstack_depth_to_print; i++) { 26026f80bd6SBrian Gerst if (stack >= irq_stack && stack <= irq_stack_end) { 26126f80bd6SBrian Gerst if (stack == irq_stack_end) { 26226f80bd6SBrian Gerst stack = (unsigned long *) (irq_stack_end[-1]); 2636fcbede3SAlexander van Heukelum printk(" <EOI> "); 2646fcbede3SAlexander van Heukelum } 2656fcbede3SAlexander van Heukelum } else { 2666fcbede3SAlexander van Heukelum if (((long) stack & (THREAD_SIZE-1)) == 0) 2676fcbede3SAlexander van Heukelum break; 2686fcbede3SAlexander van Heukelum } 2698a541665SAlexander van Heukelum if (i && ((i % STACKSLOTS_PER_LINE) == 0)) 270ca0a8164SAlexander van Heukelum printk("\n%s", log_lvl); 2716fcbede3SAlexander van Heukelum printk(" %016lx", *stack++); 2726fcbede3SAlexander van Heukelum touch_nmi_watchdog(); 2736fcbede3SAlexander van Heukelum } 2746fcbede3SAlexander van Heukelum printk("\n"); 2756fcbede3SAlexander van Heukelum show_trace_log_lvl(task, regs, sp, bp, log_lvl); 2766fcbede3SAlexander van Heukelum } 2776fcbede3SAlexander van Heukelum 2786fcbede3SAlexander van Heukelum void show_registers(struct pt_regs *regs) 2796fcbede3SAlexander van Heukelum { 2806fcbede3SAlexander van Heukelum int i; 2816fcbede3SAlexander van Heukelum unsigned long sp; 2826fcbede3SAlexander van Heukelum const int cpu = smp_processor_id(); 283c6f5e0acSBrian Gerst struct task_struct *cur = current; 2846fcbede3SAlexander van Heukelum 2856fcbede3SAlexander van Heukelum sp = regs->sp; 2866fcbede3SAlexander van Heukelum printk("CPU %d ", cpu); 2876fcbede3SAlexander van Heukelum __show_regs(regs, 1); 2886fcbede3SAlexander van Heukelum printk("Process %s (pid: %d, threadinfo %p, task %p)\n", 2896fcbede3SAlexander van Heukelum cur->comm, cur->pid, task_thread_info(cur), cur); 2906fcbede3SAlexander van Heukelum 2916fcbede3SAlexander van Heukelum /* 2926fcbede3SAlexander van Heukelum * When in-kernel, we also print out the stack and code at the 2936fcbede3SAlexander van Heukelum * time of the fault.. 2946fcbede3SAlexander van Heukelum */ 2956fcbede3SAlexander van Heukelum if (!user_mode(regs)) { 2966fcbede3SAlexander van Heukelum unsigned int code_prologue = code_bytes * 43 / 64; 2976fcbede3SAlexander van Heukelum unsigned int code_len = code_bytes; 2986fcbede3SAlexander van Heukelum unsigned char c; 2996fcbede3SAlexander van Heukelum u8 *ip; 3006fcbede3SAlexander van Heukelum 301ca0a8164SAlexander van Heukelum printk(KERN_EMERG "Stack:\n"); 3026fcbede3SAlexander van Heukelum show_stack_log_lvl(NULL, regs, (unsigned long *)sp, 303ca0a8164SAlexander van Heukelum regs->bp, KERN_EMERG); 3046fcbede3SAlexander van Heukelum 3056fcbede3SAlexander van Heukelum printk(KERN_EMERG "Code: "); 3066fcbede3SAlexander van Heukelum 3076fcbede3SAlexander van Heukelum ip = (u8 *)regs->ip - code_prologue; 3086fcbede3SAlexander van Heukelum if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { 3098a541665SAlexander van Heukelum /* try starting at IP */ 3106fcbede3SAlexander van Heukelum ip = (u8 *)regs->ip; 3116fcbede3SAlexander van Heukelum code_len = code_len - code_prologue + 1; 3126fcbede3SAlexander van Heukelum } 3136fcbede3SAlexander van Heukelum for (i = 0; i < code_len; i++, ip++) { 3146fcbede3SAlexander van Heukelum if (ip < (u8 *)PAGE_OFFSET || 3156fcbede3SAlexander van Heukelum probe_kernel_address(ip, c)) { 3166fcbede3SAlexander van Heukelum printk(" Bad RIP value."); 3176fcbede3SAlexander van Heukelum break; 3186fcbede3SAlexander van Heukelum } 3196fcbede3SAlexander van Heukelum if (ip == (u8 *)regs->ip) 3206fcbede3SAlexander van Heukelum printk("<%02x> ", c); 3216fcbede3SAlexander van Heukelum else 3226fcbede3SAlexander van Heukelum printk("%02x ", c); 3236fcbede3SAlexander van Heukelum } 3246fcbede3SAlexander van Heukelum } 3256fcbede3SAlexander van Heukelum printk("\n"); 3266fcbede3SAlexander van Heukelum } 3276fcbede3SAlexander van Heukelum 3286fcbede3SAlexander van Heukelum int is_valid_bugaddr(unsigned long ip) 3296fcbede3SAlexander van Heukelum { 3306fcbede3SAlexander van Heukelum unsigned short ud2; 3316fcbede3SAlexander van Heukelum 3326fcbede3SAlexander van Heukelum if (__copy_from_user(&ud2, (const void __user *) ip, sizeof(ud2))) 3336fcbede3SAlexander van Heukelum return 0; 3346fcbede3SAlexander van Heukelum 3356fcbede3SAlexander van Heukelum return ud2 == 0x0b0f; 3366fcbede3SAlexander van Heukelum } 3376fcbede3SAlexander van Heukelum 338