blob: 36cf1a49822746da21d2950c9324c1669555e3d4 [file] [log] [blame]
Alexander van Heukelum6fcbede2008-09-30 13:12:15 +02001/*
2 * Copyright (C) 1991, 1992 Linus Torvalds
3 * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs
4 */
5#include <linux/kallsyms.h>
6#include <linux/kprobes.h>
7#include <linux/uaccess.h>
Alexander van Heukelum6fcbede2008-09-30 13:12:15 +02008#include <linux/hardirq.h>
9#include <linux/kdebug.h>
Paul Gortmaker186f4362016-07-13 20:18:56 -040010#include <linux/export.h>
Alexander van Heukelum6fcbede2008-09-30 13:12:15 +020011#include <linux/ptrace.h>
12#include <linux/kexec.h>
Ingo Molnarb8030902009-11-26 08:17:31 +010013#include <linux/sysfs.h>
Alexander van Heukelum6fcbede2008-09-30 13:12:15 +020014#include <linux/bug.h>
15#include <linux/nmi.h>
16
17#include <asm/stacktrace.h>
18
Josh Poimboeuf9c003902016-09-14 21:07:41 -050019static char *exception_stack_names[N_EXCEPTION_STACKS] = {
20 [ DOUBLEFAULT_STACK-1 ] = "#DF",
21 [ NMI_STACK-1 ] = "NMI",
22 [ DEBUG_STACK-1 ] = "#DB",
23 [ MCE_STACK-1 ] = "#MC",
24};
Alexander van Heukelum6fcbede2008-09-30 13:12:15 +020025
Josh Poimboeuf9c003902016-09-14 21:07:41 -050026static unsigned long exception_stack_sizes[N_EXCEPTION_STACKS] = {
27 [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STKSZ,
28 [DEBUG_STACK - 1] = DEBUG_STKSZ
Ingo Molnarb8030902009-11-26 08:17:31 +010029};
Frederic Weisbecker0406ca62009-07-01 21:02:09 +020030
Josh Poimboeufcb76c932016-09-14 21:07:42 -050031void stack_type_str(enum stack_type type, const char **begin, const char **end)
Frederic Weisbecker0406ca62009-07-01 21:02:09 +020032{
Josh Poimboeufcb76c932016-09-14 21:07:42 -050033 BUILD_BUG_ON(N_EXCEPTION_STACKS != 4);
34
35 switch (type) {
36 case STACK_TYPE_IRQ:
37 *begin = "IRQ";
38 *end = "EOI";
39 break;
40 case STACK_TYPE_EXCEPTION ... STACK_TYPE_EXCEPTION_LAST:
41 *begin = exception_stack_names[type - STACK_TYPE_EXCEPTION];
42 *end = "EOE";
43 break;
44 default:
45 *begin = NULL;
46 *end = NULL;
47 }
48}
49
Josh Poimboeuffcd709e2016-09-14 21:07:44 -050050static bool in_exception_stack(unsigned long *stack, struct stack_info *info)
Josh Poimboeufcb76c932016-09-14 21:07:42 -050051{
52 unsigned long *begin, *end;
53 struct pt_regs *regs;
Alexander van Heukelum6fcbede2008-09-30 13:12:15 +020054 unsigned k;
55
Josh Poimboeuf9c003902016-09-14 21:07:41 -050056 BUILD_BUG_ON(N_EXCEPTION_STACKS != 4);
Alexander van Heukelum6fcbede2008-09-30 13:12:15 +020057
Josh Poimboeuf9c003902016-09-14 21:07:41 -050058 for (k = 0; k < N_EXCEPTION_STACKS; k++) {
Josh Poimboeufcb76c932016-09-14 21:07:42 -050059 end = (unsigned long *)raw_cpu_ptr(&orig_ist)->ist[k];
60 begin = end - (exception_stack_sizes[k] / sizeof(long));
61 regs = (struct pt_regs *)end - 1;
Josh Poimboeuf9c003902016-09-14 21:07:41 -050062
63 if (stack < begin || stack >= end)
64 continue;
65
Josh Poimboeufcb76c932016-09-14 21:07:42 -050066 info->type = STACK_TYPE_EXCEPTION + k;
67 info->begin = begin;
68 info->end = end;
69 info->next_sp = (unsigned long *)regs->sp;
70
71 return true;
Alexander van Heukelum6fcbede2008-09-30 13:12:15 +020072 }
Josh Poimboeuf9c003902016-09-14 21:07:41 -050073
Josh Poimboeufcb76c932016-09-14 21:07:42 -050074 return false;
Alexander van Heukelum6fcbede2008-09-30 13:12:15 +020075}
76
Josh Poimboeufcb76c932016-09-14 21:07:42 -050077static bool in_irq_stack(unsigned long *stack, struct stack_info *info)
Frederic Weisbeckeraf2d8282009-12-06 05:34:27 +010078{
Josh Poimboeufcb76c932016-09-14 21:07:42 -050079 unsigned long *end = (unsigned long *)this_cpu_read(irq_stack_ptr);
80 unsigned long *begin = end - (IRQ_STACK_SIZE / sizeof(long));
81
Josh Poimboeuf5fe599e2016-09-14 21:07:43 -050082 /*
83 * This is a software stack, so 'end' can be a valid stack pointer.
84 * It just means the stack is empty.
85 */
86 if (stack < begin || stack > end)
Josh Poimboeufcb76c932016-09-14 21:07:42 -050087 return false;
88
89 info->type = STACK_TYPE_IRQ;
90 info->begin = begin;
91 info->end = end;
92
93 /*
94 * The next stack pointer is the first thing pushed by the entry code
95 * after switching to the irq stack.
96 */
97 info->next_sp = (unsigned long *)*(end - 1);
98
99 return true;
Frederic Weisbeckeraf2d8282009-12-06 05:34:27 +0100100}
101
Josh Poimboeufcb76c932016-09-14 21:07:42 -0500102int get_stack_info(unsigned long *stack, struct task_struct *task,
103 struct stack_info *info, unsigned long *visit_mask)
Steven Rostedt2223f6f2014-02-06 09:41:32 -0500104{
Josh Poimboeufcb76c932016-09-14 21:07:42 -0500105 if (!stack)
106 goto unknown;
Steven Rostedt2223f6f2014-02-06 09:41:32 -0500107
Josh Poimboeufcb76c932016-09-14 21:07:42 -0500108 task = task ? : current;
Steven Rostedt2223f6f2014-02-06 09:41:32 -0500109
Josh Poimboeufcb76c932016-09-14 21:07:42 -0500110 if (in_task_stack(stack, task, info))
Josh Poimboeuffcd709e2016-09-14 21:07:44 -0500111 goto recursion_check;
Steven Rostedt2223f6f2014-02-06 09:41:32 -0500112
Josh Poimboeufcb76c932016-09-14 21:07:42 -0500113 if (task != current)
114 goto unknown;
Steven Rostedt2223f6f2014-02-06 09:41:32 -0500115
Josh Poimboeuffcd709e2016-09-14 21:07:44 -0500116 if (in_exception_stack(stack, info))
117 goto recursion_check;
Steven Rostedt2223f6f2014-02-06 09:41:32 -0500118
Josh Poimboeufcb76c932016-09-14 21:07:42 -0500119 if (in_irq_stack(stack, info))
Josh Poimboeuffcd709e2016-09-14 21:07:44 -0500120 goto recursion_check;
121
122 goto unknown;
123
124recursion_check:
125 /*
126 * Make sure we don't iterate through any given stack more than once.
127 * If it comes up a second time then there's something wrong going on:
128 * just break out and report an unknown stack type.
129 */
130 if (visit_mask) {
131 if (*visit_mask & (1UL << info->type))
132 goto unknown;
133 *visit_mask |= 1UL << info->type;
134 }
Steven Rostedt2223f6f2014-02-06 09:41:32 -0500135
Josh Poimboeufcb76c932016-09-14 21:07:42 -0500136 return 0;
137
138unknown:
139 info->type = STACK_TYPE_UNKNOWN;
140 return -EINVAL;
Steven Rostedt2223f6f2014-02-06 09:41:32 -0500141}
142
Josh Poimboeufe18bccc2016-09-16 14:18:16 -0500143void show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
144 unsigned long *sp, char *log_lvl)
Alexander van Heukelum6fcbede2008-09-30 13:12:15 +0200145{
Ingo Molnar67f2de02009-11-26 08:29:10 +0100146 unsigned long *irq_stack_end;
147 unsigned long *irq_stack;
Alexander van Heukelum6fcbede2008-09-30 13:12:15 +0200148 unsigned long *stack;
149 int i;
Ingo Molnar67f2de02009-11-26 08:29:10 +0100150
Andy Lutomirski1959a602016-09-15 22:45:45 -0700151 if (!try_get_task_stack(task))
152 return;
153
Josh Poimboeufcfeeed22016-09-08 16:49:20 -0500154 irq_stack_end = (unsigned long *)this_cpu_read(irq_stack_ptr);
Josh Poimboeuf4950d6d2016-08-18 10:59:08 -0500155 irq_stack = irq_stack_end - (IRQ_STACK_SIZE / sizeof(long));
Alexander van Heukelum6fcbede2008-09-30 13:12:15 +0200156
Josh Poimboeuf4b8afaf2016-08-24 11:50:17 -0500157 sp = sp ? : get_stack_pointer(task, regs);
Alexander van Heukelum6fcbede2008-09-30 13:12:15 +0200158
159 stack = sp;
160 for (i = 0; i < kstack_depth_to_print; i++) {
Andy Lutomirski98f30b12016-07-14 13:22:53 -0700161 unsigned long word;
162
Brian Gerst26f80bd2009-01-19 00:38:58 +0900163 if (stack >= irq_stack && stack <= irq_stack_end) {
164 if (stack == irq_stack_end) {
165 stack = (unsigned long *) (irq_stack_end[-1]);
Joe Perchesc767a542012-05-21 19:50:07 -0700166 pr_cont(" <EOI> ");
Alexander van Heukelum6fcbede2008-09-30 13:12:15 +0200167 }
168 } else {
Adrien Schildknecht04769ae2015-02-22 16:23:58 +0100169 if (kstack_end(stack))
Alexander van Heukelum6fcbede2008-09-30 13:12:15 +0200170 break;
171 }
Andy Lutomirski98f30b12016-07-14 13:22:53 -0700172
173 if (probe_kernel_address(stack, word))
174 break;
175
Adrien Schildknecht1fc7f612015-02-20 03:34:21 +0100176 if ((i % STACKSLOTS_PER_LINE) == 0) {
177 if (i != 0)
178 pr_cont("\n");
Andy Lutomirski98f30b12016-07-14 13:22:53 -0700179 printk("%s %016lx", log_lvl, word);
Adrien Schildknecht1fc7f612015-02-20 03:34:21 +0100180 } else
Andy Lutomirski98f30b12016-07-14 13:22:53 -0700181 pr_cont(" %016lx", word);
182
183 stack++;
Alexander van Heukelum6fcbede2008-09-30 13:12:15 +0200184 touch_nmi_watchdog();
185 }
Ingo Molnar67f2de02009-11-26 08:29:10 +0100186
Joe Perchesc767a542012-05-21 19:50:07 -0700187 pr_cont("\n");
Josh Poimboeufe18bccc2016-09-16 14:18:16 -0500188 show_trace_log_lvl(task, regs, sp, log_lvl);
Andy Lutomirski1959a602016-09-15 22:45:45 -0700189
190 put_task_stack(task);
Alexander van Heukelum6fcbede2008-09-30 13:12:15 +0200191}
192
Jan Beulich57da8b92012-05-09 08:47:37 +0100193void show_regs(struct pt_regs *regs)
Alexander van Heukelum6fcbede2008-09-30 13:12:15 +0200194{
195 int i;
Alexander van Heukelum6fcbede2008-09-30 13:12:15 +0200196
Tejun Heoa43cb952013-04-30 15:27:17 -0700197 show_regs_print_info(KERN_DEFAULT);
Alexander van Heukelum6fcbede2008-09-30 13:12:15 +0200198 __show_regs(regs, 1);
Alexander van Heukelum6fcbede2008-09-30 13:12:15 +0200199
200 /*
201 * When in-kernel, we also print out the stack and code at the
202 * time of the fault..
203 */
204 if (!user_mode(regs)) {
205 unsigned int code_prologue = code_bytes * 43 / 64;
206 unsigned int code_len = code_bytes;
207 unsigned char c;
208 u8 *ip;
209
Prarit Bhargavab0f4c4b2012-01-26 08:55:34 -0500210 printk(KERN_DEFAULT "Stack:\n");
Josh Poimboeufe18bccc2016-09-16 14:18:16 -0500211 show_stack_log_lvl(current, regs, NULL, KERN_DEFAULT);
Alexander van Heukelum6fcbede2008-09-30 13:12:15 +0200212
Prarit Bhargavab0f4c4b2012-01-26 08:55:34 -0500213 printk(KERN_DEFAULT "Code: ");
Alexander van Heukelum6fcbede2008-09-30 13:12:15 +0200214
215 ip = (u8 *)regs->ip - code_prologue;
216 if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) {
Alexander van Heukelum8a541662008-10-04 23:12:46 +0200217 /* try starting at IP */
Alexander van Heukelum6fcbede2008-09-30 13:12:15 +0200218 ip = (u8 *)regs->ip;
219 code_len = code_len - code_prologue + 1;
220 }
221 for (i = 0; i < code_len; i++, ip++) {
222 if (ip < (u8 *)PAGE_OFFSET ||
223 probe_kernel_address(ip, c)) {
Joe Perchesc767a542012-05-21 19:50:07 -0700224 pr_cont(" Bad RIP value.");
Alexander van Heukelum6fcbede2008-09-30 13:12:15 +0200225 break;
226 }
227 if (ip == (u8 *)regs->ip)
Joe Perchesc767a542012-05-21 19:50:07 -0700228 pr_cont("<%02x> ", c);
Alexander van Heukelum6fcbede2008-09-30 13:12:15 +0200229 else
Joe Perchesc767a542012-05-21 19:50:07 -0700230 pr_cont("%02x ", c);
Alexander van Heukelum6fcbede2008-09-30 13:12:15 +0200231 }
232 }
Joe Perchesc767a542012-05-21 19:50:07 -0700233 pr_cont("\n");
Alexander van Heukelum6fcbede2008-09-30 13:12:15 +0200234}
235
236int is_valid_bugaddr(unsigned long ip)
237{
238 unsigned short ud2;
239
240 if (__copy_from_user(&ud2, (const void __user *) ip, sizeof(ud2)))
241 return 0;
242
243 return ud2 == 0x0b0f;
244}