|
[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 |