aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/kernel-parameters.txt4
-rw-r--r--arch/x86/kernel/traps_64.c44
2 files changed, 35 insertions, 13 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index e7910f8b4fcc..40db7dd1d92a 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -416,8 +416,8 @@ and is between 256 and 4096 characters. It is defined in the file
416 [SPARC64] tick 416 [SPARC64] tick
417 [X86-64] hpet,tsc 417 [X86-64] hpet,tsc
418 418
419 code_bytes [IA32] How many bytes of object code to print in an 419 code_bytes [IA32/X86_64] How many bytes of object code to print
420 oops report. 420 in an oops report.
421 Range: 0 - 8192 421 Range: 0 - 8192
422 Default: 64 422 Default: 64
423 423
diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c
index 304ca6b4a1ca..0bba7924604e 100644
--- a/arch/x86/kernel/traps_64.c
+++ b/arch/x86/kernel/traps_64.c
@@ -74,6 +74,8 @@ asmlinkage void alignment_check(void);
74asmlinkage void machine_check(void); 74asmlinkage void machine_check(void);
75asmlinkage void spurious_interrupt_bug(void); 75asmlinkage void spurious_interrupt_bug(void);
76 76
77static unsigned int code_bytes = 64;
78
77static inline void conditional_sti(struct pt_regs *regs) 79static inline void conditional_sti(struct pt_regs *regs)
78{ 80{
79 if (regs->flags & X86_EFLAGS_IF) 81 if (regs->flags & X86_EFLAGS_IF)
@@ -459,12 +461,15 @@ EXPORT_SYMBOL(dump_stack);
459void show_registers(struct pt_regs *regs) 461void show_registers(struct pt_regs *regs)
460{ 462{
461 int i; 463 int i;
462 int in_kernel = !user_mode(regs);
463 unsigned long sp; 464 unsigned long sp;
464 const int cpu = smp_processor_id(); 465 const int cpu = smp_processor_id();
465 struct task_struct *cur = cpu_pda(cpu)->pcurrent; 466 struct task_struct *cur = cpu_pda(cpu)->pcurrent;
467 u8 *ip;
468 unsigned int code_prologue = code_bytes * 43 / 64;
469 unsigned int code_len = code_bytes;
466 470
467 sp = regs->sp; 471 sp = regs->sp;
472 ip = (u8 *) regs->ip - code_prologue;
468 printk("CPU %d ", cpu); 473 printk("CPU %d ", cpu);
469 __show_regs(regs); 474 __show_regs(regs);
470 printk("Process %s (pid: %d, threadinfo %p, task %p)\n", 475 printk("Process %s (pid: %d, threadinfo %p, task %p)\n",
@@ -474,22 +479,28 @@ void show_registers(struct pt_regs *regs)
474 * When in-kernel, we also print out the stack and code at the 479 * When in-kernel, we also print out the stack and code at the
475 * time of the fault.. 480 * time of the fault..
476 */ 481 */
477 if (in_kernel) { 482 if (!user_mode(regs)) {
483 unsigned char c;
478 printk("Stack: "); 484 printk("Stack: ");
479 _show_stack(NULL, regs, (unsigned long *)sp, regs->bp); 485 _show_stack(NULL, regs, (unsigned long *)sp, regs->bp);
486 printk("\n");
480 487
481 printk("\nCode: "); 488 printk(KERN_EMERG "Code: ");
482 if (regs->ip < PAGE_OFFSET) 489 if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) {
483 goto bad; 490 /* try starting at RIP */
484 491 ip = (u8 *) regs->ip;
485 for (i=0; i<20; i++) { 492 code_len = code_len - code_prologue + 1;
486 unsigned char c; 493 }
487 if (__get_user(c, &((unsigned char*)regs->ip)[i])) { 494 for (i = 0; i < code_len; i++, ip++) {
488bad: 495 if (ip < (u8 *)PAGE_OFFSET ||
496 probe_kernel_address(ip, c)) {
489 printk(" Bad RIP value."); 497 printk(" Bad RIP value.");
490 break; 498 break;
491 } 499 }
492 printk("%02x ", c); 500 if (ip == (u8 *)regs->ip)
501 printk("<%02x> ", c);
502 else
503 printk("%02x ", c);
493 } 504 }
494 } 505 }
495 printk("\n"); 506 printk("\n");
@@ -1164,3 +1175,14 @@ static int __init kstack_setup(char *s)
1164 return 0; 1175 return 0;
1165} 1176}
1166early_param("kstack", kstack_setup); 1177early_param("kstack", kstack_setup);
1178
1179
1180static int __init code_bytes_setup(char *s)
1181{
1182 code_bytes = simple_strtoul(s, NULL, 0);
1183 if (code_bytes > 8192)
1184 code_bytes = 8192;
1185
1186 return 1;
1187}
1188__setup("code_bytes=", code_bytes_setup);