aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBorislav Petkov <bp@suse.de>2018-04-17 12:11:23 -0400
committerThomas Gleixner <tglx@linutronix.de>2018-04-26 10:15:28 -0400
commit602bd705da334f214fc03db328dc37d2f1f33307 (patch)
tree7c0a3b71e9c7291a024f1358db99c5d5083ba81d
parent7cccf0725cf7402514e09c52b089430005798b7f (diff)
x86/dumpstack: Save first regs set for the executive summary
Save the regs set when __die() is onvoked for the first time and print it in oops_end(). Signed-off-by: Borislav Petkov <bp@suse.de> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Josh Poimboeuf <jpoimboe@redhat.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Andy Lutomirski <luto@amacapital.net> Link: https://lkml.kernel.org/r/20180417161124.5294-9-bp@alien8.de
-rw-r--r--arch/x86/kernel/dumpstack.c32
1 files changed, 12 insertions, 20 deletions
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c
index 82da808b5c36..ee344030fd0a 100644
--- a/arch/x86/kernel/dumpstack.c
+++ b/arch/x86/kernel/dumpstack.c
@@ -28,6 +28,8 @@ int panic_on_unrecovered_nmi;
28int panic_on_io_nmi; 28int panic_on_io_nmi;
29static int die_counter; 29static int die_counter;
30 30
31static struct pt_regs exec_summary_regs;
32
31bool in_task_stack(unsigned long *stack, struct task_struct *task, 33bool in_task_stack(unsigned long *stack, struct task_struct *task,
32 struct stack_info *info) 34 struct stack_info *info)
33{ 35{
@@ -321,6 +323,9 @@ void oops_end(unsigned long flags, struct pt_regs *regs, int signr)
321 raw_local_irq_restore(flags); 323 raw_local_irq_restore(flags);
322 oops_exit(); 324 oops_exit();
323 325
326 /* Executive summary in case the oops scrolled away */
327 __show_regs(&exec_summary_regs, true);
328
324 if (!signr) 329 if (!signr)
325 return; 330 return;
326 if (in_interrupt()) 331 if (in_interrupt())
@@ -339,10 +344,10 @@ NOKPROBE_SYMBOL(oops_end);
339 344
340int __die(const char *str, struct pt_regs *regs, long err) 345int __die(const char *str, struct pt_regs *regs, long err)
341{ 346{
342#ifdef CONFIG_X86_32 347 /* Save the regs of the first oops for the executive summary later. */
343 unsigned short ss; 348 if (!die_counter)
344 unsigned long sp; 349 exec_summary_regs = *regs;
345#endif 350
346 printk(KERN_DEFAULT 351 printk(KERN_DEFAULT
347 "%s: %04lx [#%d]%s%s%s%s%s\n", str, err & 0xffff, ++die_counter, 352 "%s: %04lx [#%d]%s%s%s%s%s\n", str, err & 0xffff, ++die_counter,
348 IS_ENABLED(CONFIG_PREEMPT) ? " PREEMPT" : "", 353 IS_ENABLED(CONFIG_PREEMPT) ? " PREEMPT" : "",
@@ -352,26 +357,13 @@ int __die(const char *str, struct pt_regs *regs, long err)
352 IS_ENABLED(CONFIG_PAGE_TABLE_ISOLATION) ? 357 IS_ENABLED(CONFIG_PAGE_TABLE_ISOLATION) ?
353 (boot_cpu_has(X86_FEATURE_PTI) ? " PTI" : " NOPTI") : ""); 358 (boot_cpu_has(X86_FEATURE_PTI) ? " PTI" : " NOPTI") : "");
354 359
360 show_regs(regs);
361 print_modules();
362
355 if (notify_die(DIE_OOPS, str, regs, err, 363 if (notify_die(DIE_OOPS, str, regs, err,
356 current->thread.trap_nr, SIGSEGV) == NOTIFY_STOP) 364 current->thread.trap_nr, SIGSEGV) == NOTIFY_STOP)
357 return 1; 365 return 1;
358 366
359 print_modules();
360 show_regs(regs);
361#ifdef CONFIG_X86_32
362 if (user_mode(regs)) {
363 sp = regs->sp;
364 ss = regs->ss;
365 } else {
366 sp = kernel_stack_pointer(regs);
367 savesegment(ss, ss);
368 }
369 printk(KERN_EMERG "EIP: %pS SS:ESP: %04x:%08lx\n",
370 (void *)regs->ip, ss, sp);
371#else
372 /* Executive summary in case the oops scrolled away */
373 printk(KERN_ALERT "RIP: %pS RSP: %016lx\n", (void *)regs->ip, regs->sp);
374#endif
375 return 0; 367 return 0;
376} 368}
377NOKPROBE_SYMBOL(__die); 369NOKPROBE_SYMBOL(__die);