Merge remote-tracking branch 'torvalds/master' into perf/core
[linux-2.6-microblaze.git] / arch / x86 / include / asm / fpu / internal.h
index 8d33ad8..fdee23e 100644 (file)
@@ -578,19 +578,19 @@ static inline void switch_fpu_finish(struct fpu *new_fpu)
         * PKRU state is switched eagerly because it needs to be valid before we
         * return to userland e.g. for a copy_to_user() operation.
         */
-       if (current->mm) {
+       if (!(current->flags & PF_KTHREAD)) {
+               /*
+                * If the PKRU bit in xsave.header.xfeatures is not set,
+                * then the PKRU component was in init state, which means
+                * XRSTOR will set PKRU to 0. If the bit is not set then
+                * get_xsave_addr() will return NULL because the PKRU value
+                * in memory is not valid. This means pkru_val has to be
+                * set to 0 and not to init_pkru_value.
+                */
                pk = get_xsave_addr(&new_fpu->state.xsave, XFEATURE_PKRU);
-               if (pk)
-                       pkru_val = pk->pkru;
+               pkru_val = pk ? pk->pkru : 0;
        }
        __write_pkru(pkru_val);
-
-       /*
-        * Expensive PASID MSR write will be avoided in update_pasid() because
-        * TIF_NEED_FPU_LOAD was set. And the PASID state won't be updated
-        * unless it's different from mm->pasid to reduce overhead.
-        */
-       update_pasid();
 }
 
 #endif /* _ASM_X86_FPU_INTERNAL_H */