EXPORT_SYMBOL_GPL(fpu__activate_curr);
 
 /*
- * This function must be called before we modify a stopped child's
- * fpstate.
+ * This function must be called before we read or write a task's fpstate.
  *
- * If the child has not used the FPU before then initialize its
+ * If the task has not used the FPU before then initialize its
  * fpstate.
  *
- * If the child has used the FPU before then unlazy it.
+ * If the task has used the FPU before then save and unlazy it.
  *
- * [ After this function call, after registers in the fpstate are
+ * [ If this function is used for non-current child tasks, then
+ *   after this function call, after registers in the fpstate are
  *   modified and the child task has woken up, the child task will
  *   restore the modified FPU state from the modified context. If we
  *   didn't clear its lazy status here then the lazy in-registers
  *   state pending on its former CPU could be restored, corrupting
- *   the modifications. ]
+ *   the modifications.
  *
- * This function is also called before we read a stopped child's
- * FPU state - to make sure it's initialized if the child has
- * no active FPU state.
+ *   This function can be used for the current task as well, but
+ *   only for reading the fpstate. Modifications to the fpstate
+ *   will be lost on eagerfpu systems. ]
  *
  * TODO: A future optimization would be to skip the unlazying in
  *       the read-only case, it's not strictly necessary for
  *       read-only access to the context.
  */
-void fpu__activate_stopped(struct fpu *child_fpu)
+void fpu__activate_fpstate(struct fpu *fpu)
 {
-       WARN_ON_FPU(child_fpu == ¤t->thread.fpu);
-
-       if (child_fpu->fpstate_active) {
-               child_fpu->last_cpu = -1;
+       /*
+        * If fpregs are active (in the current CPU), then
+        * copy them to the fpstate:
+        */
+       if (fpu->fpregs_active) {
+               fpu__save(fpu);
        } else {
-               fpstate_init(&child_fpu->state);
-
-               /* Safe to do for stopped child tasks: */
-               child_fpu->fpstate_active = 1;
+               if (fpu->fpstate_active) {
+                       /* Invalidate any lazy state: */
+                       fpu->last_cpu = -1;
+               } else {
+                       fpstate_init(&fpu->state);
+
+                       /* Safe to do for current and for stopped child tasks: */
+                       fpu->fpstate_active = 1;
+               }
        }
 }
 
 
        if (!cpu_has_fxsr)
                return -ENODEV;
 
-       fpu__activate_stopped(fpu);
+       fpu__activate_fpstate(fpu);
        fpstate_sanitize_xstate(fpu);
 
        return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
        if (!cpu_has_fxsr)
                return -ENODEV;
 
-       fpu__activate_stopped(fpu);
+       fpu__activate_fpstate(fpu);
        fpstate_sanitize_xstate(fpu);
 
        ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
        if (!cpu_has_xsave)
                return -ENODEV;
 
-       fpu__activate_stopped(fpu);
+       fpu__activate_fpstate(fpu);
 
        xsave = &fpu->state.xsave;
 
        if (!cpu_has_xsave)
                return -ENODEV;
 
-       fpu__activate_stopped(fpu);
+       fpu__activate_fpstate(fpu);
 
        xsave = &fpu->state.xsave;
 
        struct fpu *fpu = &target->thread.fpu;
        struct user_i387_ia32_struct env;
 
-       fpu__activate_stopped(fpu);
+       fpu__activate_fpstate(fpu);
 
        if (!static_cpu_has(X86_FEATURE_FPU))
                return fpregs_soft_get(target, regset, pos, count, kbuf, ubuf);
        struct user_i387_ia32_struct env;
        int ret;
 
-       fpu__activate_stopped(fpu);
+       fpu__activate_fpstate(fpu);
        fpstate_sanitize_xstate(fpu);
 
        if (!static_cpu_has(X86_FEATURE_FPU))