x86/pkru: Remove xstate fiddling from write_pkru()
authorThomas Gleixner <tglx@linutronix.de>
Wed, 23 Jun 2021 12:02:23 +0000 (14:02 +0200)
committerBorislav Petkov <bp@suse.de>
Wed, 23 Jun 2021 17:55:51 +0000 (19:55 +0200)
The PKRU value of a task is stored in task->thread.pkru when the task is
scheduled out. PKRU is restored on schedule in from there. So keeping the
XSAVE buffer up to date is a pointless exercise.

Remove the xstate fiddling and cleanup all related functions.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Borislav Petkov <bp@suse.de>
Link: https://lkml.kernel.org/r/20210623121456.897372712@linutronix.de
arch/x86/include/asm/pkru.h
arch/x86/include/asm/special_insns.h
arch/x86/kvm/x86.c

index 7e45509..ccc539f 100644 (file)
@@ -41,23 +41,14 @@ static inline u32 read_pkru(void)
 
 static inline void write_pkru(u32 pkru)
 {
-       struct pkru_state *pk;
-
        if (!cpu_feature_enabled(X86_FEATURE_OSPKE))
                return;
-
-       pk = get_xsave_addr(&current->thread.fpu.state.xsave, XFEATURE_PKRU);
-
        /*
-        * The PKRU value in xstate needs to be in sync with the value that is
-        * written to the CPU. The FPU restore on return to userland would
-        * otherwise load the previous value again.
+        * WRPKRU is relatively expensive compared to RDPKRU.
+        * Avoid WRPKRU when it would not change the value.
         */
-       fpregs_lock();
-       if (pk)
-               pk->pkru = pkru;
-       __write_pkru(pkru);
-       fpregs_unlock();
+       if (pkru != rdpkru())
+               wrpkru(pkru);
 }
 
 static inline void pkru_write_default(void)
index 2acd6cb..f3fbb84 100644 (file)
@@ -104,25 +104,13 @@ static inline void wrpkru(u32 pkru)
                     : : "a" (pkru), "c"(ecx), "d"(edx));
 }
 
-static inline void __write_pkru(u32 pkru)
-{
-       /*
-        * WRPKRU is relatively expensive compared to RDPKRU.
-        * Avoid WRPKRU when it would not change the value.
-        */
-       if (pkru == rdpkru())
-               return;
-
-       wrpkru(pkru);
-}
-
 #else
 static inline u32 rdpkru(void)
 {
        return 0;
 }
 
-static inline void __write_pkru(u32 pkru)
+static inline void wrpkru(u32 pkru)
 {
 }
 #endif
index 07f7888..8ee7add 100644 (file)
@@ -943,7 +943,7 @@ void kvm_load_guest_xsave_state(struct kvm_vcpu *vcpu)
            (kvm_read_cr4_bits(vcpu, X86_CR4_PKE) ||
             (vcpu->arch.xcr0 & XFEATURE_MASK_PKRU)) &&
            vcpu->arch.pkru != vcpu->arch.host_pkru)
-               __write_pkru(vcpu->arch.pkru);
+               write_pkru(vcpu->arch.pkru);
 }
 EXPORT_SYMBOL_GPL(kvm_load_guest_xsave_state);
 
@@ -957,7 +957,7 @@ void kvm_load_host_xsave_state(struct kvm_vcpu *vcpu)
             (vcpu->arch.xcr0 & XFEATURE_MASK_PKRU))) {
                vcpu->arch.pkru = rdpkru();
                if (vcpu->arch.pkru != vcpu->arch.host_pkru)
-                       __write_pkru(vcpu->arch.host_pkru);
+                       write_pkru(vcpu->arch.host_pkru);
        }
 
        if (kvm_read_cr4_bits(vcpu, X86_CR4_OSXSAVE)) {