diff --git a/arch/x86/kernel/i387_64.c b/arch/x86/kernel/i387_64.c index 56c1f11471099103292b5aa291a388113d27fa9b..bfaff28fb1348f41f14b7caadf363ca86879595e 100644 --- a/arch/x86/kernel/i387_64.c +++ b/arch/x86/kernel/i387_64.c @@ -92,13 +92,14 @@ int save_i387(struct _fpstate __user *buf) if (task_thread_info(tsk)->status & TS_USEDFPU) { err = save_i387_checking((struct i387_fxsave_struct __user *)buf); if (err) return err; + task_thread_info(tsk)->status &= ~TS_USEDFPU; stts(); - } else { - if (__copy_to_user(buf, &tsk->thread.i387.fxsave, + } else { + if (__copy_to_user(buf, &tsk->thread.i387.fxsave, sizeof(struct i387_fxsave_struct))) return -1; - } - return 1; + } + return 1; } /* diff --git a/include/asm-x86/i387_64.h b/include/asm-x86/i387_64.h index 0217b74cc9fc0cd30456d40929e6196229680178..3a4ffba3d6bcf2c30bbad9e6cd7f87cce8a165ba 100644 --- a/include/asm-x86/i387_64.h +++ b/include/asm-x86/i387_64.h @@ -203,6 +203,11 @@ static inline void save_init_fpu(struct task_struct *tsk) */ static inline int restore_i387(struct _fpstate __user *buf) { + set_used_math(); + if (!(task_thread_info(current)->status & TS_USEDFPU)) { + clts(); + task_thread_info(current)->status |= TS_USEDFPU; + } return restore_fpu_checking((__force struct i387_fxsave_struct *)buf); }