Browse Source

Merge branch 'x86-fpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'x86-fpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86_64: fix incorrect comments
  x86: unify restore_fpu_checking
  x86_32: introduce restore_fpu_checking()
Linus Torvalds 16 years ago
parent
commit
5301e0de34
2 changed files with 16 additions and 20 deletions
  1. 15 16
      arch/x86/include/asm/i387.h
  2. 1 4
      arch/x86/kernel/traps.c

+ 15 - 16
arch/x86/include/asm/i387.h

@@ -67,7 +67,7 @@ static inline int fxrstor_checking(struct i387_fxsave_struct *fx)
 		     ".previous\n"
 		     ".previous\n"
 		     _ASM_EXTABLE(1b, 3b)
 		     _ASM_EXTABLE(1b, 3b)
 		     : [err] "=r" (err)
 		     : [err] "=r" (err)
-#if 0 /* See comment in __save_init_fpu() below. */
+#if 0 /* See comment in fxsave() below. */
 		     : [fx] "r" (fx), "m" (*fx), "0" (0));
 		     : [fx] "r" (fx), "m" (*fx), "0" (0));
 #else
 #else
 		     : [fx] "cdaSDb" (fx), "m" (*fx), "0" (0));
 		     : [fx] "cdaSDb" (fx), "m" (*fx), "0" (0));
@@ -75,14 +75,6 @@ static inline int fxrstor_checking(struct i387_fxsave_struct *fx)
 	return err;
 	return err;
 }
 }
 
 
-static inline int restore_fpu_checking(struct task_struct *tsk)
-{
-	if (task_thread_info(tsk)->status & TS_XSAVE)
-		return xrstor_checking(&tsk->thread.xstate->xsave);
-	else
-		return fxrstor_checking(&tsk->thread.xstate->fxsave);
-}
-
 /* AMD CPUs don't save/restore FDP/FIP/FOP unless an exception
 /* AMD CPUs don't save/restore FDP/FIP/FOP unless an exception
    is pending. Clear the x87 state here by setting it to fixed
    is pending. Clear the x87 state here by setting it to fixed
    values. The kernel data segment can be sometimes 0 and sometimes
    values. The kernel data segment can be sometimes 0 and sometimes
@@ -120,7 +112,7 @@ static inline int fxsave_user(struct i387_fxsave_struct __user *fx)
 		     ".previous\n"
 		     ".previous\n"
 		     _ASM_EXTABLE(1b, 3b)
 		     _ASM_EXTABLE(1b, 3b)
 		     : [err] "=r" (err), "=m" (*fx)
 		     : [err] "=r" (err), "=m" (*fx)
-#if 0 /* See comment in __fxsave_clear() below. */
+#if 0 /* See comment in fxsave() below. */
 		     : [fx] "r" (fx), "0" (0));
 		     : [fx] "r" (fx), "0" (0));
 #else
 #else
 		     : [fx] "cdaSDb" (fx), "0" (0));
 		     : [fx] "cdaSDb" (fx), "0" (0));
@@ -185,12 +177,9 @@ static inline void tolerant_fwait(void)
 	asm volatile("fnclex ; fwait");
 	asm volatile("fnclex ; fwait");
 }
 }
 
 
-static inline void restore_fpu(struct task_struct *tsk)
+/* perform fxrstor iff the processor has extended states, otherwise frstor */
+static inline int fxrstor_checking(struct i387_fxsave_struct *fx)
 {
 {
-	if (task_thread_info(tsk)->status & TS_XSAVE) {
-		xrstor_checking(&tsk->thread.xstate->xsave);
-		return;
-	}
 	/*
 	/*
 	 * The "nop" is needed to make the instructions the same
 	 * The "nop" is needed to make the instructions the same
 	 * length.
 	 * length.
@@ -199,7 +188,9 @@ static inline void restore_fpu(struct task_struct *tsk)
 		"nop ; frstor %1",
 		"nop ; frstor %1",
 		"fxrstor %1",
 		"fxrstor %1",
 		X86_FEATURE_FXSR,
 		X86_FEATURE_FXSR,
-		"m" (tsk->thread.xstate->fxsave));
+		"m" (*fx));
+
+	return 0;
 }
 }
 
 
 /* We need a safe address that is cheap to find and that is already
 /* We need a safe address that is cheap to find and that is already
@@ -262,6 +253,14 @@ end:
 
 
 #endif	/* CONFIG_X86_64 */
 #endif	/* CONFIG_X86_64 */
 
 
+static inline int restore_fpu_checking(struct task_struct *tsk)
+{
+	if (task_thread_info(tsk)->status & TS_XSAVE)
+		return xrstor_checking(&tsk->thread.xstate->xsave);
+	else
+		return fxrstor_checking(&tsk->thread.xstate->fxsave);
+}
+
 /*
 /*
  * Signal frame handlers...
  * Signal frame handlers...
  */
  */

+ 1 - 4
arch/x86/kernel/traps.c

@@ -839,9 +839,6 @@ asmlinkage void math_state_restore(void)
 	}
 	}
 
 
 	clts();				/* Allow maths ops (or we recurse) */
 	clts();				/* Allow maths ops (or we recurse) */
-#ifdef CONFIG_X86_32
-	restore_fpu(tsk);
-#else
 	/*
 	/*
 	 * Paranoid restore. send a SIGSEGV if we fail to restore the state.
 	 * Paranoid restore. send a SIGSEGV if we fail to restore the state.
 	 */
 	 */
@@ -850,7 +847,7 @@ asmlinkage void math_state_restore(void)
 		force_sig(SIGSEGV, tsk);
 		force_sig(SIGSEGV, tsk);
 		return;
 		return;
 	}
 	}
-#endif
+
 	thread->status |= TS_USEDFPU;	/* So we fnsave on switch_to() */
 	thread->status |= TS_USEDFPU;	/* So we fnsave on switch_to() */
 	tsk->fpu_counter++;
 	tsk->fpu_counter++;
 }
 }