aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/dumpstack.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/dumpstack.c')
-rw-r--r--arch/x86/kernel/dumpstack.c98
1 files changed, 79 insertions, 19 deletions
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c
index f13b4c00a5de..afbecff161d1 100644
--- a/arch/x86/kernel/dumpstack.c
+++ b/arch/x86/kernel/dumpstack.c
@@ -18,6 +18,7 @@
18#include <linux/nmi.h> 18#include <linux/nmi.h>
19#include <linux/sysfs.h> 19#include <linux/sysfs.h>
20 20
21#include <asm/cpu_entry_area.h>
21#include <asm/stacktrace.h> 22#include <asm/stacktrace.h>
22#include <asm/unwind.h> 23#include <asm/unwind.h>
23 24
@@ -43,6 +44,24 @@ bool in_task_stack(unsigned long *stack, struct task_struct *task,
43 return true; 44 return true;
44} 45}
45 46
47bool in_entry_stack(unsigned long *stack, struct stack_info *info)
48{
49 struct entry_stack *ss = cpu_entry_stack(smp_processor_id());
50
51 void *begin = ss;
52 void *end = ss + 1;
53
54 if ((void *)stack < begin || (void *)stack >= end)
55 return false;
56
57 info->type = STACK_TYPE_ENTRY;
58 info->begin = begin;
59 info->end = end;
60 info->next_sp = NULL;
61
62 return true;
63}
64
46static void printk_stack_address(unsigned long address, int reliable, 65static void printk_stack_address(unsigned long address, int reliable,
47 char *log_lvl) 66 char *log_lvl)
48{ 67{
@@ -50,6 +69,39 @@ static void printk_stack_address(unsigned long address, int reliable,
50 printk("%s %s%pB\n", log_lvl, reliable ? "" : "? ", (void *)address); 69 printk("%s %s%pB\n", log_lvl, reliable ? "" : "? ", (void *)address);
51} 70}
52 71
72void show_iret_regs(struct pt_regs *regs)
73{
74 printk(KERN_DEFAULT "RIP: %04x:%pS\n", (int)regs->cs, (void *)regs->ip);
75 printk(KERN_DEFAULT "RSP: %04x:%016lx EFLAGS: %08lx", (int)regs->ss,
76 regs->sp, regs->flags);
77}
78
79static void show_regs_if_on_stack(struct stack_info *info, struct pt_regs *regs,
80 bool partial)
81{
82 /*
83 * These on_stack() checks aren't strictly necessary: the unwind code
84 * has already validated the 'regs' pointer. The checks are done for
85 * ordering reasons: if the registers are on the next stack, we don't
86 * want to print them out yet. Otherwise they'll be shown as part of
87 * the wrong stack. Later, when show_trace_log_lvl() switches to the
88 * next stack, this function will be called again with the same regs so
89 * they can be printed in the right context.
90 */
91 if (!partial && on_stack(info, regs, sizeof(*regs))) {
92 __show_regs(regs, 0);
93
94 } else if (partial && on_stack(info, (void *)regs + IRET_FRAME_OFFSET,
95 IRET_FRAME_SIZE)) {
96 /*
97 * When an interrupt or exception occurs in entry code, the
98 * full pt_regs might not have been saved yet. In that case
99 * just print the iret frame.
100 */
101 show_iret_regs(regs);
102 }
103}
104
53void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, 105void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
54 unsigned long *stack, char *log_lvl) 106 unsigned long *stack, char *log_lvl)
55{ 107{
@@ -57,11 +109,13 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
57 struct stack_info stack_info = {0}; 109 struct stack_info stack_info = {0};
58 unsigned long visit_mask = 0; 110 unsigned long visit_mask = 0;
59 int graph_idx = 0; 111 int graph_idx = 0;
112 bool partial;
60 113
61 printk("%sCall Trace:\n", log_lvl); 114 printk("%sCall Trace:\n", log_lvl);
62 115
63 unwind_start(&state, task, regs, stack); 116 unwind_start(&state, task, regs, stack);
64 stack = stack ? : get_stack_pointer(task, regs); 117 stack = stack ? : get_stack_pointer(task, regs);
118 regs = unwind_get_entry_regs(&state, &partial);
65 119
66 /* 120 /*
67 * Iterate through the stacks, starting with the current stack pointer. 121 * Iterate through the stacks, starting with the current stack pointer.
@@ -71,31 +125,35 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
71 * - task stack 125 * - task stack
72 * - interrupt stack 126 * - interrupt stack
73 * - HW exception stacks (double fault, nmi, debug, mce) 127 * - HW exception stacks (double fault, nmi, debug, mce)
128 * - entry stack
74 * 129 *
75 * x86-32 can have up to three stacks: 130 * x86-32 can have up to four stacks:
76 * - task stack 131 * - task stack
77 * - softirq stack 132 * - softirq stack
78 * - hardirq stack 133 * - hardirq stack
134 * - entry stack
79 */ 135 */
80 for (regs = NULL; stack; stack = PTR_ALIGN(stack_info.next_sp, sizeof(long))) { 136 for ( ; stack; stack = PTR_ALIGN(stack_info.next_sp, sizeof(long))) {
81 const char *stack_name; 137 const char *stack_name;
82 138
83 /* 139 if (get_stack_info(stack, task, &stack_info, &visit_mask)) {
84 * If we overflowed the task stack into a guard page, jump back 140 /*
85 * to the bottom of the usable stack. 141 * We weren't on a valid stack. It's possible that
86 */ 142 * we overflowed a valid stack into a guard page.
87 if (task_stack_page(task) - (void *)stack < PAGE_SIZE) 143 * See if the next page up is valid so that we can
88 stack = task_stack_page(task); 144 * generate some kind of backtrace if this happens.
89 145 */
90 if (get_stack_info(stack, task, &stack_info, &visit_mask)) 146 stack = (unsigned long *)PAGE_ALIGN((unsigned long)stack);
91 break; 147 if (get_stack_info(stack, task, &stack_info, &visit_mask))
148 break;
149 }
92 150
93 stack_name = stack_type_name(stack_info.type); 151 stack_name = stack_type_name(stack_info.type);
94 if (stack_name) 152 if (stack_name)
95 printk("%s <%s>\n", log_lvl, stack_name); 153 printk("%s <%s>\n", log_lvl, stack_name);
96 154
97 if (regs && on_stack(&stack_info, regs, sizeof(*regs))) 155 if (regs)
98 __show_regs(regs, 0); 156 show_regs_if_on_stack(&stack_info, regs, partial);
99 157
100 /* 158 /*
101 * Scan the stack, printing any text addresses we find. At the 159 * Scan the stack, printing any text addresses we find. At the
@@ -119,7 +177,7 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
119 177
120 /* 178 /*
121 * Don't print regs->ip again if it was already printed 179 * Don't print regs->ip again if it was already printed
122 * by __show_regs() below. 180 * by show_regs_if_on_stack().
123 */ 181 */
124 if (regs && stack == &regs->ip) 182 if (regs && stack == &regs->ip)
125 goto next; 183 goto next;
@@ -154,9 +212,9 @@ next:
154 unwind_next_frame(&state); 212 unwind_next_frame(&state);
155 213
156 /* if the frame has entry regs, print them */ 214 /* if the frame has entry regs, print them */
157 regs = unwind_get_entry_regs(&state); 215 regs = unwind_get_entry_regs(&state, &partial);
158 if (regs && on_stack(&stack_info, regs, sizeof(*regs))) 216 if (regs)
159 __show_regs(regs, 0); 217 show_regs_if_on_stack(&stack_info, regs, partial);
160 } 218 }
161 219
162 if (stack_name) 220 if (stack_name)
@@ -252,11 +310,13 @@ int __die(const char *str, struct pt_regs *regs, long err)
252 unsigned long sp; 310 unsigned long sp;
253#endif 311#endif
254 printk(KERN_DEFAULT 312 printk(KERN_DEFAULT
255 "%s: %04lx [#%d]%s%s%s%s\n", str, err & 0xffff, ++die_counter, 313 "%s: %04lx [#%d]%s%s%s%s%s\n", str, err & 0xffff, ++die_counter,
256 IS_ENABLED(CONFIG_PREEMPT) ? " PREEMPT" : "", 314 IS_ENABLED(CONFIG_PREEMPT) ? " PREEMPT" : "",
257 IS_ENABLED(CONFIG_SMP) ? " SMP" : "", 315 IS_ENABLED(CONFIG_SMP) ? " SMP" : "",
258 debug_pagealloc_enabled() ? " DEBUG_PAGEALLOC" : "", 316 debug_pagealloc_enabled() ? " DEBUG_PAGEALLOC" : "",
259 IS_ENABLED(CONFIG_KASAN) ? " KASAN" : ""); 317 IS_ENABLED(CONFIG_KASAN) ? " KASAN" : "",
318 IS_ENABLED(CONFIG_PAGE_TABLE_ISOLATION) ?
319 (boot_cpu_has(X86_FEATURE_PTI) ? " PTI" : " NOPTI") : "");
260 320
261 if (notify_die(DIE_OOPS, str, regs, err, 321 if (notify_die(DIE_OOPS, str, regs, err,
262 current->thread.trap_nr, SIGSEGV) == NOTIFY_STOP) 322 current->thread.trap_nr, SIGSEGV) == NOTIFY_STOP)