aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/dumpstack.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-01-02 08:46:35 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-01-02 08:46:35 -0500
commitb6a09416e83ffe4eccfb4ef1b91b3b66483fa810 (patch)
treeb30f266e85047244dcdb47d5afc134e76aec530d /arch/x86/kernel/dumpstack.c
parentdb809859c8cee415293b830e67178f526d1eb2be (diff)
parent30a7acd573899fd8b8ac39236eff6468b195ac7d (diff)
Merge 4.15-rc6 into char-misc-next
We want the fixes in here as well. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch/x86/kernel/dumpstack.c')
-rw-r--r--arch/x86/kernel/dumpstack.c81
1 files changed, 64 insertions, 17 deletions
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c
index f13b4c00a5de..5fa110699ed2 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,28 @@ 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_safe(struct stack_info *info, struct pt_regs *regs)
80{
81 if (on_stack(info, regs, sizeof(*regs)))
82 __show_regs(regs, 0);
83 else if (on_stack(info, (void *)regs + IRET_FRAME_OFFSET,
84 IRET_FRAME_SIZE)) {
85 /*
86 * When an interrupt or exception occurs in entry code, the
87 * full pt_regs might not have been saved yet. In that case
88 * just print the iret frame.
89 */
90 show_iret_regs(regs);
91 }
92}
93
53void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, 94void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
54 unsigned long *stack, char *log_lvl) 95 unsigned long *stack, char *log_lvl)
55{ 96{
@@ -71,31 +112,35 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
71 * - task stack 112 * - task stack
72 * - interrupt stack 113 * - interrupt stack
73 * - HW exception stacks (double fault, nmi, debug, mce) 114 * - HW exception stacks (double fault, nmi, debug, mce)
115 * - entry stack
74 * 116 *
75 * x86-32 can have up to three stacks: 117 * x86-32 can have up to four stacks:
76 * - task stack 118 * - task stack
77 * - softirq stack 119 * - softirq stack
78 * - hardirq stack 120 * - hardirq stack
121 * - entry stack
79 */ 122 */
80 for (regs = NULL; stack; stack = PTR_ALIGN(stack_info.next_sp, sizeof(long))) { 123 for (regs = NULL; stack; stack = PTR_ALIGN(stack_info.next_sp, sizeof(long))) {
81 const char *stack_name; 124 const char *stack_name;
82 125
83 /* 126 if (get_stack_info(stack, task, &stack_info, &visit_mask)) {
84 * If we overflowed the task stack into a guard page, jump back 127 /*
85 * to the bottom of the usable stack. 128 * We weren't on a valid stack. It's possible that
86 */ 129 * we overflowed a valid stack into a guard page.
87 if (task_stack_page(task) - (void *)stack < PAGE_SIZE) 130 * See if the next page up is valid so that we can
88 stack = task_stack_page(task); 131 * generate some kind of backtrace if this happens.
89 132 */
90 if (get_stack_info(stack, task, &stack_info, &visit_mask)) 133 stack = (unsigned long *)PAGE_ALIGN((unsigned long)stack);
91 break; 134 if (get_stack_info(stack, task, &stack_info, &visit_mask))
135 break;
136 }
92 137
93 stack_name = stack_type_name(stack_info.type); 138 stack_name = stack_type_name(stack_info.type);
94 if (stack_name) 139 if (stack_name)
95 printk("%s <%s>\n", log_lvl, stack_name); 140 printk("%s <%s>\n", log_lvl, stack_name);
96 141
97 if (regs && on_stack(&stack_info, regs, sizeof(*regs))) 142 if (regs)
98 __show_regs(regs, 0); 143 show_regs_safe(&stack_info, regs);
99 144
100 /* 145 /*
101 * Scan the stack, printing any text addresses we find. At the 146 * Scan the stack, printing any text addresses we find. At the
@@ -119,7 +164,7 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
119 164
120 /* 165 /*
121 * Don't print regs->ip again if it was already printed 166 * Don't print regs->ip again if it was already printed
122 * by __show_regs() below. 167 * by show_regs_safe() below.
123 */ 168 */
124 if (regs && stack == &regs->ip) 169 if (regs && stack == &regs->ip)
125 goto next; 170 goto next;
@@ -155,8 +200,8 @@ next:
155 200
156 /* if the frame has entry regs, print them */ 201 /* if the frame has entry regs, print them */
157 regs = unwind_get_entry_regs(&state); 202 regs = unwind_get_entry_regs(&state);
158 if (regs && on_stack(&stack_info, regs, sizeof(*regs))) 203 if (regs)
159 __show_regs(regs, 0); 204 show_regs_safe(&stack_info, regs);
160 } 205 }
161 206
162 if (stack_name) 207 if (stack_name)
@@ -252,11 +297,13 @@ int __die(const char *str, struct pt_regs *regs, long err)
252 unsigned long sp; 297 unsigned long sp;
253#endif 298#endif
254 printk(KERN_DEFAULT 299 printk(KERN_DEFAULT
255 "%s: %04lx [#%d]%s%s%s%s\n", str, err & 0xffff, ++die_counter, 300 "%s: %04lx [#%d]%s%s%s%s%s\n", str, err & 0xffff, ++die_counter,
256 IS_ENABLED(CONFIG_PREEMPT) ? " PREEMPT" : "", 301 IS_ENABLED(CONFIG_PREEMPT) ? " PREEMPT" : "",
257 IS_ENABLED(CONFIG_SMP) ? " SMP" : "", 302 IS_ENABLED(CONFIG_SMP) ? " SMP" : "",
258 debug_pagealloc_enabled() ? " DEBUG_PAGEALLOC" : "", 303 debug_pagealloc_enabled() ? " DEBUG_PAGEALLOC" : "",
259 IS_ENABLED(CONFIG_KASAN) ? " KASAN" : ""); 304 IS_ENABLED(CONFIG_KASAN) ? " KASAN" : "",
305 IS_ENABLED(CONFIG_PAGE_TABLE_ISOLATION) ?
306 (boot_cpu_has(X86_FEATURE_PTI) ? " PTI" : " NOPTI") : "");
260 307
261 if (notify_die(DIE_OOPS, str, regs, err, 308 if (notify_die(DIE_OOPS, str, regs, err,
262 current->thread.trap_nr, SIGSEGV) == NOTIFY_STOP) 309 current->thread.trap_nr, SIGSEGV) == NOTIFY_STOP)