x86/fpu: Use a feature number instead of mask in two more helpers
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>
Wed, 3 Apr 2019 16:41:40 +0000 (18:41 +0200)
committerBorislav Petkov <bp@suse.de>
Wed, 10 Apr 2019 16:20:27 +0000 (18:20 +0200)
After changing the argument of __raw_xsave_addr() from a mask to
number Dave suggested to check if it makes sense to do the same for
get_xsave_addr(). As it turns out it does.

Only get_xsave_addr() needs the mask to check if the requested feature
is part of what is supported/saved and then uses the number again. The
shift operation is cheaper compared to fls64() (find last bit set).
Also, the feature number uses less opcode space compared to the mask. :)

Make the get_xsave_addr() argument a xfeature number instead of a mask
and fix up its callers.

Furthermore, use xfeature_nr and xfeature_mask consistently.

This results in the following changes to the kvm code:

  feature -> xfeature_mask
  index -> xfeature_nr

Suggested-by: Dave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Dave Hansen <dave.hansen@intel.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jann Horn <jannh@google.com>
Cc: "Jason A. Donenfeld" <Jason@zx2c4.com>
Cc: kvm ML <kvm@vger.kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: "Radim Krčmář" <rkrcmar@redhat.com>
Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Cc: Rik van Riel <riel@surriel.com>
Cc: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
Cc: Siarhei Liakh <Siarhei.Liakh@concurrent-rt.com>
Cc: x86-ml <x86@kernel.org>
Link: https://lkml.kernel.org/r/20190403164156.19645-12-bigeasy@linutronix.de
arch/x86/include/asm/fpu/xstate.h
arch/x86/kernel/fpu/xstate.c
arch/x86/kernel/traps.c
arch/x86/kvm/x86.c
arch/x86/mm/mpx.c

index 48581988d78c750e9216f21874e0eb1ac5f70a4f..fbe41f808e5d827baaaf78d36ada77424336c2e6 100644 (file)
@@ -46,8 +46,8 @@ extern void __init update_regset_xstate_info(unsigned int size,
                                             u64 xstate_mask);
 
 void fpu__xstate_clear_all_cpu_caps(void);
-void *get_xsave_addr(struct xregs_state *xsave, int xstate);
-const void *get_xsave_field_ptr(int xstate_field);
+void *get_xsave_addr(struct xregs_state *xsave, int xfeature_nr);
+const void *get_xsave_field_ptr(int xfeature_nr);
 int using_compacted_format(void);
 int copy_xstate_to_kernel(void *kbuf, struct xregs_state *xsave, unsigned int offset, unsigned int size);
 int copy_xstate_to_user(void __user *ubuf, struct xregs_state *xsave, unsigned int offset, unsigned int size);
index 4f7f3c5d0d0cff678d8fc903a90e6597a101f001..9c459fd1d38e6cbf0414dbbb0209fc9428bee92b 100644 (file)
@@ -830,15 +830,14 @@ static void *__raw_xsave_addr(struct xregs_state *xsave, int xfeature_nr)
  *
  * Inputs:
  *     xstate: the thread's storage area for all FPU data
- *     xstate_feature: state which is defined in xsave.h (e.g.
- *     XFEATURE_MASK_FP, XFEATURE_MASK_SSE, etc...)
+ *     xfeature_nr: state which is defined in xsave.h (e.g. XFEATURE_FP,
+ *     XFEATURE_SSE, etc...)
  * Output:
  *     address of the state in the xsave area, or NULL if the
  *     field is not present in the xsave buffer.
  */
-void *get_xsave_addr(struct xregs_state *xsave, int xstate_feature)
+void *get_xsave_addr(struct xregs_state *xsave, int xfeature_nr)
 {
-       int xfeature_nr;
        /*
         * Do we even *have* xsave state?
         */
@@ -850,11 +849,11 @@ void *get_xsave_addr(struct xregs_state *xsave, int xstate_feature)
         * have not enabled.  Remember that pcntxt_mask is
         * what we write to the XCR0 register.
         */
-       WARN_ONCE(!(xfeatures_mask & xstate_feature),
+       WARN_ONCE(!(xfeatures_mask & BIT_ULL(xfeature_nr)),
                  "get of unsupported state");
        /*
         * This assumes the last 'xsave*' instruction to
-        * have requested that 'xstate_feature' be saved.
+        * have requested that 'xfeature_nr' be saved.
         * If it did not, we might be seeing and old value
         * of the field in the buffer.
         *
@@ -863,10 +862,9 @@ void *get_xsave_addr(struct xregs_state *xsave, int xstate_feature)
         * or because the "init optimization" caused it
         * to not be saved.
         */
-       if (!(xsave->header.xfeatures & xstate_feature))
+       if (!(xsave->header.xfeatures & BIT_ULL(xfeature_nr)))
                return NULL;
 
-       xfeature_nr = fls64(xstate_feature) - 1;
        return __raw_xsave_addr(xsave, xfeature_nr);
 }
 EXPORT_SYMBOL_GPL(get_xsave_addr);
@@ -882,13 +880,13 @@ EXPORT_SYMBOL_GPL(get_xsave_addr);
  * Note that this only works on the current task.
  *
  * Inputs:
- *     @xsave_state: state which is defined in xsave.h (e.g. XFEATURE_MASK_FP,
- *     XFEATURE_MASK_SSE, etc...)
+ *     @xfeature_nr: state which is defined in xsave.h (e.g. XFEATURE_FP,
+ *     XFEATURE_SSE, etc...)
  * Output:
  *     address of the state in the xsave area or NULL if the state
  *     is not present or is in its 'init state'.
  */
-const void *get_xsave_field_ptr(int xsave_state)
+const void *get_xsave_field_ptr(int xfeature_nr)
 {
        struct fpu *fpu = &current->thread.fpu;
 
@@ -898,7 +896,7 @@ const void *get_xsave_field_ptr(int xsave_state)
         */
        fpu__save(fpu);
 
-       return get_xsave_addr(&fpu->state.xsave, xsave_state);
+       return get_xsave_addr(&fpu->state.xsave, xfeature_nr);
 }
 
 #ifdef CONFIG_ARCH_HAS_PKEYS
index d26f9e9c3d8308fbb17a8d2c826f002367b74a85..8b6d03e55d2f79888c0aa9740c51bc486d8fa05f 100644 (file)
@@ -456,7 +456,7 @@ dotraplinkage void do_bounds(struct pt_regs *regs, long error_code)
         * which is all zeros which indicates MPX was not
         * responsible for the exception.
         */
-       bndcsr = get_xsave_field_ptr(XFEATURE_MASK_BNDCSR);
+       bndcsr = get_xsave_field_ptr(XFEATURE_BNDCSR);
        if (!bndcsr)
                goto exit_trap;
 
index 099b851dabafd7e2980f96472209777f9cc8f77b..8022e7769b3a1967af8f9a8cb1180b3493628856 100644 (file)
@@ -3674,15 +3674,15 @@ static void fill_xsave(u8 *dest, struct kvm_vcpu *vcpu)
         */
        valid = xstate_bv & ~XFEATURE_MASK_FPSSE;
        while (valid) {
-               u64 feature = valid & -valid;
-               int index = fls64(feature) - 1;
-               void *src = get_xsave_addr(xsave, feature);
+               u64 xfeature_mask = valid & -valid;
+               int xfeature_nr = fls64(xfeature_mask) - 1;
+               void *src = get_xsave_addr(xsave, xfeature_nr);
 
                if (src) {
                        u32 size, offset, ecx, edx;
-                       cpuid_count(XSTATE_CPUID, index,
+                       cpuid_count(XSTATE_CPUID, xfeature_nr,
                                    &size, &offset, &ecx, &edx);
-                       if (feature == XFEATURE_MASK_PKRU)
+                       if (xfeature_nr == XFEATURE_PKRU)
                                memcpy(dest + offset, &vcpu->arch.pkru,
                                       sizeof(vcpu->arch.pkru));
                        else
@@ -3690,7 +3690,7 @@ static void fill_xsave(u8 *dest, struct kvm_vcpu *vcpu)
 
                }
 
-               valid -= feature;
+               valid -= xfeature_mask;
        }
 }
 
@@ -3717,22 +3717,22 @@ static void load_xsave(struct kvm_vcpu *vcpu, u8 *src)
         */
        valid = xstate_bv & ~XFEATURE_MASK_FPSSE;
        while (valid) {
-               u64 feature = valid & -valid;
-               int index = fls64(feature) - 1;
-               void *dest = get_xsave_addr(xsave, feature);
+               u64 xfeature_mask = valid & -valid;
+               int xfeature_nr = fls64(xfeature_mask) - 1;
+               void *dest = get_xsave_addr(xsave, xfeature_nr);
 
                if (dest) {
                        u32 size, offset, ecx, edx;
-                       cpuid_count(XSTATE_CPUID, index,
+                       cpuid_count(XSTATE_CPUID, xfeature_nr,
                                    &size, &offset, &ecx, &edx);
-                       if (feature == XFEATURE_MASK_PKRU)
+                       if (xfeature_nr == XFEATURE_PKRU)
                                memcpy(&vcpu->arch.pkru, src + offset,
                                       sizeof(vcpu->arch.pkru));
                        else
                                memcpy(dest, src + offset, size);
                }
 
-               valid -= feature;
+               valid -= xfeature_mask;
        }
 }
 
@@ -8850,11 +8850,11 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
                if (init_event)
                        kvm_put_guest_fpu(vcpu);
                mpx_state_buffer = get_xsave_addr(&vcpu->arch.guest_fpu->state.xsave,
-                                       XFEATURE_MASK_BNDREGS);
+                                       XFEATURE_BNDREGS);
                if (mpx_state_buffer)
                        memset(mpx_state_buffer, 0, sizeof(struct mpx_bndreg_state));
                mpx_state_buffer = get_xsave_addr(&vcpu->arch.guest_fpu->state.xsave,
-                                       XFEATURE_MASK_BNDCSR);
+                                       XFEATURE_BNDCSR);
                if (mpx_state_buffer)
                        memset(mpx_state_buffer, 0, sizeof(struct mpx_bndcsr));
                if (init_event)
index c805db6236b474bfdde03f4cd173863e7952d191..59726aaf46713fb1f08569dbb4167135b2a8cc29 100644 (file)
@@ -142,7 +142,7 @@ int mpx_fault_info(struct mpx_fault_info *info, struct pt_regs *regs)
                goto err_out;
        }
        /* get bndregs field from current task's xsave area */
-       bndregs = get_xsave_field_ptr(XFEATURE_MASK_BNDREGS);
+       bndregs = get_xsave_field_ptr(XFEATURE_BNDREGS);
        if (!bndregs) {
                err = -EINVAL;
                goto err_out;
@@ -190,7 +190,7 @@ static __user void *mpx_get_bounds_dir(void)
         * The bounds directory pointer is stored in a register
         * only accessible if we first do an xsave.
         */
-       bndcsr = get_xsave_field_ptr(XFEATURE_MASK_BNDCSR);
+       bndcsr = get_xsave_field_ptr(XFEATURE_BNDCSR);
        if (!bndcsr)
                return MPX_INVALID_BOUNDS_DIR;
 
@@ -376,7 +376,7 @@ static int do_mpx_bt_fault(void)
        const struct mpx_bndcsr *bndcsr;
        struct mm_struct *mm = current->mm;
 
-       bndcsr = get_xsave_field_ptr(XFEATURE_MASK_BNDCSR);
+       bndcsr = get_xsave_field_ptr(XFEATURE_BNDCSR);
        if (!bndcsr)
                return -EINVAL;
        /*