diff options
-rw-r--r-- | Documentation/kernel-parameters.txt | 4 | ||||
-rw-r--r-- | arch/x86/kernel/traps_64.c | 44 |
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); | |||
74 | asmlinkage void machine_check(void); | 74 | asmlinkage void machine_check(void); |
75 | asmlinkage void spurious_interrupt_bug(void); | 75 | asmlinkage void spurious_interrupt_bug(void); |
76 | 76 | ||
77 | static unsigned int code_bytes = 64; | ||
78 | |||
77 | static inline void conditional_sti(struct pt_regs *regs) | 79 | static 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); | |||
459 | void show_registers(struct pt_regs *regs) | 461 | void 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++) { |
488 | bad: | 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 | } |
1166 | early_param("kstack", kstack_setup); | 1177 | early_param("kstack", kstack_setup); |
1178 | |||
1179 | |||
1180 | static 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); | ||