return copy_uabi_to_xstate(xsave, NULL, ubuf);
 }
 
+static bool validate_xsaves_xrstors(u64 mask)
+{
+       u64 xchk;
+
+       if (WARN_ON_FPU(!cpu_feature_enabled(X86_FEATURE_XSAVES)))
+               return false;
+       /*
+        * Validate that this is either a task->fpstate related component
+        * subset or an independent one.
+        */
+       if (mask & xfeatures_mask_independent())
+               xchk = ~xfeatures_mask_independent();
+       else
+               xchk = ~xfeatures_mask_all;
+
+       if (WARN_ON_ONCE(!mask || mask & xchk))
+               return false;
+
+       return true;
+}
+
 /**
- * copy_independent_supervisor_to_kernel() - Save independent supervisor states to
- *                                           an xsave area
- * @xstate: A pointer to an xsave area
- * @mask: Represent the independent supervisor features saved into the xsave area
+ * xsaves - Save selected components to a kernel xstate buffer
+ * @xstate:    Pointer to the buffer
+ * @mask:      Feature mask to select the components to save
  *
- * Only the independent supervisor states sets in the mask are saved into the xsave
- * area (See the comment in XFEATURE_MASK_INDEPENDENT for the details of independent
- * supervisor feature). Besides the independent supervisor states, the legacy
- * region and XSAVE header are also saved into the xsave area. The supervisor
- * features in the XFEATURE_MASK_SUPERVISOR_SUPPORTED and
- * XFEATURE_MASK_SUPERVISOR_UNSUPPORTED are not saved.
+ * The @xstate buffer must be 64 byte aligned and correctly initialized as
+ * XSAVES does not write the full xstate header. Before first use the
+ * buffer should be zeroed otherwise a consecutive XRSTORS from that buffer
+ * can #GP.
  *
- * The xsave area must be 64-bytes aligned.
+ * The feature mask must either be a subset of the independent features or
+ * a subset of the task->fpstate related features.
  */
-void copy_independent_supervisor_to_kernel(struct xregs_state *xstate, u64 mask)
+void xsaves(struct xregs_state *xstate, u64 mask)
 {
-       u64 independent_mask = xfeatures_mask_independent() & mask;
-       u32 lmask, hmask;
        int err;
 
-       if (WARN_ON_FPU(!boot_cpu_has(X86_FEATURE_XSAVES)))
+       if (!validate_xsaves_xrstors(mask))
                return;
 
-       if (WARN_ON_FPU(!independent_mask))
-               return;
-
-       lmask = independent_mask;
-       hmask = independent_mask >> 32;
-
-       XSTATE_OP(XSAVES, xstate, lmask, hmask, err);
-
-       /* Should never fault when copying to a kernel buffer */
-       WARN_ON_FPU(err);
+       XSTATE_OP(XSAVES, xstate, (u32)mask, (u32)(mask >> 32), err);
+       WARN_ON_ONCE(err);
 }
 
 /**
- * copy_kernel_to_independent_supervisor() - Restore independent supervisor states from
- *                                           an xsave area
- * @xstate: A pointer to an xsave area
- * @mask: Represent the independent supervisor features restored from the xsave area
+ * xrstors - Restore selected components from a kernel xstate buffer
+ * @xstate:    Pointer to the buffer
+ * @mask:      Feature mask to select the components to restore
+ *
+ * The @xstate buffer must be 64 byte aligned and correctly initialized
+ * otherwise XRSTORS from that buffer can #GP.
  *
- * Only the independent supervisor states sets in the mask are restored from the
- * xsave area (See the comment in XFEATURE_MASK_INDEPENDENT for the details of
- * independent supervisor feature). Besides the independent supervisor states, the
- * legacy region and XSAVE header are also restored from the xsave area. The
- * supervisor features in the XFEATURE_MASK_SUPERVISOR_SUPPORTED and
- * XFEATURE_MASK_SUPERVISOR_UNSUPPORTED are not restored.
+ * Proper usage is to restore the state which was saved with
+ * xsaves() into @xstate.
  *
- * The xsave area must be 64-bytes aligned.
+ * The feature mask must either be a subset of the independent features or
+ * a subset of the task->fpstate related features.
  */
-void copy_kernel_to_independent_supervisor(struct xregs_state *xstate, u64 mask)
+void xrstors(struct xregs_state *xstate, u64 mask)
 {
-       u64 independent_mask = xfeatures_mask_independent() & mask;
-       u32 lmask, hmask;
        int err;
 
-       if (WARN_ON_FPU(!boot_cpu_has(X86_FEATURE_XSAVES)))
+       if (!validate_xsaves_xrstors(mask))
                return;
 
-       if (WARN_ON_FPU(!independent_mask))
-               return;
-
-       lmask = independent_mask;
-       hmask = independent_mask >> 32;
-
-       XSTATE_OP(XRSTORS, xstate, lmask, hmask, err);
-
-       /* Should never fault when copying from a kernel buffer */
-       WARN_ON_FPU(err);
+       XSTATE_OP(XRSTORS, xstate, (u32)mask, (u32)(mask >> 32), err);
+       WARN_ON_ONCE(err);
 }
 
 #ifdef CONFIG_PROC_PID_ARCH_STATUS