diff options
| -rw-r--r-- | arch/x86/kernel/i387.c | 12 | ||||
| -rw-r--r-- | include/asm-x86/i387.h | 10 |
2 files changed, 19 insertions, 3 deletions
diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c index db6839b53195..e03cc952f233 100644 --- a/arch/x86/kernel/i387.c +++ b/arch/x86/kernel/i387.c | |||
| @@ -450,7 +450,6 @@ static inline int restore_i387_fsave(struct _fpstate_ia32 __user *buf) | |||
| 450 | { | 450 | { |
| 451 | struct task_struct *tsk = current; | 451 | struct task_struct *tsk = current; |
| 452 | 452 | ||
| 453 | clear_fpu(tsk); | ||
| 454 | return __copy_from_user(&tsk->thread.xstate->fsave, buf, | 453 | return __copy_from_user(&tsk->thread.xstate->fsave, buf, |
| 455 | sizeof(struct i387_fsave_struct)); | 454 | sizeof(struct i387_fsave_struct)); |
| 456 | } | 455 | } |
| @@ -461,7 +460,6 @@ static int restore_i387_fxsave(struct _fpstate_ia32 __user *buf) | |||
| 461 | struct user_i387_ia32_struct env; | 460 | struct user_i387_ia32_struct env; |
| 462 | int err; | 461 | int err; |
| 463 | 462 | ||
| 464 | clear_fpu(tsk); | ||
| 465 | err = __copy_from_user(&tsk->thread.xstate->fxsave, &buf->_fxsr_env[0], | 463 | err = __copy_from_user(&tsk->thread.xstate->fxsave, &buf->_fxsr_env[0], |
| 466 | sizeof(struct i387_fxsave_struct)); | 464 | sizeof(struct i387_fxsave_struct)); |
| 467 | /* mxcsr reserved bits must be masked to zero for security reasons */ | 465 | /* mxcsr reserved bits must be masked to zero for security reasons */ |
| @@ -478,6 +476,16 @@ int restore_i387_ia32(struct _fpstate_ia32 __user *buf) | |||
| 478 | int err; | 476 | int err; |
| 479 | 477 | ||
| 480 | if (HAVE_HWFP) { | 478 | if (HAVE_HWFP) { |
| 479 | struct task_struct *tsk = current; | ||
| 480 | |||
| 481 | clear_fpu(tsk); | ||
| 482 | |||
| 483 | if (!used_math()) { | ||
| 484 | err = init_fpu(tsk); | ||
| 485 | if (err) | ||
| 486 | return err; | ||
| 487 | } | ||
| 488 | |||
| 481 | if (cpu_has_fxsr) | 489 | if (cpu_has_fxsr) |
| 482 | err = restore_i387_fxsave(buf); | 490 | err = restore_i387_fxsave(buf); |
| 483 | else | 491 | else |
diff --git a/include/asm-x86/i387.h b/include/asm-x86/i387.h index da2adb45f6e3..6b722d315936 100644 --- a/include/asm-x86/i387.h +++ b/include/asm-x86/i387.h | |||
| @@ -175,7 +175,15 @@ static inline int save_i387(struct _fpstate __user *buf) | |||
| 175 | */ | 175 | */ |
| 176 | static inline int restore_i387(struct _fpstate __user *buf) | 176 | static inline int restore_i387(struct _fpstate __user *buf) |
| 177 | { | 177 | { |
| 178 | set_used_math(); | 178 | struct task_struct *tsk = current; |
| 179 | int err; | ||
| 180 | |||
| 181 | if (!used_math()) { | ||
| 182 | err = init_fpu(tsk); | ||
| 183 | if (err) | ||
| 184 | return err; | ||
| 185 | } | ||
| 186 | |||
| 179 | if (!(task_thread_info(current)->status & TS_USEDFPU)) { | 187 | if (!(task_thread_info(current)->status & TS_USEDFPU)) { |
| 180 | clts(); | 188 | clts(); |
| 181 | task_thread_info(current)->status |= TS_USEDFPU; | 189 | task_thread_info(current)->status |= TS_USEDFPU; |
