1 /* 2 * Copyright (C) 1991, 1992 Linus Torvalds 3 * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs 4 */ 5 #include <linux/sched/debug.h> 6 #include <linux/kallsyms.h> 7 #include <linux/kprobes.h> 8 #include <linux/uaccess.h> 9 #include <linux/hardirq.h> 10 #include <linux/kdebug.h> 11 #include <linux/export.h> 12 #include <linux/ptrace.h> 13 #include <linux/kexec.h> 14 #include <linux/sysfs.h> 15 #include <linux/bug.h> 16 #include <linux/nmi.h> 17 18 #include <asm/stacktrace.h> 19 20 static char *exception_stack_names[N_EXCEPTION_STACKS] = { 21 [ DOUBLEFAULT_STACK-1 ] = "#DF", 22 [ NMI_STACK-1 ] = "NMI", 23 [ DEBUG_STACK-1 ] = "#DB", 24 [ MCE_STACK-1 ] = "#MC", 25 }; 26 27 static unsigned long exception_stack_sizes[N_EXCEPTION_STACKS] = { 28 [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STKSZ, 29 [DEBUG_STACK - 1] = DEBUG_STKSZ 30 }; 31 32 const char *stack_type_name(enum stack_type type) 33 { 34 BUILD_BUG_ON(N_EXCEPTION_STACKS != 4); 35 36 if (type == STACK_TYPE_IRQ) 37 return "IRQ"; 38 39 if (type >= STACK_TYPE_EXCEPTION && type <= STACK_TYPE_EXCEPTION_LAST) 40 return exception_stack_names[type - STACK_TYPE_EXCEPTION]; 41 42 return NULL; 43 } 44 45 static bool in_exception_stack(unsigned long *stack, struct stack_info *info) 46 { 47 unsigned long *begin, *end; 48 struct pt_regs *regs; 49 unsigned k; 50 51 BUILD_BUG_ON(N_EXCEPTION_STACKS != 4); 52 53 for (k = 0; k < N_EXCEPTION_STACKS; k++) { 54 end = (unsigned long *)raw_cpu_ptr(&orig_ist)->ist[k]; 55 begin = end - (exception_stack_sizes[k] / sizeof(long)); 56 regs = (struct pt_regs *)end - 1; 57 58 if (stack < begin || stack >= end) 59 continue; 60 61 info->type = STACK_TYPE_EXCEPTION + k; 62 info->begin = begin; 63 info->end = end; 64 info->next_sp = (unsigned long *)regs->sp; 65 66 return true; 67 } 68 69 return false; 70 } 71 72 static bool in_irq_stack(unsigned long *stack, struct stack_info *info) 73 { 74 unsigned long *end = (unsigned long *)this_cpu_read(irq_stack_ptr); 75 unsigned long *begin = end - (IRQ_STACK_SIZE / sizeof(long)); 76 77 /* 78 * This is a software stack, so 'end' can be a valid stack pointer. 79 * It just means the stack is empty. 80 */ 81 if (stack < begin || stack > end) 82 return false; 83 84 info->type = STACK_TYPE_IRQ; 85 info->begin = begin; 86 info->end = end; 87 88 /* 89 * The next stack pointer is the first thing pushed by the entry code 90 * after switching to the irq stack. 91 */ 92 info->next_sp = (unsigned long *)*(end - 1); 93 94 return true; 95 } 96 97 int get_stack_info(unsigned long *stack, struct task_struct *task, 98 struct stack_info *info, unsigned long *visit_mask) 99 { 100 if (!stack) 101 goto unknown; 102 103 task = task ? : current; 104 105 if (in_task_stack(stack, task, info)) 106 goto recursion_check; 107 108 if (task != current) 109 goto unknown; 110 111 if (in_exception_stack(stack, info)) 112 goto recursion_check; 113 114 if (in_irq_stack(stack, info)) 115 goto recursion_check; 116 117 goto unknown; 118 119 recursion_check: 120 /* 121 * Make sure we don't iterate through any given stack more than once. 122 * If it comes up a second time then there's something wrong going on: 123 * just break out and report an unknown stack type. 124 */ 125 if (visit_mask) { 126 if (*visit_mask & (1UL << info->type)) { 127 printk_deferred_once(KERN_WARNING "WARNING: stack recursion on stack type %d\n", info->type); 128 goto unknown; 129 } 130 *visit_mask |= 1UL << info->type; 131 } 132 133 return 0; 134 135 unknown: 136 info->type = STACK_TYPE_UNKNOWN; 137 return -EINVAL; 138 } 139 140 void show_regs(struct pt_regs *regs) 141 { 142 int i; 143 144 show_regs_print_info(KERN_DEFAULT); 145 __show_regs(regs, 1); 146 147 /* 148 * When in-kernel, we also print out the stack and code at the 149 * time of the fault.. 150 */ 151 if (!user_mode(regs)) { 152 unsigned int code_prologue = code_bytes * 43 / 64; 153 unsigned int code_len = code_bytes; 154 unsigned char c; 155 u8 *ip; 156 157 show_trace_log_lvl(current, regs, NULL, KERN_DEFAULT); 158 159 printk(KERN_DEFAULT "Code: "); 160 161 ip = (u8 *)regs->ip - code_prologue; 162 if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { 163 /* try starting at IP */ 164 ip = (u8 *)regs->ip; 165 code_len = code_len - code_prologue + 1; 166 } 167 for (i = 0; i < code_len; i++, ip++) { 168 if (ip < (u8 *)PAGE_OFFSET || 169 probe_kernel_address(ip, c)) { 170 pr_cont(" Bad RIP value."); 171 break; 172 } 173 if (ip == (u8 *)regs->ip) 174 pr_cont("<%02x> ", c); 175 else 176 pr_cont("%02x ", c); 177 } 178 } 179 pr_cont("\n"); 180 } 181