diff options
| -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); |
