aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-11 22:15:52 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-01-15 18:28:53 -0500
commite23fe36a8cf5faa57d0c45868a3f7679c4f07cb0 (patch)
treed65d491b6c9f639cb6825ca44f929ef77ac0fc0f
parent7b2252e993e29974eb0d017156db989173ec31aa (diff)
x86, fpu, amd: Clear exceptions in AMD FXSAVE workaround
commit 26bef1318adc1b3a530ecc807ef99346db2aa8b0 upstream. Before we do an EMMS in the AMD FXSAVE information leak workaround we need to clear any pending exceptions, otherwise we trap with a floating-point exception inside this code. Reported-by: halfdog <me@halfdog.net> Tested-by: Borislav Petkov <bp@suse.de> Link: http://lkml.kernel.org/r/CA%2B55aFxQnY_PCG_n4=0w-VG=YLXL-yr7oMxyy0WU2gCBAf3ydg@mail.gmail.com Signed-off-by: H. Peter Anvin <hpa@zytor.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--arch/x86/include/asm/fpu-internal.h13
1 files changed, 7 insertions, 6 deletions
diff --git a/arch/x86/include/asm/fpu-internal.h b/arch/x86/include/asm/fpu-internal.h
index e25cc33ec54d..e72b2e41499e 100644
--- a/arch/x86/include/asm/fpu-internal.h
+++ b/arch/x86/include/asm/fpu-internal.h
@@ -295,12 +295,13 @@ static inline int restore_fpu_checking(struct task_struct *tsk)
295 /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception 295 /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception
296 is pending. Clear the x87 state here by setting it to fixed 296 is pending. Clear the x87 state here by setting it to fixed
297 values. "m" is a random variable that should be in L1 */ 297 values. "m" is a random variable that should be in L1 */
298 alternative_input( 298 if (unlikely(static_cpu_has(X86_FEATURE_FXSAVE_LEAK))) {
299 ASM_NOP8 ASM_NOP2, 299 asm volatile(
300 "emms\n\t" /* clear stack tags */ 300 "fnclex\n\t"
301 "fildl %P[addr]", /* set F?P to defined value */ 301 "emms\n\t"
302 X86_FEATURE_FXSAVE_LEAK, 302 "fildl %P[addr]" /* set F?P to defined value */
303 [addr] "m" (tsk->thread.fpu.has_fpu)); 303 : : [addr] "m" (tsk->thread.fpu.has_fpu));
304 }
304 305
305 return fpu_restore_checking(&tsk->thread.fpu); 306 return fpu_restore_checking(&tsk->thread.fpu);
306} 307}