diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-11 19:15:52 -0800 |
---|---|---|
committer | Stefan Bader <stefan.bader@canonical.com> | 2014-05-20 16:35:12 +0200 |
commit | a4b163fa217bde1c2c6c658193e17f4f41ce5d1f (patch) | |
tree | ad94eabd3bc8a3970f2c90ea78b4626b04466ad3 | |
parent | 522ac9d28e7823d0312c931ad4521473f2226adf (diff) | |
download | linux-2.6.32.y-drm33.z-a4b163fa217bde1c2c6c658193e17f4f41ce5d1f.tar.gz |
x86, fpu, amd: Clear exceptions in AMD FXSAVE workaround
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>
(cherry picked from commit 26bef1318adc1b3a530ecc807ef99346db2aa8b0)
[wt: in 2.6.32, patch applies to arch/x86/include/asm/i387.h. There's
no static_cpu_has() so we use boot_cpu_has() like other kernels do
with gcc3.
]
Signed-off-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
-rw-r--r-- | arch/x86/include/asm/i387.h | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/arch/x86/include/asm/i387.h b/arch/x86/include/asm/i387.h index 0b20bbb758f265..cb42fad1f6fde5 100644 --- a/arch/x86/include/asm/i387.h +++ b/arch/x86/include/asm/i387.h @@ -242,12 +242,13 @@ clear_state: /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception is pending. Clear the x87 state here by setting it to fixed values. safe_address is a random variable that should be in L1 */ - alternative_input( - GENERIC_NOP8 GENERIC_NOP2, - "emms\n\t" /* clear stack tags */ - "fildl %[addr]", /* set F?P to defined value */ - X86_FEATURE_FXSAVE_LEAK, - [addr] "m" (safe_address)); + if (unlikely(boot_cpu_has(X86_FEATURE_FXSAVE_LEAK))) { + asm volatile( + "fnclex\n\t" + "emms\n\t" + "fildl %[addr]" /* set F?P to defined value */ + : : [addr] "m" (safe_address)); + } end: task_thread_info(tsk)->status &= ~TS_USEDFPU; } |