diff options
author | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2005-02-22 23:04:40 +0000 |
---|---|---|
committer | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2005-02-22 23:04:40 +0000 |
commit | 4ddaeb24b5eb996bba6b05e69b5c6584fb1fcc3f (patch) | |
tree | 7f48fbce691000f79d9d9f5ea2e941a75235c0ea | |
parent | 2a022479a2cf44b2de5b79bc1865d7224eb79d0c (diff) | |
download | xen-4ddaeb24b5eb996bba6b05e69b5c6584fb1fcc3f.tar.gz xen-4ddaeb24b5eb996bba6b05e69b5c6584fb1fcc3f.tar.bz2 xen-4ddaeb24b5eb996bba6b05e69b5c6584fb1fcc3f.zip |
bitkeeper revision 1.1236.1.1 (421bba88ZaitlU4qEVN6Xp2WKaq8Vg)
FPU fixes.
Signed-off-by: Keir Fraser <keir@xensource.com>
-rw-r--r-- | xen/arch/x86/i387.c | 51 | ||||
-rw-r--r-- | xen/arch/x86/traps.c | 8 | ||||
-rw-r--r-- | xen/include/asm-x86/i387.h | 25 |
3 files changed, 40 insertions, 44 deletions
diff --git a/xen/arch/x86/i387.c b/xen/arch/x86/i387.c index 902da0b57f..5aa6b59707 100644 --- a/xen/arch/x86/i387.c +++ b/xen/arch/x86/i387.c @@ -16,42 +16,43 @@ void init_fpu(void) { - __asm__("fninit"); - if ( cpu_has_xmm ) load_mxcsr(0x1f80); + __asm__ __volatile__ ( "fninit" ); + if ( cpu_has_xmm ) + load_mxcsr(0x1f80); set_bit(EDF_DONEFPUINIT, ¤t->ed_flags); } -static inline void __save_init_fpu( struct exec_domain *tsk ) -{ - if ( cpu_has_fxsr ) { - asm volatile( "fxsave %0 ; fnclex" - : "=m" (tsk->arch.i387) ); - } else { - asm volatile( "fnsave %0 ; fwait" - : "=m" (tsk->arch.i387) ); - } - clear_bit(EDF_USEDFPU, &tsk->ed_flags); -} - -void save_init_fpu( struct exec_domain *tsk ) +void save_init_fpu(struct exec_domain *tsk) { /* * The guest OS may have set the 'virtual STTS' flag. * This causes us to set the real flag, so we'll need * to temporarily clear it while saving f-p state. */ - if ( test_bit(EDF_GUEST_STTS, &tsk->ed_flags) ) clts(); - __save_init_fpu(tsk); + if ( test_bit(EDF_GUEST_STTS, &tsk->ed_flags) ) + clts(); + + if ( cpu_has_fxsr ) + __asm__ __volatile__ ( + "fxsave %0 ; fnclex" + : "=m" (tsk->arch.i387) ); + else + __asm__ __volatile__ ( + "fnsave %0 ; fwait" + : "=m" (tsk->arch.i387) ); + + clear_bit(EDF_USEDFPU, &tsk->ed_flags); stts(); } -void restore_fpu( struct exec_domain *tsk ) +void restore_fpu(struct exec_domain *tsk) { - if ( cpu_has_fxsr ) { - asm volatile( "fxrstor %0" - : : "m" (tsk->arch.i387) ); - } else { - asm volatile( "frstor %0" - : : "m" (tsk->arch.i387) ); - } + if ( cpu_has_fxsr ) + __asm__ __volatile__ ( + "fxrstor %0" + : : "m" (tsk->arch.i387) ); + else + __asm__ __volatile__ ( + "frstor %0" + : : "m" (tsk->arch.i387) ); } diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 26cf436e07..8a3aa56de8 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -371,7 +371,9 @@ static int emulate_privileged_op(struct xen_regs *regs) switch ( opcode ) { case 0x06: /* CLTS */ - (void)do_fpu_taskswitch(); + clear_bit(EDF_GUEST_STTS, &ed->ed_flags); + if ( test_bit(EDF_USEDFPU, &ed->ed_flags) ) + clts(); break; case 0x09: /* WBINVD */ @@ -420,8 +422,8 @@ static int emulate_privileged_op(struct xen_regs *regs) switch ( (opcode >> 3) & 7 ) { case 0: /* Write CR0 */ - if ( *reg & X86_CR0_TS ) /* XXX ignore all but TS bit */ - (void)do_fpu_taskswitch; + if ( *reg & X86_CR0_TS ) + (void)do_fpu_taskswitch(); break; case 2: /* Write CR2 */ diff --git a/xen/include/asm-x86/i387.h b/xen/include/asm-x86/i387.h index a09422d74f..9f6bb78b90 100644 --- a/xen/include/asm-x86/i387.h +++ b/xen/include/asm-x86/i387.h @@ -15,24 +15,17 @@ #include <asm/processor.h> extern void init_fpu(void); -extern void save_init_fpu( struct exec_domain *tsk ); -extern void restore_fpu( struct exec_domain *tsk ); +extern void save_init_fpu(struct exec_domain *tsk); +extern void restore_fpu(struct exec_domain *tsk); -#define unlazy_fpu( tsk ) do { \ - if ( test_bit(EDF_USEDFPU, &tsk->ed_flags) ) \ - save_init_fpu( tsk ); \ -} while (0) - -#define clear_fpu( tsk ) do { \ - if ( test_and_clear_bit(EDF_USEDFPU, &tsk->ed_flags) ) { \ - asm volatile("fwait"); \ - stts(); \ - } \ -} while (0) +#define unlazy_fpu(_tsk) do { \ + if ( test_bit(EDF_USEDFPU, &(_tsk)->ed_flags) ) \ + save_init_fpu(_tsk); \ +} while ( 0 ) #define load_mxcsr( val ) do { \ - unsigned long __mxcsr = ((unsigned long)(val) & 0xffbf); \ - asm volatile( "ldmxcsr %0" : : "m" (__mxcsr) ); \ -} while (0) + unsigned long __mxcsr = ((unsigned long)(val) & 0xffbf); \ + __asm__ __volatile__ ( "ldmxcsr %0" : : "m" (__mxcsr) ); \ +} while ( 0 ) #endif /* __ASM_I386_I387_H */ |