aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/traps.c44
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
580static 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 */
598void math_error(struct pt_regs *regs, int error_code, int trapnr) 584void 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
666dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code) 666dotraplinkage 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)
681dotraplinkage void 675dotraplinkage void
682do_simd_coprocessor_error(struct pt_regs *regs, long error_code) 676do_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);