[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] x86emul/test: wrap libc functions with FPU save/restore code
Currently with the native tool chain on Debian Jessie ./test_x86_emulator yields: 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. Introduce wrappers (and machinery to forward calls to those wrappers) saving/restoring FPU state around certain library calls. Reported-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> --- Obviously requires Andrew's "tests/x86emul: Helpers to save and restore FPU state" as a prereq. --- a/tools/fuzz/x86_instruction_emulator/Makefile +++ b/tools/fuzz/x86_instruction_emulator/Makefile @@ -18,7 +18,7 @@ asm: asm/%: asm ; -x86-emulate.c x86-emulate.h: %: +x86-emulate.c x86-emulate.h wrappers.c: %: [ -L $* ] || ln -sf $(XEN_ROOT)/tools/tests/x86_emulator/$* CFLAGS += $(CFLAGS_xeninclude) -D__XEN_TOOLS__ -I. @@ -38,10 +38,10 @@ fuzz-emul.o fuzz-emulate-cov.o: $(x86_em x86-insn-fuzzer.a: fuzz-emul.o x86-emulate.o $(AR) rc $@ $^ -afl-harness: afl-harness.o fuzz-emul.o x86-emulate.o +afl-harness: afl-harness.o fuzz-emul.o x86-emulate.o wrappers.o $(CC) $(CFLAGS) $^ -o $@ -afl-harness-cov: afl-harness-cov.o fuzz-emul-cov.o x86-emulate-cov.o +afl-harness-cov: afl-harness-cov.o fuzz-emul-cov.o x86-emulate-cov.o wrappers.o $(CC) $(CFLAGS) $(GCOV_FLAGS) $^ -o $@ # Common targets --- a/tools/tests/x86_emulator/Makefile +++ b/tools/tests/x86_emulator/Makefile @@ -103,7 +103,7 @@ $(addsuffix .o,$(SIMD) $(FMA) $(SG)): si xop.o: simd-fma.c -$(TARGET): x86-emulate.o test_x86_emulator.o +$(TARGET): x86-emulate.o test_x86_emulator.o wrappers.o $(HOSTCC) $(HOSTCFLAGS) -o $@ $^ .PHONY: clean @@ -133,8 +133,10 @@ HOSTCFLAGS += $(CFLAGS_xeninclude) -I. $ x86.h := asm/x86-vendors.h asm/x86-defns.h asm/msr-index.h x86_emulate.h := x86-emulate.h x86_emulate/x86_emulate.h $(x86.h) -x86-emulate.o: x86-emulate.c x86_emulate/x86_emulate.c $(x86_emulate.h) - $(HOSTCC) $(HOSTCFLAGS) -D__XEN_TOOLS__ -c -g -o $@ $< - -test_x86_emulator.o: test_x86_emulator.c $(addsuffix .h,$(TESTCASES)) $(x86_emulate.h) +x86-emulate.o test_x86_emulator.o wrappers.o: %.o: %.c $(x86_emulate.h) $(HOSTCC) $(HOSTCFLAGS) -c -g -o $@ $< + +x86-emulate.o: x86_emulate/x86_emulate.c +x86-emulate.o: HOSTCFLAGS += -D__XEN_TOOLS__ + +test_x86_emulator.o: $(addsuffix .h,$(TESTCASES)) --- /dev/null +++ b/tools/tests/x86_emulator/wrappers.c @@ -0,0 +1,79 @@ +#include <stdarg.h> +#include <stdio.h> + +#define WRAP(x) typeof(x) emul_##x +#include "x86-emulate.h" + +size_t emul_fwrite(const void *src, size_t sz, size_t n, FILE *f) +{ + emul_save_fpu_state(); + sz = fwrite(src, sz, n, f); + emul_restore_fpu_state(); + + return sz; +} + +int emul_memcmp(const void *p1, const void *p2, size_t sz) +{ + int rc; + + emul_save_fpu_state(); + rc = memcmp(p1, p2, sz); + emul_restore_fpu_state(); + + return rc; +} + +void *emul_memcpy(void *dst, const void *src, size_t sz) +{ + emul_save_fpu_state(); + memcpy(dst, src, sz); + emul_restore_fpu_state(); + + return dst; +} + +void *emul_memset(void *dst, int c, size_t sz) +{ + emul_save_fpu_state(); + memset(dst, c, sz); + emul_restore_fpu_state(); + + return dst; +} + +int emul_printf(const char *fmt, ...) +{ + va_list varg; + int rc; + + emul_save_fpu_state(); + va_start(varg, fmt); + rc = vprintf(fmt, varg); + va_end(varg); + emul_restore_fpu_state(); + + return rc; +} + +int emul_putchar(int c) +{ + int rc; + + emul_save_fpu_state(); + rc = putchar(c); + emul_restore_fpu_state(); + + return rc; +} + +int emul_puts(const char *str) +{ + int rc; + + emul_save_fpu_state(); + rc = puts(str); + emul_restore_fpu_state(); + + return rc; +} --- a/tools/tests/x86_emulator/x86-emulate.h +++ b/tools/tests/x86_emulator/x86-emulate.h @@ -56,6 +56,29 @@ bool emul_test_init(void); void emul_save_fpu_state(void); void emul_restore_fpu_state(void); +/* + * In order to reasonably use the above, wrap library calls we use and which we + * think might access any of the FPU state into wrappers saving/restoring state + * around the actual function. + */ +#ifndef WRAP +# if 0 /* This only works for explicit calls, not for compiler generated ones. */ +# define WRAP(x) typeof(x) x asm("emul_" #x) +# else +# define WRAP(x) asm(".equ " #x ", emul_" #x) +# endif +#endif + +WRAP(fwrite); +WRAP(memcmp); +WRAP(memcpy); +WRAP(memset); +WRAP(printf); +WRAP(putchar); +WRAP(puts); + +#undef WRAP + #include "x86_emulate/x86_emulate.h" static inline uint64_t xgetbv(uint32_t xcr) _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |