aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-06-04 22:19:16 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-04 22:19:16 -0400
commit831638568702f82dc291ad92bb0e5a4afdcc81be (patch)
treefd798ad41214b0acdf66b44d5d2df8f0569b5508
parent0afe832e55a70f4bc5e725db400779b4f620290c (diff)
parent4dba072cd097f35fa8f77c49d909ada2b079a4c4 (diff)
Merge branch 'x86-debug-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 debug updates from Ingo Molnar: "This contains the x86 oops code printing reorganization and cleanups from Borislav Betkov, with a particular focus in enhancing opcode dumping all around" * 'x86-debug-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/dumpstack: Explain the reasoning for the prologue and buffer size x86/dumpstack: Save first regs set for the executive summary x86/dumpstack: Add a show_ip() function x86/fault: Dump user opcode bytes on fatal faults x86/dumpstack: Add loglevel argument to show_opcodes() x86/dumpstack: Improve opcodes dumping in the code section x86/dumpstack: Carve out code-dumping into a function x86/dumpstack: Unexport oops_begin() x86/dumpstack: Remove code_bytes
-rw-r--r--Documentation/admin-guide/kernel-parameters.txt5
-rw-r--r--arch/x86/include/asm/stacktrace.h2
-rw-r--r--arch/x86/kernel/dumpstack.c144
-rw-r--r--arch/x86/kernel/process_32.c8
-rw-r--r--arch/x86/mm/fault.c7
5 files changed, 80 insertions, 86 deletions
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 746b799e9ed8..9d699c85d8fe 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -587,11 +587,6 @@
587 Sets the size of memory pool for coherent, atomic dma 587 Sets the size of memory pool for coherent, atomic dma
588 allocations, by default set to 256K. 588 allocations, by default set to 256K.
589 589
590 code_bytes [X86] How many bytes of object code to print
591 in an oops report.
592 Range: 0 - 8192
593 Default: 64
594
595 com20020= [HW,NET] ARCnet - COM20020 chipset 590 com20020= [HW,NET] ARCnet - COM20020 chipset
596 Format: 591 Format:
597 <io>[,<irq>[,<nodeID>[,<backplane>[,<ckp>[,<timeout>]]]]] 592 <io>[,<irq>[,<nodeID>[,<backplane>[,<ckp>[,<timeout>]]]]]
diff --git a/arch/x86/include/asm/stacktrace.h b/arch/x86/include/asm/stacktrace.h
index 133d9425fced..b6dc698f992a 100644
--- a/arch/x86/include/asm/stacktrace.h
+++ b/arch/x86/include/asm/stacktrace.h
@@ -111,4 +111,6 @@ static inline unsigned long caller_frame_pointer(void)
111 return (unsigned long)frame; 111 return (unsigned long)frame;
112} 112}
113 113
114void show_opcodes(u8 *rip, const char *loglvl);
115void show_ip(struct pt_regs *regs, const char *loglvl);
114#endif /* _ASM_X86_STACKTRACE_H */ 116#endif /* _ASM_X86_STACKTRACE_H */
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c
index 18fa9d74c182..666a284116ac 100644
--- a/arch/x86/kernel/dumpstack.c
+++ b/arch/x86/kernel/dumpstack.c
@@ -22,11 +22,14 @@
22#include <asm/stacktrace.h> 22#include <asm/stacktrace.h>
23#include <asm/unwind.h> 23#include <asm/unwind.h>
24 24
25#define OPCODE_BUFSIZE 64
26
25int panic_on_unrecovered_nmi; 27int panic_on_unrecovered_nmi;
26int panic_on_io_nmi; 28int panic_on_io_nmi;
27static unsigned int code_bytes = 64;
28static int die_counter; 29static int die_counter;
29 30
31static struct pt_regs exec_summary_regs;
32
30bool in_task_stack(unsigned long *stack, struct task_struct *task, 33bool in_task_stack(unsigned long *stack, struct task_struct *task,
31 struct stack_info *info) 34 struct stack_info *info)
32{ 35{
@@ -69,9 +72,62 @@ static void printk_stack_address(unsigned long address, int reliable,
69 printk("%s %s%pB\n", log_lvl, reliable ? "" : "? ", (void *)address); 72 printk("%s %s%pB\n", log_lvl, reliable ? "" : "? ", (void *)address);
70} 73}
71 74
75/*
76 * There are a couple of reasons for the 2/3rd prologue, courtesy of Linus:
77 *
78 * In case where we don't have the exact kernel image (which, if we did, we can
79 * simply disassemble and navigate to the RIP), the purpose of the bigger
80 * prologue is to have more context and to be able to correlate the code from
81 * the different toolchains better.
82 *
83 * In addition, it helps in recreating the register allocation of the failing
84 * kernel and thus make sense of the register dump.
85 *
86 * What is more, the additional complication of a variable length insn arch like
87 * x86 warrants having longer byte sequence before rIP so that the disassembler
88 * can "sync" up properly and find instruction boundaries when decoding the
89 * opcode bytes.
90 *
91 * Thus, the 2/3rds prologue and 64 byte OPCODE_BUFSIZE is just a random
92 * guesstimate in attempt to achieve all of the above.
93 */
94void show_opcodes(u8 *rip, const char *loglvl)
95{
96 unsigned int code_prologue = OPCODE_BUFSIZE * 2 / 3;
97 u8 opcodes[OPCODE_BUFSIZE];
98 u8 *ip;
99 int i;
100
101 printk("%sCode: ", loglvl);
102
103 ip = (u8 *)rip - code_prologue;
104 if (probe_kernel_read(opcodes, ip, OPCODE_BUFSIZE)) {
105 pr_cont("Bad RIP value.\n");
106 return;
107 }
108
109 for (i = 0; i < OPCODE_BUFSIZE; i++, ip++) {
110 if (ip == rip)
111 pr_cont("<%02x> ", opcodes[i]);
112 else
113 pr_cont("%02x ", opcodes[i]);
114 }
115 pr_cont("\n");
116}
117
118void show_ip(struct pt_regs *regs, const char *loglvl)
119{
120#ifdef CONFIG_X86_32
121 printk("%sEIP: %pS\n", loglvl, (void *)regs->ip);
122#else
123 printk("%sRIP: %04x:%pS\n", loglvl, (int)regs->cs, (void *)regs->ip);
124#endif
125 show_opcodes((u8 *)regs->ip, loglvl);
126}
127
72void show_iret_regs(struct pt_regs *regs) 128void show_iret_regs(struct pt_regs *regs)
73{ 129{
74 printk(KERN_DEFAULT "RIP: %04x:%pS\n", (int)regs->cs, (void *)regs->ip); 130 show_ip(regs, KERN_DEFAULT);
75 printk(KERN_DEFAULT "RSP: %04x:%016lx EFLAGS: %08lx", (int)regs->ss, 131 printk(KERN_DEFAULT "RSP: %04x:%016lx EFLAGS: %08lx", (int)regs->ss,
76 regs->sp, regs->flags); 132 regs->sp, regs->flags);
77} 133}
@@ -267,7 +323,6 @@ unsigned long oops_begin(void)
267 bust_spinlocks(1); 323 bust_spinlocks(1);
268 return flags; 324 return flags;
269} 325}
270EXPORT_SYMBOL_GPL(oops_begin);
271NOKPROBE_SYMBOL(oops_begin); 326NOKPROBE_SYMBOL(oops_begin);
272 327
273void __noreturn rewind_stack_do_exit(int signr); 328void __noreturn rewind_stack_do_exit(int signr);
@@ -287,6 +342,9 @@ void oops_end(unsigned long flags, struct pt_regs *regs, int signr)
287 raw_local_irq_restore(flags); 342 raw_local_irq_restore(flags);
288 oops_exit(); 343 oops_exit();
289 344
345 /* Executive summary in case the oops scrolled away */
346 __show_regs(&exec_summary_regs, true);
347
290 if (!signr) 348 if (!signr)
291 return; 349 return;
292 if (in_interrupt()) 350 if (in_interrupt())
@@ -305,10 +363,10 @@ NOKPROBE_SYMBOL(oops_end);
305 363
306int __die(const char *str, struct pt_regs *regs, long err) 364int __die(const char *str, struct pt_regs *regs, long err)
307{ 365{
308#ifdef CONFIG_X86_32 366 /* Save the regs of the first oops for the executive summary later. */
309 unsigned short ss; 367 if (!die_counter)
310 unsigned long sp; 368 exec_summary_regs = *regs;
311#endif 369
312 printk(KERN_DEFAULT 370 printk(KERN_DEFAULT
313 "%s: %04lx [#%d]%s%s%s%s%s\n", str, err & 0xffff, ++die_counter, 371 "%s: %04lx [#%d]%s%s%s%s%s\n", str, err & 0xffff, ++die_counter,
314 IS_ENABLED(CONFIG_PREEMPT) ? " PREEMPT" : "", 372 IS_ENABLED(CONFIG_PREEMPT) ? " PREEMPT" : "",
@@ -318,26 +376,13 @@ int __die(const char *str, struct pt_regs *regs, long err)
318 IS_ENABLED(CONFIG_PAGE_TABLE_ISOLATION) ? 376 IS_ENABLED(CONFIG_PAGE_TABLE_ISOLATION) ?
319 (boot_cpu_has(X86_FEATURE_PTI) ? " PTI" : " NOPTI") : ""); 377 (boot_cpu_has(X86_FEATURE_PTI) ? " PTI" : " NOPTI") : "");
320 378
379 show_regs(regs);
380 print_modules();
381
321 if (notify_die(DIE_OOPS, str, regs, err, 382 if (notify_die(DIE_OOPS, str, regs, err,
322 current->thread.trap_nr, SIGSEGV) == NOTIFY_STOP) 383 current->thread.trap_nr, SIGSEGV) == NOTIFY_STOP)
323 return 1; 384 return 1;
324 385
325 print_modules();
326 show_regs(regs);
327#ifdef CONFIG_X86_32
328 if (user_mode(regs)) {
329 sp = regs->sp;
330 ss = regs->ss;
331 } else {
332 sp = kernel_stack_pointer(regs);
333 savesegment(ss, ss);
334 }
335 printk(KERN_EMERG "EIP: %pS SS:ESP: %04x:%08lx\n",
336 (void *)regs->ip, ss, sp);
337#else
338 /* Executive summary in case the oops scrolled away */
339 printk(KERN_ALERT "RIP: %pS RSP: %016lx\n", (void *)regs->ip, regs->sp);
340#endif
341 return 0; 386 return 0;
342} 387}
343NOKPROBE_SYMBOL(__die); 388NOKPROBE_SYMBOL(__die);
@@ -356,30 +401,9 @@ void die(const char *str, struct pt_regs *regs, long err)
356 oops_end(flags, regs, sig); 401 oops_end(flags, regs, sig);
357} 402}
358 403
359static int __init code_bytes_setup(char *s)
360{
361 ssize_t ret;
362 unsigned long val;
363
364 if (!s)
365 return -EINVAL;
366
367 ret = kstrtoul(s, 0, &val);
368 if (ret)
369 return ret;
370
371 code_bytes = val;
372 if (code_bytes > 8192)
373 code_bytes = 8192;
374
375 return 1;
376}
377__setup("code_bytes=", code_bytes_setup);
378
379void show_regs(struct pt_regs *regs) 404void show_regs(struct pt_regs *regs)
380{ 405{
381 bool all = true; 406 bool all = true;
382 int i;
383 407
384 show_regs_print_info(KERN_DEFAULT); 408 show_regs_print_info(KERN_DEFAULT);
385 409
@@ -389,36 +413,8 @@ void show_regs(struct pt_regs *regs)
389 __show_regs(regs, all); 413 __show_regs(regs, all);
390 414
391 /* 415 /*
392 * When in-kernel, we also print out the stack and code at the 416 * When in-kernel, we also print out the stack at the time of the fault..
393 * time of the fault..
394 */ 417 */
395 if (!user_mode(regs)) { 418 if (!user_mode(regs))
396 unsigned int code_prologue = code_bytes * 43 / 64;
397 unsigned int code_len = code_bytes;
398 unsigned char c;
399 u8 *ip;
400
401 show_trace_log_lvl(current, regs, NULL, KERN_DEFAULT); 419 show_trace_log_lvl(current, regs, NULL, KERN_DEFAULT);
402
403 printk(KERN_DEFAULT "Code: ");
404
405 ip = (u8 *)regs->ip - code_prologue;
406 if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) {
407 /* try starting at IP */
408 ip = (u8 *)regs->ip;
409 code_len = code_len - code_prologue + 1;
410 }
411 for (i = 0; i < code_len; i++, ip++) {
412 if (ip < (u8 *)PAGE_OFFSET ||
413 probe_kernel_address(ip, c)) {
414 pr_cont(" Bad RIP value.");
415 break;
416 }
417 if (ip == (u8 *)regs->ip)
418 pr_cont("<%02x> ", c);
419 else
420 pr_cont("%02x ", c);
421 }
422 }
423 pr_cont("\n");
424} 420}
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 5224c6099184..0ae659de21eb 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -76,16 +76,14 @@ void __show_regs(struct pt_regs *regs, int all)
76 savesegment(gs, gs); 76 savesegment(gs, gs);
77 } 77 }
78 78
79 printk(KERN_DEFAULT "EIP: %pS\n", (void *)regs->ip); 79 show_ip(regs, KERN_DEFAULT);
80 printk(KERN_DEFAULT "EFLAGS: %08lx CPU: %d\n", regs->flags,
81 raw_smp_processor_id());
82 80
83 printk(KERN_DEFAULT "EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", 81 printk(KERN_DEFAULT "EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
84 regs->ax, regs->bx, regs->cx, regs->dx); 82 regs->ax, regs->bx, regs->cx, regs->dx);
85 printk(KERN_DEFAULT "ESI: %08lx EDI: %08lx EBP: %08lx ESP: %08lx\n", 83 printk(KERN_DEFAULT "ESI: %08lx EDI: %08lx EBP: %08lx ESP: %08lx\n",
86 regs->si, regs->di, regs->bp, sp); 84 regs->si, regs->di, regs->bp, sp);
87 printk(KERN_DEFAULT " DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x\n", 85 printk(KERN_DEFAULT "DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x EFLAGS: %08lx\n",
88 (u16)regs->ds, (u16)regs->es, (u16)regs->fs, gs, ss); 86 (u16)regs->ds, (u16)regs->es, (u16)regs->fs, gs, ss, regs->flags);
89 87
90 if (!all) 88 if (!all)
91 return; 89 return;
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 0e634956efdf..9a84a0d08727 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -829,6 +829,8 @@ static inline void
829show_signal_msg(struct pt_regs *regs, unsigned long error_code, 829show_signal_msg(struct pt_regs *regs, unsigned long error_code,
830 unsigned long address, struct task_struct *tsk) 830 unsigned long address, struct task_struct *tsk)
831{ 831{
832 const char *loglvl = task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG;
833
832 if (!unhandled_signal(tsk, SIGSEGV)) 834 if (!unhandled_signal(tsk, SIGSEGV))
833 return; 835 return;
834 836
@@ -836,13 +838,14 @@ show_signal_msg(struct pt_regs *regs, unsigned long error_code,
836 return; 838 return;
837 839
838 printk("%s%s[%d]: segfault at %lx ip %px sp %px error %lx", 840 printk("%s%s[%d]: segfault at %lx ip %px sp %px error %lx",
839 task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, 841 loglvl, tsk->comm, task_pid_nr(tsk), address,
840 tsk->comm, task_pid_nr(tsk), address,
841 (void *)regs->ip, (void *)regs->sp, error_code); 842 (void *)regs->ip, (void *)regs->sp, error_code);
842 843
843 print_vma_addr(KERN_CONT " in ", regs->ip); 844 print_vma_addr(KERN_CONT " in ", regs->ip);
844 845
845 printk(KERN_CONT "\n"); 846 printk(KERN_CONT "\n");
847
848 show_opcodes((u8 *)regs->ip, loglvl);
846} 849}
847 850
848static void 851static void