[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 2/3] tests/x86emul: Save and restore FPU state in the emulator callbacks
Currently with then native toolchain on Debian Jessie ./test_x86_emulator yeilds: Testing AVX2 256bit single native execution...okay Testing AVX2 256bit single 64-bit code sequence...[line 933] failed! The bug is that libc's memcpy() in read() uses %xmm8 (specifically, in __memcpy_sse2_unaligned()), which corrupts %ymm8 behind the back of the AVX2 test code. Switch all hooks to use "goto out" style returns, and use emul_{save,restore}_fpu_state(). Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- CC: Jan Beulich <JBeulich@xxxxxxxx> --- tools/tests/x86_emulator/test_x86_emulator.c | 94 +++++++++++++++++++++++----- 1 file changed, 79 insertions(+), 15 deletions(-) diff --git a/tools/tests/x86_emulator/test_x86_emulator.c b/tools/tests/x86_emulator/test_x86_emulator.c index 625cd2a..a764d99 100644 --- a/tools/tests/x86_emulator/test_x86_emulator.c +++ b/tools/tests/x86_emulator/test_x86_emulator.c @@ -226,6 +226,10 @@ static int read( unsigned int bytes, struct x86_emulate_ctxt *ctxt) { + int rc = X86EMUL_OKAY; + + emul_save_fpu_state(); + if ( verbose ) printf("** %s(%u, %p,, %u,)\n", __func__, seg, (void *)offset, bytes); @@ -236,42 +240,61 @@ static int read( case x86_seg_gdtr: /* Fake system segment type matching table index. */ if ( (offset & 7) || (bytes > 8) ) - return X86EMUL_UNHANDLEABLE; + { + rc = X86EMUL_UNHANDLEABLE; + goto out; + } #ifdef __x86_64__ if ( !(offset & 8) ) { memset(p_data, 0, bytes); - return X86EMUL_OKAY; + goto out; } value = (offset - 8) >> 4; #else value = (offset - 8) >> 3; #endif if ( value >= 0x10 ) - return X86EMUL_UNHANDLEABLE; + { + rc = X86EMUL_UNHANDLEABLE; + goto out; + } value |= value << 40; memcpy(p_data, &value, bytes); - return X86EMUL_OKAY; + goto out; case x86_seg_ldtr: /* Fake user segment type matching table index. */ if ( (offset & 7) || (bytes > 8) ) - return X86EMUL_UNHANDLEABLE; + { + rc = X86EMUL_UNHANDLEABLE; + goto out; + } value = offset >> 3; if ( value >= 0x10 ) - return X86EMUL_UNHANDLEABLE; + { + rc = X86EMUL_UNHANDLEABLE; + goto out; + } value |= (value | 0x10) << 40; memcpy(p_data, &value, bytes); - return X86EMUL_OKAY; + goto out; default: if ( !is_x86_user_segment(seg) ) - return X86EMUL_UNHANDLEABLE; + { + rc = X86EMUL_UNHANDLEABLE; + goto out; + } bytes_read += bytes; break; } memcpy(p_data, (void *)offset, bytes); - return X86EMUL_OKAY; + + out: + emul_restore_fpu_state(); + + return rc; } static int fetch( @@ -281,10 +304,15 @@ static int fetch( unsigned int bytes, struct x86_emulate_ctxt *ctxt) { + emul_save_fpu_state(); + if ( verbose ) printf("** %s(%u, %p,, %u,)\n", __func__, seg, (void *)offset, bytes); memcpy(p_data, (void *)offset, bytes); + + emul_restore_fpu_state(); + return X86EMUL_OKAY; } @@ -295,13 +323,25 @@ static int write( unsigned int bytes, struct x86_emulate_ctxt *ctxt) { + int rc = X86EMUL_OKAY; + + emul_save_fpu_state(); + if ( verbose ) printf("** %s(%u, %p,, %u,)\n", __func__, seg, (void *)offset, bytes); if ( !is_x86_user_segment(seg) ) - return X86EMUL_UNHANDLEABLE; + { + rc = X86EMUL_UNHANDLEABLE; + goto out; + } + memcpy((void *)offset, p_data, bytes); - return X86EMUL_OKAY; + + out: + emul_restore_fpu_state(); + + return rc; } static int cmpxchg( @@ -312,13 +352,25 @@ static int cmpxchg( unsigned int bytes, struct x86_emulate_ctxt *ctxt) { + int rc = X86EMUL_OKAY; + + emul_save_fpu_state(); + if ( verbose ) printf("** %s(%u, %p,, %u,)\n", __func__, seg, (void *)offset, bytes); if ( !is_x86_user_segment(seg) ) - return X86EMUL_UNHANDLEABLE; + { + rc = X86EMUL_UNHANDLEABLE; + goto out; + } + memcpy((void *)offset, new, bytes); - return X86EMUL_OKAY; + + out: + emul_restore_fpu_state(); + + return rc; } static int read_segment( @@ -326,11 +378,23 @@ static int read_segment( struct segment_register *reg, struct x86_emulate_ctxt *ctxt) { + int rc = X86EMUL_OKAY; + + emul_save_fpu_state(); + if ( !is_x86_user_segment(seg) ) - return X86EMUL_UNHANDLEABLE; + { + rc = X86EMUL_UNHANDLEABLE; + goto out; + } + memset(reg, 0, sizeof(*reg)); reg->p = 1; - return X86EMUL_OKAY; + + out: + emul_restore_fpu_state(); + + return rc; } static int read_msr( -- 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 |