diff options
author | Chuck Ebbert <76306.1226@compuserve.com> | 2006-04-29 14:07:49 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-04-29 17:13:16 -0400 |
commit | 543f2a3382bd7abd7380903518c61f00c7c87577 (patch) | |
tree | ca6dff499b29f40b5ff62aaaed48def6e4c81016 | |
parent | 693f7d362055261882659475d2ef022e32edbff1 (diff) |
[PATCH] i386: fix broken FP exception handling
The FXSAVE information leak patch introduced a bug in FP exception
handling: it clears FP exceptions only when there are already
none outstanding. Mikael Pettersson reported that causes problems
with the Erlang runtime and has tested this fix.
Signed-off-by: Chuck Ebbert <76306.1226@compuserve.com>
Acked-by: Mikael Pettersson <mikpe@it.uu.se>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | include/asm-i386/i387.h | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/include/asm-i386/i387.h b/include/asm-i386/i387.h index 7b1f01191e70..bc1d6edae1ed 100644 --- a/include/asm-i386/i387.h +++ b/include/asm-i386/i387.h | |||
@@ -58,13 +58,13 @@ static inline void __save_init_fpu( struct task_struct *tsk ) | |||
58 | alternative_input( | 58 | alternative_input( |
59 | "fnsave %[fx] ;fwait;" GENERIC_NOP8 GENERIC_NOP4, | 59 | "fnsave %[fx] ;fwait;" GENERIC_NOP8 GENERIC_NOP4, |
60 | "fxsave %[fx]\n" | 60 | "fxsave %[fx]\n" |
61 | "bt $7,%[fsw] ; jc 1f ; fnclex\n1:", | 61 | "bt $7,%[fsw] ; jnc 1f ; fnclex\n1:", |
62 | X86_FEATURE_FXSR, | 62 | X86_FEATURE_FXSR, |
63 | [fx] "m" (tsk->thread.i387.fxsave), | 63 | [fx] "m" (tsk->thread.i387.fxsave), |
64 | [fsw] "m" (tsk->thread.i387.fxsave.swd) : "memory"); | 64 | [fsw] "m" (tsk->thread.i387.fxsave.swd) : "memory"); |
65 | /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception | 65 | /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception |
66 | is pending. Clear the x87 state here by setting it to fixed | 66 | is pending. Clear the x87 state here by setting it to fixed |
67 | values. __per_cpu_offset[0] is a random variable that should be in L1 */ | 67 | values. safe_address is a random variable that should be in L1 */ |
68 | alternative_input( | 68 | alternative_input( |
69 | GENERIC_NOP8 GENERIC_NOP2, | 69 | GENERIC_NOP8 GENERIC_NOP2, |
70 | "emms\n\t" /* clear stack tags */ | 70 | "emms\n\t" /* clear stack tags */ |