x86/fpu: Get rid of copy_supervisor_to_kernel()
[linux-2.6-microblaze.git] / arch / x86 / kernel / fpu / xstate.c
index d0eef96..427977b 100644 (file)
@@ -59,19 +59,23 @@ static short xsave_cpuid_features[] __initdata = {
  * This represents the full set of bits that should ever be set in a kernel
  * XSAVE buffer, both supervisor and user xstates.
  */
-u64 xfeatures_mask_all __read_mostly;
+u64 xfeatures_mask_all __ro_after_init;
 
-static unsigned int xstate_offsets[XFEATURE_MAX] = { [ 0 ... XFEATURE_MAX - 1] = -1};
-static unsigned int xstate_sizes[XFEATURE_MAX]   = { [ 0 ... XFEATURE_MAX - 1] = -1};
-static unsigned int xstate_comp_offsets[XFEATURE_MAX] = { [ 0 ... XFEATURE_MAX - 1] = -1};
-static unsigned int xstate_supervisor_only_offsets[XFEATURE_MAX] = { [ 0 ... XFEATURE_MAX - 1] = -1};
+static unsigned int xstate_offsets[XFEATURE_MAX] __ro_after_init =
+       { [ 0 ... XFEATURE_MAX - 1] = -1};
+static unsigned int xstate_sizes[XFEATURE_MAX] __ro_after_init =
+       { [ 0 ... XFEATURE_MAX - 1] = -1};
+static unsigned int xstate_comp_offsets[XFEATURE_MAX] __ro_after_init =
+       { [ 0 ... XFEATURE_MAX - 1] = -1};
+static unsigned int xstate_supervisor_only_offsets[XFEATURE_MAX] __ro_after_init =
+       { [ 0 ... XFEATURE_MAX - 1] = -1};
 
 /*
  * The XSAVE area of kernel can be in standard or compacted format;
  * it is always in standard format for user mode. This is the user
  * mode standard format size used for signal and ptrace frames.
  */
-unsigned int fpu_user_xstate_size;
+unsigned int fpu_user_xstate_size __ro_after_init;
 
 /*
  * Return whether the system supports a given xfeature.
@@ -124,104 +128,14 @@ static bool xfeature_is_supervisor(int xfeature_nr)
        return ecx & 1;
 }
 
-/*
- * When executing XSAVEOPT (or other optimized XSAVE instructions), if
- * a processor implementation detects that an FPU state component is still
- * (or is again) in its initialized state, it may clear the corresponding
- * bit in the header.xfeatures field, and can skip the writeout of registers
- * to the corresponding memory layout.
- *
- * This means that when the bit is zero, the state component might still contain
- * some previous - non-initialized register state.
- *
- * Before writing xstate information to user-space we sanitize those components,
- * to always ensure that the memory layout of a feature will be in the init state
- * if the corresponding header bit is zero. This is to ensure that user-space doesn't
- * see some stale state in the memory layout during signal handling, debugging etc.
- */
-void fpstate_sanitize_xstate(struct fpu *fpu)
-{
-       struct fxregs_state *fx = &fpu->state.fxsave;
-       int feature_bit;
-       u64 xfeatures;
-
-       if (!use_xsaveopt())
-               return;
-
-       xfeatures = fpu->state.xsave.header.xfeatures;
-
-       /*
-        * None of the feature bits are in init state. So nothing else
-        * to do for us, as the memory layout is up to date.
-        */
-       if ((xfeatures & xfeatures_mask_all) == xfeatures_mask_all)
-               return;
-
-       /*
-        * FP is in init state
-        */
-       if (!(xfeatures & XFEATURE_MASK_FP)) {
-               fx->cwd = 0x37f;
-               fx->swd = 0;
-               fx->twd = 0;
-               fx->fop = 0;
-               fx->rip = 0;
-               fx->rdp = 0;
-               memset(fx->st_space, 0, sizeof(fx->st_space));
-       }
-
-       /*
-        * SSE is in init state
-        */
-       if (!(xfeatures & XFEATURE_MASK_SSE))
-               memset(fx->xmm_space, 0, sizeof(fx->xmm_space));
-
-       /*
-        * First two features are FPU and SSE, which above we handled
-        * in a special way already:
-        */
-       feature_bit = 0x2;
-       xfeatures = (xfeatures_mask_user() & ~xfeatures) >> 2;
-
-       /*
-        * Update all the remaining memory layouts according to their
-        * standard xstate layout, if their header bit is in the init
-        * state:
-        */
-       while (xfeatures) {
-               if (xfeatures & 0x1) {
-                       int offset = xstate_comp_offsets[feature_bit];
-                       int size = xstate_sizes[feature_bit];
-
-                       memcpy((void *)fx + offset,
-                              (void *)&init_fpstate.xsave + offset,
-                              size);
-               }
-
-               xfeatures >>= 1;
-               feature_bit++;
-       }
-}
-
 /*
  * Enable the extended processor state save/restore feature.
  * Called once per CPU onlining.
  */
 void fpu__init_cpu_xstate(void)
 {
-       u64 unsup_bits;
-
        if (!boot_cpu_has(X86_FEATURE_XSAVE) || !xfeatures_mask_all)
                return;
-       /*
-        * Unsupported supervisor xstates should not be found in
-        * the xfeatures mask.
-        */
-       unsup_bits = xfeatures_mask_all & XFEATURE_MASK_SUPERVISOR_UNSUPPORTED;
-       WARN_ONCE(unsup_bits, "x86/fpu: Found unsupported supervisor xstates: 0x%llx\n",
-                 unsup_bits);
-
-       xfeatures_mask_all &= ~XFEATURE_MASK_SUPERVISOR_UNSUPPORTED;
 
        cr4_set_bits(X86_CR4_OSXSAVE);
 
@@ -440,6 +354,25 @@ static void __init print_xstate_offset_size(void)
        }
 }
 
+/*
+ * All supported features have either init state all zeros or are
+ * handled in setup_init_fpu() individually. This is an explicit
+ * feature list and does not use XFEATURE_MASK*SUPPORTED to catch
+ * newly added supported features at build time and make people
+ * actually look at the init state for the new feature.
+ */
+#define XFEATURES_INIT_FPSTATE_HANDLED         \
+       (XFEATURE_MASK_FP |                     \
+        XFEATURE_MASK_SSE |                    \
+        XFEATURE_MASK_YMM |                    \
+        XFEATURE_MASK_OPMASK |                 \
+        XFEATURE_MASK_ZMM_Hi256 |              \
+        XFEATURE_MASK_Hi16_ZMM  |              \
+        XFEATURE_MASK_PKRU |                   \
+        XFEATURE_MASK_BNDREGS |                \
+        XFEATURE_MASK_BNDCSR |                 \
+        XFEATURE_MASK_PASID)
+
 /*
  * setup the xstate image representing the init state
  */
@@ -447,6 +380,10 @@ static void __init setup_init_fpu_buf(void)
 {
        static int on_boot_cpu __initdata = 1;
 
+       BUILD_BUG_ON((XFEATURE_MASK_USER_SUPPORTED |
+                     XFEATURE_MASK_SUPERVISOR_SUPPORTED) !=
+                    XFEATURES_INIT_FPSTATE_HANDLED);
+
        WARN_ON_FPU(!on_boot_cpu);
        on_boot_cpu = 0;
 
@@ -466,10 +403,22 @@ static void __init setup_init_fpu_buf(void)
        copy_kernel_to_xregs_booting(&init_fpstate.xsave);
 
        /*
-        * Dump the init state again. This is to identify the init state
-        * of any feature which is not represented by all zero's.
+        * All components are now in init state. Read the state back so
+        * that init_fpstate contains all non-zero init state. This only
+        * works with XSAVE, but not with XSAVEOPT and XSAVES because
+        * those use the init optimization which skips writing data for
+        * components in init state.
+        *
+        * XSAVE could be used, but that would require to reshuffle the
+        * data when XSAVES is available because XSAVES uses xstate
+        * compaction. But doing so is a pointless exercise because most
+        * components have an all zeros init state except for the legacy
+        * ones (FP and SSE). Those can be saved with FXSAVE into the
+        * legacy area. Adding new features requires to ensure that init
+        * state is all zeroes or if not to add the necessary handling
+        * here.
         */
-       copy_xregs_to_kernel_booting(&init_fpstate.xsave);
+       fxsave(&init_fpstate.fxsave);
 }
 
 static int xfeature_uncompacted_offset(int xfeature_nr)
@@ -500,22 +449,8 @@ int xfeature_size(int xfeature_nr)
        return eax;
 }
 
-/*
- * 'XSAVES' implies two different things:
- * 1. saving of supervisor/system state
- * 2. using the compacted format
- *
- * Use this function when dealing with the compacted format so
- * that it is obvious which aspect of 'XSAVES' is being handled
- * by the calling code.
- */
-int using_compacted_format(void)
-{
-       return boot_cpu_has(X86_FEATURE_XSAVES);
-}
-
 /* Validate an xstate header supplied by userspace (ptrace or sigreturn) */
-int validate_user_xstate_header(const struct xstate_header *hdr)
+static int validate_user_xstate_header(const struct xstate_header *hdr)
 {
        /* No unknown or supervisor features may be set */
        if (hdr->xfeatures & ~xfeatures_mask_user())
@@ -632,9 +567,9 @@ static void do_extra_xstate_size_checks(void)
                check_xstate_against_struct(i);
                /*
                 * Supervisor state components can be managed only by
-                * XSAVES, which is compacted-format only.
+                * XSAVES.
                 */
-               if (!using_compacted_format())
+               if (!cpu_feature_enabled(X86_FEATURE_XSAVES))
                        XSTATE_WARN_ON(xfeature_is_supervisor(i));
 
                /* Align from the end of the previous feature */
@@ -644,9 +579,9 @@ static void do_extra_xstate_size_checks(void)
                 * The offset of a given state in the non-compacted
                 * format is given to us in a CPUID leaf.  We check
                 * them for being ordered (increasing offsets) in
-                * setup_xstate_features().
+                * setup_xstate_features(). XSAVES uses compacted format.
                 */
-               if (!using_compacted_format())
+               if (!cpu_feature_enabled(X86_FEATURE_XSAVES))
                        paranoid_xstate_size = xfeature_uncompacted_offset(i);
                /*
                 * The compacted-format offset always depends on where
@@ -786,6 +721,7 @@ void __init fpu__init_system_xstate(void)
 {
        unsigned int eax, ebx, ecx, edx;
        static int on_boot_cpu __initdata = 1;
+       u64 xfeatures;
        int err;
        int i;
 
@@ -839,7 +775,11 @@ void __init fpu__init_system_xstate(void)
                        xfeatures_mask_all &= ~BIT_ULL(i);
        }
 
-       xfeatures_mask_all &= fpu__get_supported_xfeatures_mask();
+       xfeatures_mask_all &= XFEATURE_MASK_USER_SUPPORTED |
+                             XFEATURE_MASK_SUPERVISOR_SUPPORTED;
+
+       /* Store it for paranoia check at the end */
+       xfeatures = xfeatures_mask_all;
 
        /* Enable xstate instructions to be able to continue with initialization: */
        fpu__init_cpu_xstate();
@@ -857,8 +797,18 @@ void __init fpu__init_system_xstate(void)
        setup_init_fpu_buf();
        setup_xstate_comp_offsets();
        setup_supervisor_only_offsets();
-       print_xstate_offset_size();
 
+       /*
+        * Paranoia check whether something in the setup modified the
+        * xfeatures mask.
+        */
+       if (xfeatures != xfeatures_mask_all) {
+               pr_err("x86/fpu: xfeatures modified from 0x%016llx to 0x%016llx during init, disabling XSAVE\n",
+                      xfeatures, xfeatures_mask_all);
+               goto out_disable;
+       }
+
+       print_xstate_offset_size();
        pr_info("x86/fpu: Enabled xstate features 0x%llx, context size is %d bytes, using '%s' format.\n",
                xfeatures_mask_all,
                fpu_kernel_xstate_size,
@@ -955,36 +905,6 @@ void *get_xsave_addr(struct xregs_state *xsave, int xfeature_nr)
 }
 EXPORT_SYMBOL_GPL(get_xsave_addr);
 
-/*
- * This wraps up the common operations that need to occur when retrieving
- * data from xsave state.  It first ensures that the current task was
- * using the FPU and retrieves the data in to a buffer.  It then calculates
- * the offset of the requested field in the buffer.
- *
- * This function is safe to call whether the FPU is in use or not.
- *
- * Note that this only works on the current task.
- *
- * Inputs:
- *     @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 xfeature_nr)
-{
-       struct fpu *fpu = &current->thread.fpu;
-
-       /*
-        * fpu__save() takes the CPU's xstate registers
-        * and saves them off to the 'fpu memory buffer.
-        */
-       fpu__save(fpu);
-
-       return get_xsave_addr(&fpu->state.xsave, xfeature_nr);
-}
-
 #ifdef CONFIG_ARCH_HAS_PKEYS
 
 /*
@@ -992,11 +912,10 @@ const void *get_xsave_field_ptr(int xfeature_nr)
  * rights for @pkey to @init_val.
  */
 int arch_set_user_pkey_access(struct task_struct *tsk, int pkey,
-               unsigned long init_val)
+                             unsigned long init_val)
 {
-       u32 old_pkru;
-       int pkey_shift = (pkey * PKRU_BITS_PER_PKEY);
-       u32 new_pkru_bits = 0;
+       u32 old_pkru, new_pkru_bits = 0;
+       int pkey_shift;
 
        /*
         * This check implies XSAVE support.  OSPKE only gets
@@ -1010,7 +929,8 @@ int arch_set_user_pkey_access(struct task_struct *tsk, int pkey,
         * values originating from in-kernel users.  Complain
         * if a bad value is observed.
         */
-       WARN_ON_ONCE(pkey >= arch_max_pkey());
+       if (WARN_ON_ONCE(pkey >= arch_max_pkey()))
+               return -EINVAL;
 
        /* Set the bits we need in PKRU:  */
        if (init_val & PKEY_DISABLE_ACCESS)
@@ -1019,6 +939,7 @@ int arch_set_user_pkey_access(struct task_struct *tsk, int pkey,
                new_pkru_bits |= PKRU_WD_BIT;
 
        /* Shift the bits in to the correct place in PKRU for pkey: */
+       pkey_shift = pkey * PKRU_BITS_PER_PKEY;
        new_pkru_bits <<= pkey_shift;
 
        /* Get old PKRU and mask off any old bits in place: */
@@ -1049,83 +970,133 @@ static inline bool xfeatures_mxcsr_quirk(u64 xfeatures)
        return true;
 }
 
-static void fill_gap(struct membuf *to, unsigned *last, unsigned offset)
+static void copy_feature(bool from_xstate, struct membuf *to, void *xstate,
+                        void *init_xstate, unsigned int size)
 {
-       if (*last >= offset)
-               return;
-       membuf_write(to, (void *)&init_fpstate.xsave + *last, offset - *last);
-       *last = offset;
+       membuf_write(to, from_xstate ? xstate : init_xstate, size);
 }
 
-static void copy_part(struct membuf *to, unsigned *last, unsigned offset,
-                     unsigned size, void *from)
-{
-       fill_gap(to, last, offset);
-       membuf_write(to, from, size);
-       *last = offset + size;
-}
-
-/*
- * Convert from kernel XSAVES compacted format to standard format and copy
- * to a kernel-space ptrace buffer.
+/**
+ * copy_xstate_to_uabi_buf - Copy kernel saved xstate to a UABI buffer
+ * @to:                membuf descriptor
+ * @xsave:     The kernel xstate buffer to copy from
+ * @copy_mode: The requested copy mode
+ *
+ * Converts from kernel XSAVE or XSAVES compacted format to UABI conforming
+ * format, i.e. from the kernel internal hardware dependent storage format
+ * to the requested @mode. UABI XSTATE is always uncompacted!
  *
- * It supports partial copy but pos always starts from zero. This is called
- * from xstateregs_get() and there we check the CPU has XSAVES.
+ * It supports partial copy but @to.pos always starts from zero.
  */
-void copy_xstate_to_kernel(struct membuf to, struct xregs_state *xsave)
+void copy_xstate_to_uabi_buf(struct membuf to, struct xregs_state *xsave,
+                            enum xstate_copy_mode copy_mode)
 {
+       const unsigned int off_mxcsr = offsetof(struct fxregs_state, mxcsr);
+       struct xregs_state *xinit = &init_fpstate.xsave;
        struct xstate_header header;
-       const unsigned off_mxcsr = offsetof(struct fxregs_state, mxcsr);
-       unsigned size = to.left;
-       unsigned last = 0;
+       unsigned int zerofrom;
        int i;
 
-       /*
-        * The destination is a ptrace buffer; we put in only user xstates:
-        */
-       memset(&header, 0, sizeof(header));
        header.xfeatures = xsave->header.xfeatures;
-       header.xfeatures &= xfeatures_mask_user();
-
-       if (header.xfeatures & XFEATURE_MASK_FP)
-               copy_part(&to, &last, 0, off_mxcsr, &xsave->i387);
-       if (header.xfeatures & (XFEATURE_MASK_SSE | XFEATURE_MASK_YMM))
-               copy_part(&to, &last, off_mxcsr,
-                         MXCSR_AND_FLAGS_SIZE, &xsave->i387.mxcsr);
-       if (header.xfeatures & XFEATURE_MASK_FP)
-               copy_part(&to, &last, offsetof(struct fxregs_state, st_space),
-                         128, &xsave->i387.st_space);
-       if (header.xfeatures & XFEATURE_MASK_SSE)
-               copy_part(&to, &last, xstate_offsets[XFEATURE_SSE],
-                         256, &xsave->i387.xmm_space);
-       /*
-        * Fill xsave->i387.sw_reserved value for ptrace frame:
-        */
-       copy_part(&to, &last, offsetof(struct fxregs_state, sw_reserved),
-                 48, xstate_fx_sw_bytes);
-       /*
-        * Copy xregs_state->header:
-        */
-       copy_part(&to, &last, offsetof(struct xregs_state, header),
-                 sizeof(header), &header);
+
+       /* Mask out the feature bits depending on copy mode */
+       switch (copy_mode) {
+       case XSTATE_COPY_FP:
+               header.xfeatures &= XFEATURE_MASK_FP;
+               break;
+
+       case XSTATE_COPY_FX:
+               header.xfeatures &= XFEATURE_MASK_FP | XFEATURE_MASK_SSE;
+               break;
+
+       case XSTATE_COPY_XSAVE:
+               header.xfeatures &= xfeatures_mask_user();
+               break;
+       }
+
+       /* Copy FP state up to MXCSR */
+       copy_feature(header.xfeatures & XFEATURE_MASK_FP, &to, &xsave->i387,
+                    &xinit->i387, off_mxcsr);
+
+       /* Copy MXCSR when SSE or YMM are set in the feature mask */
+       copy_feature(header.xfeatures & (XFEATURE_MASK_SSE | XFEATURE_MASK_YMM),
+                    &to, &xsave->i387.mxcsr, &xinit->i387.mxcsr,
+                    MXCSR_AND_FLAGS_SIZE);
+
+       /* Copy the remaining FP state */
+       copy_feature(header.xfeatures & XFEATURE_MASK_FP,
+                    &to, &xsave->i387.st_space, &xinit->i387.st_space,
+                    sizeof(xsave->i387.st_space));
+
+       /* Copy the SSE state - shared with YMM, but independently managed */
+       copy_feature(header.xfeatures & XFEATURE_MASK_SSE,
+                    &to, &xsave->i387.xmm_space, &xinit->i387.xmm_space,
+                    sizeof(xsave->i387.xmm_space));
+
+       if (copy_mode != XSTATE_COPY_XSAVE)
+               goto out;
+
+       /* Zero the padding area */
+       membuf_zero(&to, sizeof(xsave->i387.padding));
+
+       /* Copy xsave->i387.sw_reserved */
+       membuf_write(&to, xstate_fx_sw_bytes, sizeof(xsave->i387.sw_reserved));
+
+       /* Copy the user space relevant state of @xsave->header */
+       membuf_write(&to, &header, sizeof(header));
+
+       zerofrom = offsetof(struct xregs_state, extended_state_area);
 
        for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
                /*
-                * Copy only in-use xstates:
+                * The ptrace buffer is in non-compacted XSAVE format.
+                * In non-compacted format disabled features still occupy
+                * state space, but there is no state to copy from in the
+                * compacted init_fpstate. The gap tracking will zero this
+                * later.
                 */
-               if ((header.xfeatures >> i) & 1) {
-                       void *src = __raw_xsave_addr(xsave, i);
+               if (!(xfeatures_mask_user() & BIT_ULL(i)))
+                       continue;
 
-                       copy_part(&to, &last, xstate_offsets[i],
-                                 xstate_sizes[i], src);
-               }
+               /*
+                * If there was a feature or alignment gap, zero the space
+                * in the destination buffer.
+                */
+               if (zerofrom < xstate_offsets[i])
+                       membuf_zero(&to, xstate_offsets[i] - zerofrom);
+
+               copy_feature(header.xfeatures & BIT_ULL(i), &to,
+                            __raw_xsave_addr(xsave, i),
+                            __raw_xsave_addr(xinit, i),
+                            xstate_sizes[i]);
 
+               /*
+                * Keep track of the last copied state in the non-compacted
+                * target buffer for gap zeroing.
+                */
+               zerofrom = xstate_offsets[i] + xstate_sizes[i];
        }
-       fill_gap(&to, &last, size);
+
+out:
+       if (to.left)
+               membuf_zero(&to, to.left);
+}
+
+static inline bool mxcsr_valid(struct xstate_header *hdr, const u32 *mxcsr)
+{
+       u64 mask = XFEATURE_MASK_FP | XFEATURE_MASK_SSE | XFEATURE_MASK_YMM;
+
+       /* Only check if it is in use */
+       if (hdr->xfeatures & mask) {
+               /* Reserved bits in MXCSR must be zero. */
+               if (*mxcsr & ~mxcsr_feature_mask)
+                       return false;
+       }
+       return true;
 }
 
 /*
- * Convert from a ptrace standard-format kernel buffer to kernel XSAVES format
+ * Convert from a ptrace standard-format kernel buffer to kernel XSAVE[S] format
  * and copy to the target thread. This is called from xstateregs_set().
  */
 int copy_kernel_to_xstate(struct xregs_state *xsave, const void *kbuf)
@@ -1142,6 +1113,9 @@ int copy_kernel_to_xstate(struct xregs_state *xsave, const void *kbuf)
        if (validate_user_xstate_header(&hdr))
                return -EINVAL;
 
+       if (!mxcsr_valid(&hdr, kbuf + offsetof(struct fxregs_state, mxcsr)))
+               return -EINVAL;
+
        for (i = 0; i < XFEATURE_MAX; i++) {
                u64 mask = ((u64)1 << i);
 
@@ -1176,10 +1150,9 @@ int copy_kernel_to_xstate(struct xregs_state *xsave, const void *kbuf)
 }
 
 /*
- * Convert from a ptrace or sigreturn standard-format user-space buffer to
- * kernel XSAVES format and copy to the target thread. This is called from
- * xstateregs_set(), as well as potentially from the sigreturn() and
- * rt_sigreturn() system calls.
+ * Convert from a sigreturn standard-format user-space buffer to kernel
+ * XSAVE[S] format and copy to the target thread. This is called from the
+ * sigreturn() and rt_sigreturn() system calls.
  */
 int copy_user_to_xstate(struct xregs_state *xsave, const void __user *ubuf)
 {
@@ -1190,7 +1163,7 @@ int copy_user_to_xstate(struct xregs_state *xsave, const void __user *ubuf)
        offset = offsetof(struct xregs_state, header);
        size = sizeof(hdr);
 
-       if (__copy_from_user(&hdr, ubuf + offset, size))
+       if (copy_from_user(&hdr, ubuf + offset, size))
                return -EFAULT;
 
        if (validate_user_xstate_header(&hdr))
@@ -1205,7 +1178,7 @@ int copy_user_to_xstate(struct xregs_state *xsave, const void __user *ubuf)
                        offset = xstate_offsets[i];
                        size = xstate_sizes[i];
 
-                       if (__copy_from_user(dst, ubuf + offset, size))
+                       if (copy_from_user(dst, ubuf + offset, size))
                                return -EFAULT;
                }
        }
@@ -1213,7 +1186,7 @@ int copy_user_to_xstate(struct xregs_state *xsave, const void __user *ubuf)
        if (xfeatures_mxcsr_quirk(hdr.xfeatures)) {
                offset = offsetof(struct fxregs_state, mxcsr);
                size = MXCSR_AND_FLAGS_SIZE;
-               if (__copy_from_user(&xsave->i387.mxcsr, ubuf + offset, size))
+               if (copy_from_user(&xsave->i387.mxcsr, ubuf + offset, size))
                        return -EFAULT;
        }
 
@@ -1231,61 +1204,6 @@ int copy_user_to_xstate(struct xregs_state *xsave, const void __user *ubuf)
        return 0;
 }
 
-/*
- * Save only supervisor states to the kernel buffer.  This blows away all
- * old states, and is intended to be used only in __fpu__restore_sig(), where
- * user states are restored from the user buffer.
- */
-void copy_supervisor_to_kernel(struct xregs_state *xstate)
-{
-       struct xstate_header *header;
-       u64 max_bit, min_bit;
-       u32 lmask, hmask;
-       int err, i;
-
-       if (WARN_ON(!boot_cpu_has(X86_FEATURE_XSAVES)))
-               return;
-
-       if (!xfeatures_mask_supervisor())
-               return;
-
-       max_bit = __fls(xfeatures_mask_supervisor());
-       min_bit = __ffs(xfeatures_mask_supervisor());
-
-       lmask = xfeatures_mask_supervisor();
-       hmask = xfeatures_mask_supervisor() >> 32;
-       XSTATE_OP(XSAVES, xstate, lmask, hmask, err);
-
-       /* We should never fault when copying to a kernel buffer: */
-       if (WARN_ON_FPU(err))
-               return;
-
-       /*
-        * At this point, the buffer has only supervisor states and must be
-        * converted back to normal kernel format.
-        */
-       header = &xstate->header;
-       header->xcomp_bv |= xfeatures_mask_all;
-
-       /*
-        * This only moves states up in the buffer.  Start with
-        * the last state and move backwards so that states are
-        * not overwritten until after they are moved.  Note:
-        * memmove() allows overlapping src/dst buffers.
-        */
-       for (i = max_bit; i >= min_bit; i--) {
-               u8 *xbuf = (u8 *)xstate;
-
-               if (!((header->xfeatures >> i) & 1))
-                       continue;
-
-               /* Move xfeature 'i' into its normal location */
-               memmove(xbuf + xstate_comp_offsets[i],
-                       xbuf + xstate_supervisor_only_offsets[i],
-                       xstate_sizes[i]);
-       }
-}
-
 /**
  * copy_dynamic_supervisor_to_kernel() - Save dynamic supervisor states to
  *                                       an xsave area