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 */ 5*b17b0153SIngo Molnar #include <linux/sched/debug.h> 62bc5f927SAlexander van Heukelum #include <linux/kallsyms.h> 72bc5f927SAlexander van Heukelum #include <linux/kprobes.h> 82bc5f927SAlexander van Heukelum #include <linux/uaccess.h> 92bc5f927SAlexander van Heukelum #include <linux/hardirq.h> 102bc5f927SAlexander van Heukelum #include <linux/kdebug.h> 11186f4360SPaul Gortmaker #include <linux/export.h> 122bc5f927SAlexander van Heukelum #include <linux/ptrace.h> 132bc5f927SAlexander van Heukelum #include <linux/kexec.h> 14b8030906SIngo Molnar #include <linux/sysfs.h> 152bc5f927SAlexander van Heukelum #include <linux/bug.h> 162bc5f927SAlexander van Heukelum #include <linux/nmi.h> 172bc5f927SAlexander van Heukelum 182bc5f927SAlexander van Heukelum #include <asm/stacktrace.h> 192bc5f927SAlexander van Heukelum 203d02a9c4SJosh Poimboeuf const char *stack_type_name(enum stack_type type) 21198d208dSSteven Rostedt { 223d02a9c4SJosh Poimboeuf if (type == STACK_TYPE_IRQ) 233d02a9c4SJosh Poimboeuf return "IRQ"; 243d02a9c4SJosh Poimboeuf 253d02a9c4SJosh Poimboeuf if (type == STACK_TYPE_SOFTIRQ) 263d02a9c4SJosh Poimboeuf return "SOFTIRQ"; 273d02a9c4SJosh Poimboeuf 283d02a9c4SJosh Poimboeuf return NULL; 29198d208dSSteven Rostedt } 30198d208dSSteven Rostedt 31cb76c939SJosh Poimboeuf static bool in_hardirq_stack(unsigned long *stack, struct stack_info *info) 32198d208dSSteven Rostedt { 33cb76c939SJosh Poimboeuf unsigned long *begin = (unsigned long *)this_cpu_read(hardirq_stack); 34cb76c939SJosh Poimboeuf unsigned long *end = begin + (THREAD_SIZE / sizeof(long)); 35198d208dSSteven Rostedt 365fe599e0SJosh Poimboeuf /* 375fe599e0SJosh Poimboeuf * This is a software stack, so 'end' can be a valid stack pointer. 385fe599e0SJosh Poimboeuf * It just means the stack is empty. 395fe599e0SJosh Poimboeuf */ 405fe599e0SJosh Poimboeuf if (stack < begin || stack > end) 41cb76c939SJosh Poimboeuf return false; 42cb76c939SJosh Poimboeuf 43cb76c939SJosh Poimboeuf info->type = STACK_TYPE_IRQ; 44cb76c939SJosh Poimboeuf info->begin = begin; 45cb76c939SJosh Poimboeuf info->end = end; 46cb76c939SJosh Poimboeuf 47cb76c939SJosh Poimboeuf /* 48cb76c939SJosh Poimboeuf * See irq_32.c -- the next stack pointer is stored at the beginning of 49cb76c939SJosh Poimboeuf * the stack. 50cb76c939SJosh Poimboeuf */ 51cb76c939SJosh Poimboeuf info->next_sp = (unsigned long *)*begin; 52cb76c939SJosh Poimboeuf 53cb76c939SJosh Poimboeuf return true; 54198d208dSSteven Rostedt } 55198d208dSSteven Rostedt 56cb76c939SJosh Poimboeuf static bool in_softirq_stack(unsigned long *stack, struct stack_info *info) 57198d208dSSteven Rostedt { 58cb76c939SJosh Poimboeuf unsigned long *begin = (unsigned long *)this_cpu_read(softirq_stack); 59cb76c939SJosh Poimboeuf unsigned long *end = begin + (THREAD_SIZE / sizeof(long)); 60198d208dSSteven Rostedt 615fe599e0SJosh Poimboeuf /* 625fe599e0SJosh Poimboeuf * This is a software stack, so 'end' can be a valid stack pointer. 635fe599e0SJosh Poimboeuf * It just means the stack is empty. 645fe599e0SJosh Poimboeuf */ 655fe599e0SJosh Poimboeuf if (stack < begin || stack > end) 66cb76c939SJosh Poimboeuf return false; 67cb76c939SJosh Poimboeuf 68cb76c939SJosh Poimboeuf info->type = STACK_TYPE_SOFTIRQ; 69cb76c939SJosh Poimboeuf info->begin = begin; 70cb76c939SJosh Poimboeuf info->end = end; 71cb76c939SJosh Poimboeuf 72cb76c939SJosh Poimboeuf /* 73cb76c939SJosh Poimboeuf * The next stack pointer is stored at the beginning of the stack. 74cb76c939SJosh Poimboeuf * See irq_32.c. 75cb76c939SJosh Poimboeuf */ 76cb76c939SJosh Poimboeuf info->next_sp = (unsigned long *)*begin; 77cb76c939SJosh Poimboeuf 78cb76c939SJosh Poimboeuf return true; 79cb76c939SJosh Poimboeuf } 80cb76c939SJosh Poimboeuf 81cb76c939SJosh Poimboeuf int get_stack_info(unsigned long *stack, struct task_struct *task, 82cb76c939SJosh Poimboeuf struct stack_info *info, unsigned long *visit_mask) 83cb76c939SJosh Poimboeuf { 84cb76c939SJosh Poimboeuf if (!stack) 85cb76c939SJosh Poimboeuf goto unknown; 86cb76c939SJosh Poimboeuf 87cb76c939SJosh Poimboeuf task = task ? : current; 88cb76c939SJosh Poimboeuf 89cb76c939SJosh Poimboeuf if (in_task_stack(stack, task, info)) 90fcd709efSJosh Poimboeuf goto recursion_check; 91cb76c939SJosh Poimboeuf 92cb76c939SJosh Poimboeuf if (task != current) 93cb76c939SJosh Poimboeuf goto unknown; 94cb76c939SJosh Poimboeuf 95cb76c939SJosh Poimboeuf if (in_hardirq_stack(stack, info)) 96fcd709efSJosh Poimboeuf goto recursion_check; 97cb76c939SJosh Poimboeuf 98cb76c939SJosh Poimboeuf if (in_softirq_stack(stack, info)) 99fcd709efSJosh Poimboeuf goto recursion_check; 100fcd709efSJosh Poimboeuf 101fcd709efSJosh Poimboeuf goto unknown; 102fcd709efSJosh Poimboeuf 103fcd709efSJosh Poimboeuf recursion_check: 104fcd709efSJosh Poimboeuf /* 105fcd709efSJosh Poimboeuf * Make sure we don't iterate through any given stack more than once. 106fcd709efSJosh Poimboeuf * If it comes up a second time then there's something wrong going on: 107fcd709efSJosh Poimboeuf * just break out and report an unknown stack type. 108fcd709efSJosh Poimboeuf */ 109fcd709efSJosh Poimboeuf if (visit_mask) { 1100d2b8579SJosh Poimboeuf if (*visit_mask & (1UL << info->type)) { 1110d2b8579SJosh Poimboeuf printk_deferred_once(KERN_WARNING "WARNING: stack recursion on stack type %d\n", info->type); 112fcd709efSJosh Poimboeuf goto unknown; 1130d2b8579SJosh Poimboeuf } 114fcd709efSJosh Poimboeuf *visit_mask |= 1UL << info->type; 115fcd709efSJosh Poimboeuf } 116fcd709efSJosh Poimboeuf 117cb76c939SJosh Poimboeuf return 0; 118cb76c939SJosh Poimboeuf 119cb76c939SJosh Poimboeuf unknown: 120cb76c939SJosh Poimboeuf info->type = STACK_TYPE_UNKNOWN; 121cb76c939SJosh Poimboeuf return -EINVAL; 122198d208dSSteven Rostedt } 1230406ca6dSFrederic Weisbecker 12457da8b96SJan Beulich void show_regs(struct pt_regs *regs) 1252bc5f927SAlexander van Heukelum { 1262bc5f927SAlexander van Heukelum int i; 1272bc5f927SAlexander van Heukelum 128a43cb95dSTejun Heo show_regs_print_info(KERN_EMERG); 129f39b6f0eSAndy Lutomirski __show_regs(regs, !user_mode(regs)); 1302bc5f927SAlexander van Heukelum 1312bc5f927SAlexander van Heukelum /* 1322bc5f927SAlexander van Heukelum * When in-kernel, we also print out the stack and code at the 1332bc5f927SAlexander van Heukelum * time of the fault.. 1342bc5f927SAlexander van Heukelum */ 135f39b6f0eSAndy Lutomirski if (!user_mode(regs)) { 1362bc5f927SAlexander van Heukelum unsigned int code_prologue = code_bytes * 43 / 64; 1372bc5f927SAlexander van Heukelum unsigned int code_len = code_bytes; 1382bc5f927SAlexander van Heukelum unsigned char c; 1392bc5f927SAlexander van Heukelum u8 *ip; 1402bc5f927SAlexander van Heukelum 1410ee1dd9fSJosh Poimboeuf show_trace_log_lvl(current, regs, NULL, KERN_EMERG); 1422bc5f927SAlexander van Heukelum 143c767a54bSJoe Perches pr_emerg("Code:"); 1442bc5f927SAlexander van Heukelum 1452bc5f927SAlexander van Heukelum ip = (u8 *)regs->ip - code_prologue; 1462bc5f927SAlexander van Heukelum if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { 1478a541665SAlexander van Heukelum /* try starting at IP */ 1482bc5f927SAlexander van Heukelum ip = (u8 *)regs->ip; 1492bc5f927SAlexander van Heukelum code_len = code_len - code_prologue + 1; 1502bc5f927SAlexander van Heukelum } 1512bc5f927SAlexander van Heukelum for (i = 0; i < code_len; i++, ip++) { 1522bc5f927SAlexander van Heukelum if (ip < (u8 *)PAGE_OFFSET || 1532bc5f927SAlexander van Heukelum probe_kernel_address(ip, c)) { 154c767a54bSJoe Perches pr_cont(" Bad EIP value."); 1552bc5f927SAlexander van Heukelum break; 1562bc5f927SAlexander van Heukelum } 1572bc5f927SAlexander van Heukelum if (ip == (u8 *)regs->ip) 158c767a54bSJoe Perches pr_cont(" <%02x>", c); 1592bc5f927SAlexander van Heukelum else 160c767a54bSJoe Perches pr_cont(" %02x", c); 1612bc5f927SAlexander van Heukelum } 1622bc5f927SAlexander van Heukelum } 163c767a54bSJoe Perches pr_cont("\n"); 1642bc5f927SAlexander van Heukelum } 1652bc5f927SAlexander van Heukelum 1662bc5f927SAlexander van Heukelum int is_valid_bugaddr(unsigned long ip) 1672bc5f927SAlexander van Heukelum { 1682bc5f927SAlexander van Heukelum unsigned short ud2; 1692bc5f927SAlexander van Heukelum 1702bc5f927SAlexander van Heukelum if (ip < PAGE_OFFSET) 1712bc5f927SAlexander van Heukelum return 0; 1722bc5f927SAlexander van Heukelum if (probe_kernel_address((unsigned short *)ip, ud2)) 1732bc5f927SAlexander van Heukelum return 0; 1742bc5f927SAlexander van Heukelum 1752bc5f927SAlexander van Heukelum return ud2 == 0x0b0f; 1762bc5f927SAlexander van Heukelum } 177