aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSiddha, Suresh B <suresh.b.siddha@intel.com>2007-11-11 14:27:59 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-11-12 14:09:33 -0500
commit92d140e21f1ce8cf99320afbbcad73879128e6dc (patch)
tree54a67ee106da78b2a5f265e8e12fc84b92e763d6
parentefe44183f6bab5b8acb6a6182d95274978c8abb1 (diff)
x86: fix taking DNA during 64bit sigreturn
restore sigcontext is taking a DNA exception while restoring FP context from the user stack, during the sigreturn. Appended patch fixes it by doing clts() if the app doesn't touch FP during the signal handler execution. This will stop generating a DNA, during the fxrstor in the sigreturn. This improves 64-bit lat_sig numbers by ~30% on my core2 platform. Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--arch/x86/kernel/i387_64.c9
-rw-r--r--include/asm-x86/i387_64.h5
2 files changed, 10 insertions, 4 deletions
diff --git a/arch/x86/kernel/i387_64.c b/arch/x86/kernel/i387_64.c
index 56c1f1147109..bfaff28fb134 100644
--- a/arch/x86/kernel/i387_64.c
+++ b/arch/x86/kernel/i387_64.c
@@ -92,13 +92,14 @@ int save_i387(struct _fpstate __user *buf)
92 if (task_thread_info(tsk)->status & TS_USEDFPU) { 92 if (task_thread_info(tsk)->status & TS_USEDFPU) {
93 err = save_i387_checking((struct i387_fxsave_struct __user *)buf); 93 err = save_i387_checking((struct i387_fxsave_struct __user *)buf);
94 if (err) return err; 94 if (err) return err;
95 task_thread_info(tsk)->status &= ~TS_USEDFPU;
95 stts(); 96 stts();
96 } else { 97 } else {
97 if (__copy_to_user(buf, &tsk->thread.i387.fxsave, 98 if (__copy_to_user(buf, &tsk->thread.i387.fxsave,
98 sizeof(struct i387_fxsave_struct))) 99 sizeof(struct i387_fxsave_struct)))
99 return -1; 100 return -1;
100 } 101 }
101 return 1; 102 return 1;
102} 103}
103 104
104/* 105/*
diff --git a/include/asm-x86/i387_64.h b/include/asm-x86/i387_64.h
index 0217b74cc9fc..3a4ffba3d6bc 100644
--- a/include/asm-x86/i387_64.h
+++ b/include/asm-x86/i387_64.h
@@ -203,6 +203,11 @@ static inline void save_init_fpu(struct task_struct *tsk)
203 */ 203 */
204static inline int restore_i387(struct _fpstate __user *buf) 204static inline int restore_i387(struct _fpstate __user *buf)
205{ 205{
206 set_used_math();
207 if (!(task_thread_info(current)->status & TS_USEDFPU)) {
208 clts();
209 task_thread_info(current)->status |= TS_USEDFPU;
210 }
206 return restore_fpu_checking((__force struct i387_fxsave_struct *)buf); 211 return restore_fpu_checking((__force struct i387_fxsave_struct *)buf);
207} 212}
208 213