]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - arch/x86/kernel/i387.c
Merge tag 'cleanup-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm...
[karo-tx-linux.git] / arch / x86 / kernel / i387.c
index a9a4229f6161b25b6e8a5752be7943f478525d21..d5651fce0b71af6c15226483b6a06398ccbeb8a0 100644 (file)
 #include <asm/sigcontext.h>
 #include <asm/processor.h>
 #include <asm/math_emu.h>
+#include <asm/tlbflush.h>
 #include <asm/uaccess.h>
 #include <asm/ptrace.h>
 #include <asm/i387.h>
 #include <asm/fpu-internal.h>
 #include <asm/user.h>
 
+static DEFINE_PER_CPU(bool, in_kernel_fpu);
+
+void kernel_fpu_disable(void)
+{
+       WARN_ON(this_cpu_read(in_kernel_fpu));
+       this_cpu_write(in_kernel_fpu, true);
+}
+
+void kernel_fpu_enable(void)
+{
+       this_cpu_write(in_kernel_fpu, false);
+}
+
 /*
  * Were we in an interrupt that interrupted kernel mode?
  *
@@ -33,6 +47,9 @@
  */
 static inline bool interrupted_kernel_fpu_idle(void)
 {
+       if (this_cpu_read(in_kernel_fpu))
+               return false;
+
        if (use_eager_fpu())
                return __thread_has_fpu(current);
 
@@ -73,10 +90,10 @@ void __kernel_fpu_begin(void)
 {
        struct task_struct *me = current;
 
+       this_cpu_write(in_kernel_fpu, true);
+
        if (__thread_has_fpu(me)) {
-               __thread_clear_has_fpu(me);
                __save_init_fpu(me);
-               /* We do 'stts()' in __kernel_fpu_end() */
        } else if (!use_eager_fpu()) {
                this_cpu_write(fpu_owner_task, NULL);
                clts();
@@ -86,19 +103,16 @@ EXPORT_SYMBOL(__kernel_fpu_begin);
 
 void __kernel_fpu_end(void)
 {
-       if (use_eager_fpu()) {
-               /*
-                * For eager fpu, most the time, tsk_used_math() is true.
-                * Restore the user math as we are done with the kernel usage.
-                * At few instances during thread exit, signal handling etc,
-                * tsk_used_math() is false. Those few places will take proper
-                * actions, so we don't need to restore the math here.
-                */
-               if (likely(tsk_used_math(current)))
-                       math_state_restore();
-       } else {
+       struct task_struct *me = current;
+
+       if (__thread_has_fpu(me)) {
+               if (WARN_ON(restore_fpu_checking(me)))
+                       drop_init_fpu(me);
+       } else if (!use_eager_fpu()) {
                stts();
        }
+
+       this_cpu_write(in_kernel_fpu, false);
 }
 EXPORT_SYMBOL(__kernel_fpu_end);
 
@@ -180,7 +194,7 @@ void fpu_init(void)
        if (cpu_has_xmm)
                cr4_mask |= X86_CR4_OSXMMEXCPT;
        if (cr4_mask)
-               set_in_cr4(cr4_mask);
+               cr4_set_bits(cr4_mask);
 
        cr0 = read_cr0();
        cr0 &= ~(X86_CR0_TS|X86_CR0_EM); /* clear TS and EM */