diff options
author | Brian Gerst <brgerst@gmail.com> | 2010-03-21 09:00:45 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2010-05-03 16:39:31 -0400 |
commit | e2e75c915de045f0785387dc32f55e92fab0614c (patch) | |
tree | 35b9683f4694ad34b465155f3e6e07190ba6ca57 /arch | |
parent | 9b6dba9e0798325dab427b9d60c61630ccc39b28 (diff) |
x86: Merge kernel_math_error() into math_error()
Clean up the kernel exception handling and make it more similar to
the other traps.
Signed-off-by: Brian Gerst <brgerst@gmail.com>
LKML-Reference: <1269176446-2489-4-git-send-email-brgerst@gmail.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kernel/traps.c | 44 |
1 files changed, 16 insertions, 28 deletions
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index a472992cecdc..53ba86fc5dd8 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
@@ -576,20 +576,6 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) | |||
576 | return; | 576 | return; |
577 | } | 577 | } |
578 | 578 | ||
579 | #ifdef CONFIG_X86_64 | ||
580 | static int kernel_math_error(struct pt_regs *regs, const char *str, int trapnr) | ||
581 | { | ||
582 | if (fixup_exception(regs)) | ||
583 | return 1; | ||
584 | |||
585 | notify_die(DIE_GPF, str, regs, 0, trapnr, SIGFPE); | ||
586 | /* Illegal floating point operation in the kernel */ | ||
587 | current->thread.trap_no = trapnr; | ||
588 | die(str, regs, 0); | ||
589 | return 0; | ||
590 | } | ||
591 | #endif | ||
592 | |||
593 | /* | 579 | /* |
594 | * Note that we play around with the 'TS' bit in an attempt to get | 580 | * Note that we play around with the 'TS' bit in an attempt to get |
595 | * the correct behaviour even in the presence of the asynchronous | 581 | * the correct behaviour even in the presence of the asynchronous |
@@ -597,14 +583,28 @@ static int kernel_math_error(struct pt_regs *regs, const char *str, int trapnr) | |||
597 | */ | 583 | */ |
598 | void math_error(struct pt_regs *regs, int error_code, int trapnr) | 584 | void math_error(struct pt_regs *regs, int error_code, int trapnr) |
599 | { | 585 | { |
600 | struct task_struct *task; | 586 | struct task_struct *task = current; |
601 | siginfo_t info; | 587 | siginfo_t info; |
602 | unsigned short err; | 588 | unsigned short err; |
589 | char *str = (trapnr == 16) ? "fpu exception" : "simd exception"; | ||
590 | |||
591 | if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, SIGFPE) == NOTIFY_STOP) | ||
592 | return; | ||
593 | conditional_sti(regs); | ||
594 | |||
595 | if (!user_mode_vm(regs)) | ||
596 | { | ||
597 | if (!fixup_exception(regs)) { | ||
598 | task->thread.error_code = error_code; | ||
599 | task->thread.trap_no = trapnr; | ||
600 | die(str, regs, error_code); | ||
601 | } | ||
602 | return; | ||
603 | } | ||
603 | 604 | ||
604 | /* | 605 | /* |
605 | * Save the info for the exception handler and clear the error. | 606 | * Save the info for the exception handler and clear the error. |
606 | */ | 607 | */ |
607 | task = current; | ||
608 | save_init_fpu(task); | 608 | save_init_fpu(task); |
609 | task->thread.trap_no = trapnr; | 609 | task->thread.trap_no = trapnr; |
610 | task->thread.error_code = error_code; | 610 | task->thread.error_code = error_code; |
@@ -665,14 +665,8 @@ void math_error(struct pt_regs *regs, int error_code, int trapnr) | |||
665 | 665 | ||
666 | dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code) | 666 | dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code) |
667 | { | 667 | { |
668 | conditional_sti(regs); | ||
669 | |||
670 | #ifdef CONFIG_X86_32 | 668 | #ifdef CONFIG_X86_32 |
671 | ignore_fpu_irq = 1; | 669 | ignore_fpu_irq = 1; |
672 | #else | ||
673 | if (!user_mode(regs) && | ||
674 | kernel_math_error(regs, "kernel x87 math error", 16)) | ||
675 | return; | ||
676 | #endif | 670 | #endif |
677 | 671 | ||
678 | math_error(regs, error_code, 16); | 672 | math_error(regs, error_code, 16); |
@@ -681,14 +675,8 @@ dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code) | |||
681 | dotraplinkage void | 675 | dotraplinkage void |
682 | do_simd_coprocessor_error(struct pt_regs *regs, long error_code) | 676 | do_simd_coprocessor_error(struct pt_regs *regs, long error_code) |
683 | { | 677 | { |
684 | conditional_sti(regs); | ||
685 | |||
686 | #ifdef CONFIG_X86_32 | 678 | #ifdef CONFIG_X86_32 |
687 | ignore_fpu_irq = 1; | 679 | ignore_fpu_irq = 1; |
688 | #else | ||
689 | if (!user_mode(regs) && | ||
690 | kernel_math_error(regs, "kernel simd math error", 19)) | ||
691 | return; | ||
692 | #endif | 680 | #endif |
693 | 681 | ||
694 | math_error(regs, error_code, 19); | 682 | math_error(regs, error_code, 19); |