12bc5f927SAlexander van Heukelum /* 22bc5f927SAlexander van Heukelum * Copyright (C) 1991, 1992 Linus Torvalds 32bc5f927SAlexander van Heukelum * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs 42bc5f927SAlexander van Heukelum */ 52bc5f927SAlexander van Heukelum #include <linux/kallsyms.h> 62bc5f927SAlexander van Heukelum #include <linux/kprobes.h> 72bc5f927SAlexander van Heukelum #include <linux/uaccess.h> 82bc5f927SAlexander van Heukelum #include <linux/hardirq.h> 92bc5f927SAlexander van Heukelum #include <linux/kdebug.h> 10186f4360SPaul Gortmaker #include <linux/export.h> 112bc5f927SAlexander van Heukelum #include <linux/ptrace.h> 122bc5f927SAlexander van Heukelum #include <linux/kexec.h> 13b8030906SIngo Molnar #include <linux/sysfs.h> 142bc5f927SAlexander van Heukelum #include <linux/bug.h> 152bc5f927SAlexander van Heukelum #include <linux/nmi.h> 162bc5f927SAlexander van Heukelum 172bc5f927SAlexander van Heukelum #include <asm/stacktrace.h> 182bc5f927SAlexander van Heukelum 19*3d02a9c4SJosh Poimboeuf const char *stack_type_name(enum stack_type type) 20198d208dSSteven Rostedt { 21*3d02a9c4SJosh Poimboeuf if (type == STACK_TYPE_IRQ) 22*3d02a9c4SJosh Poimboeuf return "IRQ"; 23*3d02a9c4SJosh Poimboeuf 24*3d02a9c4SJosh Poimboeuf if (type == STACK_TYPE_SOFTIRQ) 25*3d02a9c4SJosh Poimboeuf return "SOFTIRQ"; 26*3d02a9c4SJosh Poimboeuf 27*3d02a9c4SJosh Poimboeuf return NULL; 28198d208dSSteven Rostedt } 29198d208dSSteven Rostedt 30cb76c939SJosh Poimboeuf static bool in_hardirq_stack(unsigned long *stack, struct stack_info *info) 31198d208dSSteven Rostedt { 32cb76c939SJosh Poimboeuf unsigned long *begin = (unsigned long *)this_cpu_read(hardirq_stack); 33cb76c939SJosh Poimboeuf unsigned long *end = begin + (THREAD_SIZE / sizeof(long)); 34198d208dSSteven Rostedt 355fe599e0SJosh Poimboeuf /* 365fe599e0SJosh Poimboeuf * This is a software stack, so 'end' can be a valid stack pointer. 375fe599e0SJosh Poimboeuf * It just means the stack is empty. 385fe599e0SJosh Poimboeuf */ 395fe599e0SJosh Poimboeuf if (stack < begin || stack > end) 40cb76c939SJosh Poimboeuf return false; 41cb76c939SJosh Poimboeuf 42cb76c939SJosh Poimboeuf info->type = STACK_TYPE_IRQ; 43cb76c939SJosh Poimboeuf info->begin = begin; 44cb76c939SJosh Poimboeuf info->end = end; 45cb76c939SJosh Poimboeuf 46cb76c939SJosh Poimboeuf /* 47cb76c939SJosh Poimboeuf * See irq_32.c -- the next stack pointer is stored at the beginning of 48cb76c939SJosh Poimboeuf * the stack. 49cb76c939SJosh Poimboeuf */ 50cb76c939SJosh Poimboeuf info->next_sp = (unsigned long *)*begin; 51cb76c939SJosh Poimboeuf 52cb76c939SJosh Poimboeuf return true; 53198d208dSSteven Rostedt } 54198d208dSSteven Rostedt 55cb76c939SJosh Poimboeuf static bool in_softirq_stack(unsigned long *stack, struct stack_info *info) 56198d208dSSteven Rostedt { 57cb76c939SJosh Poimboeuf unsigned long *begin = (unsigned long *)this_cpu_read(softirq_stack); 58cb76c939SJosh Poimboeuf unsigned long *end = begin + (THREAD_SIZE / sizeof(long)); 59198d208dSSteven Rostedt 605fe599e0SJosh Poimboeuf /* 615fe599e0SJosh Poimboeuf * This is a software stack, so 'end' can be a valid stack pointer. 625fe599e0SJosh Poimboeuf * It just means the stack is empty. 635fe599e0SJosh Poimboeuf */ 645fe599e0SJosh Poimboeuf if (stack < begin || stack > end) 65cb76c939SJosh Poimboeuf return false; 66cb76c939SJosh Poimboeuf 67cb76c939SJosh Poimboeuf info->type = STACK_TYPE_SOFTIRQ; 68cb76c939SJosh Poimboeuf info->begin = begin; 69cb76c939SJosh Poimboeuf info->end = end; 70cb76c939SJosh Poimboeuf 71cb76c939SJosh Poimboeuf /* 72cb76c939SJosh Poimboeuf * The next stack pointer is stored at the beginning of the stack. 73cb76c939SJosh Poimboeuf * See irq_32.c. 74cb76c939SJosh Poimboeuf */ 75cb76c939SJosh Poimboeuf info->next_sp = (unsigned long *)*begin; 76cb76c939SJosh Poimboeuf 77cb76c939SJosh Poimboeuf return true; 78cb76c939SJosh Poimboeuf } 79cb76c939SJosh Poimboeuf 80cb76c939SJosh Poimboeuf int get_stack_info(unsigned long *stack, struct task_struct *task, 81cb76c939SJosh Poimboeuf struct stack_info *info, unsigned long *visit_mask) 82cb76c939SJosh Poimboeuf { 83cb76c939SJosh Poimboeuf if (!stack) 84cb76c939SJosh Poimboeuf goto unknown; 85cb76c939SJosh Poimboeuf 86cb76c939SJosh Poimboeuf task = task ? : current; 87cb76c939SJosh Poimboeuf 88cb76c939SJosh Poimboeuf if (in_task_stack(stack, task, info)) 89fcd709efSJosh Poimboeuf goto recursion_check; 90cb76c939SJosh Poimboeuf 91cb76c939SJosh Poimboeuf if (task != current) 92cb76c939SJosh Poimboeuf goto unknown; 93cb76c939SJosh Poimboeuf 94cb76c939SJosh Poimboeuf if (in_hardirq_stack(stack, info)) 95fcd709efSJosh Poimboeuf goto recursion_check; 96cb76c939SJosh Poimboeuf 97cb76c939SJosh Poimboeuf if (in_softirq_stack(stack, info)) 98fcd709efSJosh Poimboeuf goto recursion_check; 99fcd709efSJosh Poimboeuf 100fcd709efSJosh Poimboeuf goto unknown; 101fcd709efSJosh Poimboeuf 102fcd709efSJosh Poimboeuf recursion_check: 103fcd709efSJosh Poimboeuf /* 104fcd709efSJosh Poimboeuf * Make sure we don't iterate through any given stack more than once. 105fcd709efSJosh Poimboeuf * If it comes up a second time then there's something wrong going on: 106fcd709efSJosh Poimboeuf * just break out and report an unknown stack type. 107fcd709efSJosh Poimboeuf */ 108fcd709efSJosh Poimboeuf if (visit_mask) { 1090d2b8579SJosh Poimboeuf if (*visit_mask & (1UL << info->type)) { 1100d2b8579SJosh Poimboeuf printk_deferred_once(KERN_WARNING "WARNING: stack recursion on stack type %d\n", info->type); 111fcd709efSJosh Poimboeuf goto unknown; 1120d2b8579SJosh Poimboeuf } 113fcd709efSJosh Poimboeuf *visit_mask |= 1UL << info->type; 114fcd709efSJosh Poimboeuf } 115fcd709efSJosh Poimboeuf 116cb76c939SJosh Poimboeuf return 0; 117cb76c939SJosh Poimboeuf 118cb76c939SJosh Poimboeuf unknown: 119cb76c939SJosh Poimboeuf info->type = STACK_TYPE_UNKNOWN; 120cb76c939SJosh Poimboeuf return -EINVAL; 121198d208dSSteven Rostedt } 1220406ca6dSFrederic Weisbecker 12357da8b96SJan Beulich void show_regs(struct pt_regs *regs) 1242bc5f927SAlexander van Heukelum { 1252bc5f927SAlexander van Heukelum int i; 1262bc5f927SAlexander van Heukelum 127a43cb95dSTejun Heo show_regs_print_info(KERN_EMERG); 128f39b6f0eSAndy Lutomirski __show_regs(regs, !user_mode(regs)); 1292bc5f927SAlexander van Heukelum 1302bc5f927SAlexander van Heukelum /* 1312bc5f927SAlexander van Heukelum * When in-kernel, we also print out the stack and code at the 1322bc5f927SAlexander van Heukelum * time of the fault.. 1332bc5f927SAlexander van Heukelum */ 134f39b6f0eSAndy Lutomirski if (!user_mode(regs)) { 1352bc5f927SAlexander van Heukelum unsigned int code_prologue = code_bytes * 43 / 64; 1362bc5f927SAlexander van Heukelum unsigned int code_len = code_bytes; 1372bc5f927SAlexander van Heukelum unsigned char c; 1382bc5f927SAlexander van Heukelum u8 *ip; 1392bc5f927SAlexander van Heukelum 1400ee1dd9fSJosh Poimboeuf show_trace_log_lvl(current, regs, NULL, KERN_EMERG); 1412bc5f927SAlexander van Heukelum 142c767a54bSJoe Perches pr_emerg("Code:"); 1432bc5f927SAlexander van Heukelum 1442bc5f927SAlexander van Heukelum ip = (u8 *)regs->ip - code_prologue; 1452bc5f927SAlexander van Heukelum if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { 1468a541665SAlexander van Heukelum /* try starting at IP */ 1472bc5f927SAlexander van Heukelum ip = (u8 *)regs->ip; 1482bc5f927SAlexander van Heukelum code_len = code_len - code_prologue + 1; 1492bc5f927SAlexander van Heukelum } 1502bc5f927SAlexander van Heukelum for (i = 0; i < code_len; i++, ip++) { 1512bc5f927SAlexander van Heukelum if (ip < (u8 *)PAGE_OFFSET || 1522bc5f927SAlexander van Heukelum probe_kernel_address(ip, c)) { 153c767a54bSJoe Perches pr_cont(" Bad EIP value."); 1542bc5f927SAlexander van Heukelum break; 1552bc5f927SAlexander van Heukelum } 1562bc5f927SAlexander van Heukelum if (ip == (u8 *)regs->ip) 157c767a54bSJoe Perches pr_cont(" <%02x>", c); 1582bc5f927SAlexander van Heukelum else 159c767a54bSJoe Perches pr_cont(" %02x", c); 1602bc5f927SAlexander van Heukelum } 1612bc5f927SAlexander van Heukelum } 162c767a54bSJoe Perches pr_cont("\n"); 1632bc5f927SAlexander van Heukelum } 1642bc5f927SAlexander van Heukelum 1652bc5f927SAlexander van Heukelum int is_valid_bugaddr(unsigned long ip) 1662bc5f927SAlexander van Heukelum { 1672bc5f927SAlexander van Heukelum unsigned short ud2; 1682bc5f927SAlexander van Heukelum 1692bc5f927SAlexander van Heukelum if (ip < PAGE_OFFSET) 1702bc5f927SAlexander van Heukelum return 0; 1712bc5f927SAlexander van Heukelum if (probe_kernel_address((unsigned short *)ip, ud2)) 1722bc5f927SAlexander van Heukelum return 0; 1732bc5f927SAlexander van Heukelum 1742bc5f927SAlexander van Heukelum return ud2 == 0x0b0f; 1752bc5f927SAlexander van Heukelum } 176