ia64/xen-unstable
changeset 3896:2d98340a3776
bitkeeper revision 1.1236.1.1 (421bba88ZaitlU4qEVN6Xp2WKaq8Vg)
FPU fixes.
Signed-off-by: Keir Fraser <keir@xensource.com>
FPU fixes.
Signed-off-by: Keir Fraser <keir@xensource.com>
author | kaf24@scramble.cl.cam.ac.uk |
---|---|
date | Tue Feb 22 23:04:40 2005 +0000 (2005-02-22) |
parents | 1e288d225372 |
children | 3d81ec6a75cd |
files | xen/arch/x86/i387.c xen/arch/x86/traps.c xen/include/asm-x86/i387.h |
line diff
1.1 --- a/xen/arch/x86/i387.c Tue Feb 22 15:04:00 2005 +0000 1.2 +++ b/xen/arch/x86/i387.c Tue Feb 22 23:04:40 2005 +0000 1.3 @@ -16,42 +16,43 @@ 1.4 1.5 void init_fpu(void) 1.6 { 1.7 - __asm__("fninit"); 1.8 - if ( cpu_has_xmm ) load_mxcsr(0x1f80); 1.9 + __asm__ __volatile__ ( "fninit" ); 1.10 + if ( cpu_has_xmm ) 1.11 + load_mxcsr(0x1f80); 1.12 set_bit(EDF_DONEFPUINIT, ¤t->ed_flags); 1.13 } 1.14 1.15 -static inline void __save_init_fpu( struct exec_domain *tsk ) 1.16 -{ 1.17 - if ( cpu_has_fxsr ) { 1.18 - asm volatile( "fxsave %0 ; fnclex" 1.19 - : "=m" (tsk->arch.i387) ); 1.20 - } else { 1.21 - asm volatile( "fnsave %0 ; fwait" 1.22 - : "=m" (tsk->arch.i387) ); 1.23 - } 1.24 - clear_bit(EDF_USEDFPU, &tsk->ed_flags); 1.25 -} 1.26 - 1.27 -void save_init_fpu( struct exec_domain *tsk ) 1.28 +void save_init_fpu(struct exec_domain *tsk) 1.29 { 1.30 /* 1.31 * The guest OS may have set the 'virtual STTS' flag. 1.32 * This causes us to set the real flag, so we'll need 1.33 * to temporarily clear it while saving f-p state. 1.34 */ 1.35 - if ( test_bit(EDF_GUEST_STTS, &tsk->ed_flags) ) clts(); 1.36 - __save_init_fpu(tsk); 1.37 + if ( test_bit(EDF_GUEST_STTS, &tsk->ed_flags) ) 1.38 + clts(); 1.39 + 1.40 + if ( cpu_has_fxsr ) 1.41 + __asm__ __volatile__ ( 1.42 + "fxsave %0 ; fnclex" 1.43 + : "=m" (tsk->arch.i387) ); 1.44 + else 1.45 + __asm__ __volatile__ ( 1.46 + "fnsave %0 ; fwait" 1.47 + : "=m" (tsk->arch.i387) ); 1.48 + 1.49 + clear_bit(EDF_USEDFPU, &tsk->ed_flags); 1.50 stts(); 1.51 } 1.52 1.53 -void restore_fpu( struct exec_domain *tsk ) 1.54 +void restore_fpu(struct exec_domain *tsk) 1.55 { 1.56 - if ( cpu_has_fxsr ) { 1.57 - asm volatile( "fxrstor %0" 1.58 - : : "m" (tsk->arch.i387) ); 1.59 - } else { 1.60 - asm volatile( "frstor %0" 1.61 - : : "m" (tsk->arch.i387) ); 1.62 - } 1.63 + if ( cpu_has_fxsr ) 1.64 + __asm__ __volatile__ ( 1.65 + "fxrstor %0" 1.66 + : : "m" (tsk->arch.i387) ); 1.67 + else 1.68 + __asm__ __volatile__ ( 1.69 + "frstor %0" 1.70 + : : "m" (tsk->arch.i387) ); 1.71 }
2.1 --- a/xen/arch/x86/traps.c Tue Feb 22 15:04:00 2005 +0000 2.2 +++ b/xen/arch/x86/traps.c Tue Feb 22 23:04:40 2005 +0000 2.3 @@ -371,7 +371,9 @@ static int emulate_privileged_op(struct 2.4 switch ( opcode ) 2.5 { 2.6 case 0x06: /* CLTS */ 2.7 - (void)do_fpu_taskswitch(); 2.8 + clear_bit(EDF_GUEST_STTS, &ed->ed_flags); 2.9 + if ( test_bit(EDF_USEDFPU, &ed->ed_flags) ) 2.10 + clts(); 2.11 break; 2.12 2.13 case 0x09: /* WBINVD */ 2.14 @@ -420,8 +422,8 @@ static int emulate_privileged_op(struct 2.15 switch ( (opcode >> 3) & 7 ) 2.16 { 2.17 case 0: /* Write CR0 */ 2.18 - if ( *reg & X86_CR0_TS ) /* XXX ignore all but TS bit */ 2.19 - (void)do_fpu_taskswitch; 2.20 + if ( *reg & X86_CR0_TS ) 2.21 + (void)do_fpu_taskswitch(); 2.22 break; 2.23 2.24 case 2: /* Write CR2 */
3.1 --- a/xen/include/asm-x86/i387.h Tue Feb 22 15:04:00 2005 +0000 3.2 +++ b/xen/include/asm-x86/i387.h Tue Feb 22 23:04:40 2005 +0000 3.3 @@ -15,24 +15,17 @@ 3.4 #include <asm/processor.h> 3.5 3.6 extern void init_fpu(void); 3.7 -extern void save_init_fpu( struct exec_domain *tsk ); 3.8 -extern void restore_fpu( struct exec_domain *tsk ); 3.9 +extern void save_init_fpu(struct exec_domain *tsk); 3.10 +extern void restore_fpu(struct exec_domain *tsk); 3.11 3.12 -#define unlazy_fpu( tsk ) do { \ 3.13 - if ( test_bit(EDF_USEDFPU, &tsk->ed_flags) ) \ 3.14 - save_init_fpu( tsk ); \ 3.15 -} while (0) 3.16 - 3.17 -#define clear_fpu( tsk ) do { \ 3.18 - if ( test_and_clear_bit(EDF_USEDFPU, &tsk->ed_flags) ) { \ 3.19 - asm volatile("fwait"); \ 3.20 - stts(); \ 3.21 - } \ 3.22 -} while (0) 3.23 +#define unlazy_fpu(_tsk) do { \ 3.24 + if ( test_bit(EDF_USEDFPU, &(_tsk)->ed_flags) ) \ 3.25 + save_init_fpu(_tsk); \ 3.26 +} while ( 0 ) 3.27 3.28 #define load_mxcsr( val ) do { \ 3.29 - unsigned long __mxcsr = ((unsigned long)(val) & 0xffbf); \ 3.30 - asm volatile( "ldmxcsr %0" : : "m" (__mxcsr) ); \ 3.31 -} while (0) 3.32 + unsigned long __mxcsr = ((unsigned long)(val) & 0xffbf); \ 3.33 + __asm__ __volatile__ ( "ldmxcsr %0" : : "m" (__mxcsr) ); \ 3.34 +} while ( 0 ) 3.35 3.36 #endif /* __ASM_I386_I387_H */