Skip to content

Commit c12b9a3

Browse files
amlutoZhengShunQian
authored andcommitted
x86/fpu: Fix FNSAVE usage in eagerfpu mode
commit 5ed73f4 upstream. In eager fpu mode, having deactivated FPU without immediately reloading some other context is illegal. Therefore, to recover from FNSAVE, we can't just deactivate the state -- we need to reload it if we're not actively context switching. We had this wrong in fpu__save() and fpu__copy(). Fix both. __kernel_fpu_begin() was fine -- add a comment. This fixes a warning triggerable with nofxsr eagerfpu=on. Signed-off-by: Andy Lutomirski <[email protected]> Cc: Andy Lutomirski <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Dave Hansen <[email protected]> Cc: Fenghua Yu <[email protected]> Cc: H. Peter Anvin <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Oleg Nesterov <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Quentin Casasnovas <[email protected]> Cc: Rik van Riel <[email protected]> Cc: Sai Praneeth Prakhya <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: yu-cheng yu <[email protected]> Link: http://lkml.kernel.org/r/60662444e13c76f06e23c15c5dcdba31b4ac3d67.1453675014.git.luto@kernel.org Signed-off-by: Ingo Molnar <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent d01e7a4 commit c12b9a3

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

arch/x86/kernel/fpu/core.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ void __kernel_fpu_begin(void)
114114
kernel_fpu_disable();
115115

116116
if (fpu->fpregs_active) {
117+
/*
118+
* Ignore return value -- we don't care if reg state
119+
* is clobbered.
120+
*/
117121
copy_fpregs_to_fpstate(fpu);
118122
} else {
119123
this_cpu_write(fpu_fpregs_owner_ctx, NULL);
@@ -189,8 +193,12 @@ void fpu__save(struct fpu *fpu)
189193

190194
preempt_disable();
191195
if (fpu->fpregs_active) {
192-
if (!copy_fpregs_to_fpstate(fpu))
193-
fpregs_deactivate(fpu);
196+
if (!copy_fpregs_to_fpstate(fpu)) {
197+
if (use_eager_fpu())
198+
copy_kernel_to_fpregs(&fpu->state);
199+
else
200+
fpregs_deactivate(fpu);
201+
}
194202
}
195203
preempt_enable();
196204
}
@@ -259,7 +267,11 @@ static void fpu_copy(struct fpu *dst_fpu, struct fpu *src_fpu)
259267
preempt_disable();
260268
if (!copy_fpregs_to_fpstate(dst_fpu)) {
261269
memcpy(&src_fpu->state, &dst_fpu->state, xstate_size);
262-
fpregs_deactivate(src_fpu);
270+
271+
if (use_eager_fpu())
272+
copy_kernel_to_fpregs(&src_fpu->state);
273+
else
274+
fpregs_deactivate(src_fpu);
263275
}
264276
preempt_enable();
265277
}

0 commit comments

Comments
 (0)