Merge branch 'x86-fpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[pandora-kernel.git] / arch / x86 / kernel / traps.c
index a472992..02cfb9b 100644 (file)
@@ -534,11 +534,11 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
 
        /* DR6 may or may not be cleared by the CPU */
        set_debugreg(0, 6);
+
        /*
         * The processor cleared BTF, so don't mark that we need it set.
         */
-       clear_tsk_thread_flag(tsk, TIF_DEBUGCTLMSR);
-       tsk->thread.debugctlmsr = 0;
+       clear_tsk_thread_flag(tsk, TIF_BLOCKSTEP);
 
        /* Store the virtualized DR6 value */
        tsk->thread.debugreg6 = dr6;
@@ -576,20 +576,6 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
        return;
 }
 
-#ifdef CONFIG_X86_64
-static int kernel_math_error(struct pt_regs *regs, const char *str, int trapnr)
-{
-       if (fixup_exception(regs))
-               return 1;
-
-       notify_die(DIE_GPF, str, regs, 0, trapnr, SIGFPE);
-       /* Illegal floating point operation in the kernel */
-       current->thread.trap_no = trapnr;
-       die(str, regs, 0);
-       return 0;
-}
-#endif
-
 /*
  * Note that we play around with the 'TS' bit in an attempt to get
  * 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)
  */
 void math_error(struct pt_regs *regs, int error_code, int trapnr)
 {
-       struct task_struct *task;
+       struct task_struct *task = current;
        siginfo_t info;
        unsigned short err;
+       char *str = (trapnr == 16) ? "fpu exception" : "simd exception";
+
+       if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, SIGFPE) == NOTIFY_STOP)
+               return;
+       conditional_sti(regs);
+
+       if (!user_mode_vm(regs))
+       {
+               if (!fixup_exception(regs)) {
+                       task->thread.error_code = error_code;
+                       task->thread.trap_no = trapnr;
+                       die(str, regs, error_code);
+               }
+               return;
+       }
 
        /*
         * Save the info for the exception handler and clear the error.
         */
-       task = current;
        save_init_fpu(task);
        task->thread.trap_no = trapnr;
        task->thread.error_code = error_code;
@@ -665,14 +665,8 @@ void math_error(struct pt_regs *regs, int error_code, int trapnr)
 
 dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code)
 {
-       conditional_sti(regs);
-
 #ifdef CONFIG_X86_32
        ignore_fpu_irq = 1;
-#else
-       if (!user_mode(regs) &&
-           kernel_math_error(regs, "kernel x87 math error", 16))
-               return;
 #endif
 
        math_error(regs, error_code, 16);
@@ -681,16 +675,6 @@ dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code)
 dotraplinkage void
 do_simd_coprocessor_error(struct pt_regs *regs, long error_code)
 {
-       conditional_sti(regs);
-
-#ifdef CONFIG_X86_32
-       ignore_fpu_irq = 1;
-#else
-       if (!user_mode(regs) &&
-                       kernel_math_error(regs, "kernel simd math error", 19))
-               return;
-#endif
-
        math_error(regs, error_code, 19);
 }