diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-02-20 17:07:48 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-02-20 18:09:44 -0500 |
commit | 1cc99544dde9e48602979f16b9309fade6e93051 (patch) | |
tree | 034a5a92f899b0e9cbcddce136f2243bc3617a1a | |
parent | 8f7661496cece8320137d5e26808825498fd2b26 (diff) |
x86, mm: fault.c, unify oops handling
Impact: add oops-recursion check to 32-bit
Unify the oops state-machine, to the 64-bit version. It is
slightly more careful in that it does a recursion check
in oops_begin(), and is thus more likely to show the relevant
oops.
It also means that 32-bit will print one more line at the
end of pagefault triggered oopses:
printk(KERN_EMERG "CR2: %016lx\n", address);
Which is generally good information to be seen in partial-dump
digital-camera jpegs ;-)
The downside is the somewhat more complex critical path. Both
variants have been tested well meanwhile by kernel developers
crashing their boxes so i dont think this is a practical worry.
This removes 3 ugly #ifdefs from no_context() and makes the
function a lot nicer read.
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | arch/x86/mm/fault.c | 19 |
1 files changed, 3 insertions, 16 deletions
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index ebfaca3bbb12..8fe2dd254df0 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c | |||
@@ -659,11 +659,8 @@ no_context(struct pt_regs *regs, unsigned long error_code, | |||
659 | { | 659 | { |
660 | struct task_struct *tsk = current; | 660 | struct task_struct *tsk = current; |
661 | unsigned long *stackend; | 661 | unsigned long *stackend; |
662 | |||
663 | #ifdef CONFIG_X86_64 | ||
664 | unsigned long flags; | 662 | unsigned long flags; |
665 | int sig; | 663 | int sig; |
666 | #endif | ||
667 | 664 | ||
668 | /* Are we prepared to handle this kernel fault? */ | 665 | /* Are we prepared to handle this kernel fault? */ |
669 | if (fixup_exception(regs)) | 666 | if (fixup_exception(regs)) |
@@ -690,11 +687,7 @@ no_context(struct pt_regs *regs, unsigned long error_code, | |||
690 | * Oops. The kernel tried to access some bad page. We'll have to | 687 | * Oops. The kernel tried to access some bad page. We'll have to |
691 | * terminate things with extreme prejudice: | 688 | * terminate things with extreme prejudice: |
692 | */ | 689 | */ |
693 | #ifdef CONFIG_X86_32 | ||
694 | bust_spinlocks(1); | ||
695 | #else | ||
696 | flags = oops_begin(); | 690 | flags = oops_begin(); |
697 | #endif | ||
698 | 691 | ||
699 | show_fault_oops(regs, error_code, address); | 692 | show_fault_oops(regs, error_code, address); |
700 | 693 | ||
@@ -702,15 +695,10 @@ no_context(struct pt_regs *regs, unsigned long error_code, | |||
702 | if (*stackend != STACK_END_MAGIC) | 695 | if (*stackend != STACK_END_MAGIC) |
703 | printk(KERN_ALERT "Thread overran stack, or stack corrupted\n"); | 696 | printk(KERN_ALERT "Thread overran stack, or stack corrupted\n"); |
704 | 697 | ||
705 | tsk->thread.cr2 = address; | 698 | tsk->thread.cr2 = address; |
706 | tsk->thread.trap_no = 14; | 699 | tsk->thread.trap_no = 14; |
707 | tsk->thread.error_code = error_code; | 700 | tsk->thread.error_code = error_code; |
708 | 701 | ||
709 | #ifdef CONFIG_X86_32 | ||
710 | die("Oops", regs, error_code); | ||
711 | bust_spinlocks(0); | ||
712 | do_exit(SIGKILL); | ||
713 | #else | ||
714 | sig = SIGKILL; | 702 | sig = SIGKILL; |
715 | if (__die("Oops", regs, error_code)) | 703 | if (__die("Oops", regs, error_code)) |
716 | sig = 0; | 704 | sig = 0; |
@@ -719,7 +707,6 @@ no_context(struct pt_regs *regs, unsigned long error_code, | |||
719 | printk(KERN_EMERG "CR2: %016lx\n", address); | 707 | printk(KERN_EMERG "CR2: %016lx\n", address); |
720 | 708 | ||
721 | oops_end(flags, regs, sig); | 709 | oops_end(flags, regs, sig); |
722 | #endif | ||
723 | } | 710 | } |
724 | 711 | ||
725 | /* | 712 | /* |