[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 1/3] tests/x86emul: Helpers to save and restore FPU state
Introduce common helpers for saving and restoring FPU state. During emul_test_init(), calculate whether to use xsave or fxsave, and tweak the existing mxcsr_mask logic to avoid using another large static buffer. Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- CC: Jan Beulich <JBeulich@xxxxxxxx> --- tools/tests/x86_emulator/x86-emulate.c | 70 +++++++++++++++++++++++++++------- tools/tests/x86_emulator/x86-emulate.h | 4 ++ 2 files changed, 60 insertions(+), 14 deletions(-) diff --git a/tools/tests/x86_emulator/x86-emulate.c b/tools/tests/x86_emulator/x86-emulate.c index 9056610..47e503d 100644 --- a/tools/tests/x86_emulator/x86-emulate.c +++ b/tools/tests/x86_emulator/x86-emulate.c @@ -26,26 +26,68 @@ uint32_t mxcsr_mask = 0x0000ffbf; +static char fpu_save_area[4096] __attribute__((__aligned__((64)))); +static bool use_xsave; + +void emul_save_fpu_state(void) +{ + if ( use_xsave ) + asm volatile ( "xsave" __OS " %[ptr]" + : [ptr] "=m" (fpu_save_area) + : "a" (~0ull), "d" (~0ull) ); + else + asm volatile ( "fxsave %0" : "=m" (fpu_save_area) ); +} + +void emul_restore_fpu_state(void) +{ + if ( use_xsave ) + asm volatile ( "xrstor" __OS " %[ptr]" + :: [ptr] "m" (fpu_save_area), "a" (~0ull), "d" (~0ull) ); + else + asm volatile ( "fxrstor %0" :: "m" (fpu_save_area) ); +} + bool emul_test_init(void) { + union { + char x[464]; + struct { + uint32_t other[6]; + uint32_t mxcsr; + uint32_t mxcsr_mask; + /* ... */ + }; + } *fxs = (void *)fpu_save_area; + unsigned long sp; - if ( cpu_has_fxsr ) + if ( cpu_has_xsave ) { - static union __attribute__((__aligned__(16))) { - char x[464]; - struct { - uint32_t other[6]; - uint32_t mxcsr; - uint32_t mxcsr_mask; - /* ... */ - }; - } fxs; - - asm ( "fxsave %0" : "=m" (fxs) ); - if ( fxs.mxcsr_mask ) - mxcsr_mask = fxs.mxcsr_mask; + unsigned int tmp, ebx; + + asm ( "cpuid" + : "=a" (tmp), "=b" (ebx), "=c" (tmp), "=d" (tmp) + : "a" (0xd), "c" (0) ); + + /* + * Sanity check that fpu_save_area[] is large enough. This assertion + * will trip eventually, at which point fpu_save_area[] needs to get + * larger. + */ + assert(ebx < sizeof(fpu_save_area)); + + /* Use xsave if available... */ + use_xsave = true; } + else + /* But use fxsave if xsave isn't available. */ + assert(cpu_has_fxsr); + + /* Reuse the save state buffer to find mcxsr_mask. */ + asm ( "fxsave %0" : "=m" (*fxs) ); + if ( fxs->mxcsr_mask ) + mxcsr_mask = fxs->mxcsr_mask; /* * Mark the entire stack executable so that the stub executions diff --git a/tools/tests/x86_emulator/x86-emulate.h b/tools/tests/x86_emulator/x86-emulate.h index a1c4774..45acea4 100644 --- a/tools/tests/x86_emulator/x86-emulate.h +++ b/tools/tests/x86_emulator/x86-emulate.h @@ -52,6 +52,10 @@ extern uint32_t mxcsr_mask; #define MMAP_SZ 16384 bool emul_test_init(void); +/* Must save and restore FPU state between any call into libc. */ +void emul_save_fpu_state(void); +void emul_restore_fpu_state(void); + #include "x86_emulate/x86_emulate.h" static inline uint64_t xgetbv(uint32_t xcr) -- 2.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |