diff options
Diffstat (limited to 'arch/x86/kernel/i387.c')
-rw-r--r-- | arch/x86/kernel/i387.c | 12 |
1 files changed, 10 insertions, 2 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 |