*     buf == buf_fx for 64-bit frames and 32-bit fsave frame.
  *     buf != buf_fx for 32-bit frames with fxstate.
  *
- * Save the state directly to the user frame pointed by the aligned pointer
- * 'buf_fx'.
+ * Save the state to task's fpu->state and then copy it to the user frame
+ * pointed to by the aligned pointer 'buf_fx'.
  *
  * If this is a 32-bit frame with fxstate, put a fsave header before
  * the aligned state at 'buf_fx'.
  */
 int copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size)
 {
+       struct fpu *fpu = ¤t->thread.fpu;
+       struct xregs_state *xsave = &fpu->state.xsave;
        struct task_struct *tsk = current;
        int ia32_fxstate = (buf != buf_fx);
 
                        sizeof(struct user_i387_ia32_struct), NULL,
                        (struct _fpstate_32 __user *) buf) ? -1 : 1;
 
-       /* Save the live registers state to the user frame directly. */
-       if (copy_fpregs_to_sigframe(buf_fx))
-               return -1;
+       copy_fpregs_to_fpstate(fpu);
+
+       if (using_compacted_format()) {
+               if (copy_xstate_to_user(buf_fx, xsave, 0, size))
+                       return -1;
+       } else {
+               fpstate_sanitize_xstate(fpu);
+               if (__copy_to_user(buf_fx, xsave, fpu_user_xstate_size))
+                       return -1;
+       }
 
        /* Save the fsave header for the 32-bit frames. */
        if ((ia32_fxstate || !use_fxsr()) && save_fsave_header(tsk, buf))