x86: make restore_fpu() use alternative assembler instructions
authorLinus Torvalds <torvalds@evo.osdl.org>
Fri, 22 Jul 2005 20:06:16 +0000 (16:06 -0400)
committerLinus Torvalds <torvalds@evo.osdl.org>
Fri, 22 Jul 2005 20:06:16 +0000 (16:06 -0400)
It's really just a single instruction, conditional on whether the CPU
supports FXSR or not, so implement it as such instead of making it a
function that queries FXSR dynamically.

This means that the instruction just gets automatically rewritten to the
correct one at boot-time.

arch/i386/kernel/i387.c
include/asm-i386/i387.h

index b817168d9c6210e4cfb55140b3543449c46dcfab..d75524758daf770811e029536f6730c8b5c0fa21 100644 (file)
@@ -82,17 +82,6 @@ void kernel_fpu_begin(void)
 }
 EXPORT_SYMBOL_GPL(kernel_fpu_begin);
 
 }
 EXPORT_SYMBOL_GPL(kernel_fpu_begin);
 
-void restore_fpu( struct task_struct *tsk )
-{
-       if ( cpu_has_fxsr ) {
-               asm volatile( "fxrstor %0"
-                             : : "m" (tsk->thread.i387.fxsave) );
-       } else {
-               asm volatile( "frstor %0"
-                             : : "m" (tsk->thread.i387.fsave) );
-       }
-}
-
 /*
  * FPU tag word conversions.
  */
 /*
  * FPU tag word conversions.
  */
index f6feb98a93972e7971662fbe09fec8f247e53fee..e678609bb57ead5c910b50b4e57bf11724ea74d8 100644 (file)
 
 extern void mxcsr_feature_mask_init(void);
 extern void init_fpu(struct task_struct *);
 
 extern void mxcsr_feature_mask_init(void);
 extern void init_fpu(struct task_struct *);
+
 /*
  * FPU lazy state save handling...
  */
 /*
  * FPU lazy state save handling...
  */
-extern void restore_fpu( struct task_struct *tsk );
+
+/*
+ * The "nop" is needed to make the instructions the same
+ * length.
+ */
+#define restore_fpu(tsk)                       \
+       alternative_input(                      \
+               "nop ; frstor %1",              \
+               "fxrstor %1",                   \
+               X86_FEATURE_FXSR,               \
+               "m" ((tsk)->thread.i387.fsave))
 
 extern void kernel_fpu_begin(void);
 #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0)
 
 extern void kernel_fpu_begin(void);
 #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0)