]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - arch/x86/kernel/i387.c
x86/fpu: Load xsave pointer *after* initialization
[karo-tx-linux.git] / arch / x86 / kernel / i387.c
index 03cc0add869478ee03b3fa475745d9702cd6706c..009183276bb738fbd28805256ccfaa04e063c364 100644 (file)
@@ -13,6 +13,7 @@
 #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>
@@ -67,7 +68,7 @@ static inline bool interrupted_kernel_fpu_idle(void)
 static inline bool interrupted_user_mode(void)
 {
        struct pt_regs *regs = get_irq_regs();
-       return regs && user_mode_vm(regs);
+       return regs && user_mode(regs);
 }
 
 /*
@@ -107,7 +108,7 @@ void __kernel_fpu_end(void)
 
        if (__thread_has_fpu(me)) {
                if (WARN_ON(restore_fpu_checking(me)))
-                       drop_init_fpu(me);
+                       fpu_reset_state(me);
        } else if (!use_eager_fpu()) {
                stts();
        }
@@ -197,7 +198,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 */
@@ -224,11 +225,12 @@ void fpu_finit(struct fpu *fpu)
                return;
        }
 
+       memset(fpu->state, 0, xstate_size);
+
        if (cpu_has_fxsr) {
                fx_finit(&fpu->state->fxsave);
        } else {
                struct i387_fsave_struct *fp = &fpu->state->fsave;
-               memset(fp, 0, xstate_size);
                fp->cwd = 0xffff037fu;
                fp->swd = 0xffff0000u;
                fp->twd = 0xffffffffu;
@@ -339,7 +341,7 @@ int xstateregs_get(struct task_struct *target, const struct user_regset *regset,
                unsigned int pos, unsigned int count,
                void *kbuf, void __user *ubuf)
 {
-       struct xsave_struct *xsave = &target->thread.fpu.state->xsave;
+       struct xsave_struct *xsave;
        int ret;
 
        if (!cpu_has_xsave)
@@ -349,6 +351,8 @@ int xstateregs_get(struct task_struct *target, const struct user_regset *regset,
        if (ret)
                return ret;
 
+       xsave = &target->thread.fpu.state->xsave;
+
        /*
         * Copy the 48bytes defined by the software first into the xstate
         * memory layout in the thread struct, so that we can copy the entire
@@ -367,7 +371,7 @@ int xstateregs_set(struct task_struct *target, const struct user_regset *regset,
                  unsigned int pos, unsigned int count,
                  const void *kbuf, const void __user *ubuf)
 {
-       struct xsave_struct *xsave = &target->thread.fpu.state->xsave;
+       struct xsave_struct *xsave;
        int ret;
 
        if (!cpu_has_xsave)
@@ -377,6 +381,8 @@ int xstateregs_set(struct task_struct *target, const struct user_regset *regset,
        if (ret)
                return ret;
 
+       xsave = &target->thread.fpu.state->xsave;
+
        ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, xsave, 0, -1);
        /*
         * mxcsr reserved bits must be masked to zero for security reasons.