tools/x86emul: Use struct cpuid_policy in the userspace test harnesses

This will shortly be required to pass into the emulator itself.

Simplify the shared cpu_has_* helpers by reading the correct bit out of the
CPUID policy itself.

No (intended) change in behaviour.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
Andrew Cooper committed 2018-11-12 18:07:16 +00:00
1 parent c66ef0fbe1
commit fd35f32b4b
4 files changed
+55 -184

No files matched your search

+6 -3
View File
@@ -8,6 +8,9 @@ else
x86-insn-fuzz-all:
endif
# Add libx86 to the build
vpath %.c $(XEN_ROOT)/xen/lib/x86
x86_emulate:
[ -L $@ ] || ln -sf $(XEN_ROOT)/xen/arch/x86/$@
@@ -31,13 +34,13 @@ x86-emulate.o x86-emulate-cov.o: x86_emulate/x86_emulate.c $(x86_emulate.h)
fuzz-emul.o fuzz-emulate-cov.o wrappers.o: $(x86_emulate.h)
x86-insn-fuzzer.a: fuzz-emul.o x86-emulate.o
x86-insn-fuzzer.a: fuzz-emul.o x86-emulate.o cpuid.o
$(AR) rc $@ $^
afl-harness: afl-harness.o fuzz-emul.o x86-emulate.o wrappers.o
afl-harness: afl-harness.o fuzz-emul.o x86-emulate.o cpuid.o wrappers.o
$(CC) $(CFLAGS) $^ -o $@
afl-harness-cov: afl-harness-cov.o fuzz-emul-cov.o x86-emulate-cov.o wrappers.o
afl-harness-cov: afl-harness-cov.o fuzz-emul-cov.o x86-emulate-cov.o cpuid.o wrappers.o
$(CC) $(CFLAGS) $(GCOV_FLAGS) $^ -o $@
# Common targets
+6 -1
View File
@@ -11,6 +11,11 @@ all: $(TARGET)
run: $(TARGET)
./$(TARGET)
# Add libx86 to the build
vpath %.c $(XEN_ROOT)/xen/lib/x86
CFLAGS += $(CFLAGS_xeninclude)
SIMD := 3dnow sse sse2 sse4 avx avx2 xop
FMA := fma4 fma
SG := avx2-sg
@@ -139,7 +144,7 @@ $(addsuffix .h,$(SIMD) $(FMA) $(SG)): simd.h
xop.h: simd-fma.c
$(TARGET): x86-emulate.o test_x86_emulator.o wrappers.o
$(TARGET): x86-emulate.o cpuid.o test_x86_emulator.o wrappers.o
$(HOSTCC) $(HOSTCFLAGS) -o $@ $^
.PHONY: clean
+12
View File
@@ -25,6 +25,7 @@
#define put_stub(stb) ((stb).addr = 0)
uint32_t mxcsr_mask = 0x0000ffbf;
struct cpuid_policy cp;
static char fpu_save_area[4096] __attribute__((__aligned__((64))));
static bool use_xsave;
@@ -64,6 +65,17 @@ bool emul_test_init(void)
unsigned long sp;
x86_cpuid_policy_fill_native(&cp);
/*
* The emulator doesn't use these instructions, so can always emulate
* them.
*/
cp.basic.movbe = true;
cp.feat.adx = true;
cp.feat.rdpid = true;
cp.extd.clzero = true;
if ( cpu_has_xsave )
{
unsigned int tmp, ebx;
+31 -180
View File
@@ -62,6 +62,7 @@
#define is_canonical_address(x) (((int64_t)(x) >> 47) == ((int64_t)(x) >> 63))
extern uint32_t mxcsr_mask;
extern struct cpuid_policy cp;
#define MMAP_SZ 16384
bool emul_test_init(void);
@@ -104,191 +105,41 @@ static inline uint64_t xgetbv(uint32_t xcr)
return ((uint64_t)hi << 32) | lo;
}
#define cache_line_size() ({ \
struct cpuid_leaf res; \
emul_test_cpuid(1, 0, &res, NULL); \
res.d & (1U << 19) ? (res.b >> 5) & 0x7f8 : 0; \
})
/* Intentionally checking OSXSAVE here. */
#define cpu_has_xsave (cp.basic.raw[1].c & (1u << 27))
#define cpu_has_mmx ({ \
struct cpuid_leaf res; \
emul_test_cpuid(1, 0, &res, NULL); \
(res.d & (1U << 23)) != 0; \
})
static inline bool xcr0_mask(uint64_t mask)
{
return cpu_has_xsave && ((xgetbv(0) & mask) == mask);
}
#define cpu_has_fxsr ({ \
struct cpuid_leaf res; \
emul_test_cpuid(1, 0, &res, NULL); \
(res.d & (1U << 24)) != 0; \
})
#define cache_line_size() (cp.basic.clflush_size * 8)
#define cpu_has_mmx cp.basic.mmx
#define cpu_has_fxsr cp.basic.fxsr
#define cpu_has_sse cp.basic.sse
#define cpu_has_sse2 cp.basic.sse2
#define cpu_has_sse3 cp.basic.sse3
#define cpu_has_fma (cp.basic.fma && xcr0_mask(6))
#define cpu_has_sse4_1 cp.basic.sse4_1
#define cpu_has_sse4_2 cp.basic.sse4_2
#define cpu_has_popcnt cp.basic.popcnt
#define cpu_has_avx (cp.basic.avx && xcr0_mask(6))
#define cpu_has_f16c (cp.basic.f16c && xcr0_mask(6))
#define cpu_has_sse ({ \
struct cpuid_leaf res; \
emul_test_cpuid(1, 0, &res, NULL); \
(res.d & (1U << 25)) != 0; \
})
#define cpu_has_avx2 (cp.feat.avx2 && xcr0_mask(6))
#define cpu_has_bmi1 cp.feat.bmi1
#define cpu_has_bmi2 cp.feat.bmi2
#define cpu_has_avx512f (cp.feat.avx512f && xcr0_mask(0xe6))
#define cpu_has_avx512dq (cp.feat.avx512dq && xcr0_mask(0xe6))
#define cpu_has_avx512bw (cp.feat.avx512bw && xcr0_mask(0xe6))
#define cpu_has_sse2 ({ \
struct cpuid_leaf res; \
emul_test_cpuid(1, 0, &res, NULL); \
(res.d & (1U << 26)) != 0; \
})
#define cpu_has_xgetbv1 (cpu_has_xsave && cp.xstate.xgetbv1)
#define cpu_has_sse3 ({ \
struct cpuid_leaf res; \
emul_test_cpuid(1, 0, &res, NULL); \
(res.c & (1U << 0)) != 0; \
})
#define cpu_has_fma ({ \
struct cpuid_leaf res; \
emul_test_cpuid(1, 0, &res, NULL); \
if ( !(res.c & (1U << 27)) || ((xgetbv(0) & 6) != 6) ) \
res.c = 0; \
(res.c & (1U << 12)) != 0; \
})
#define cpu_has_sse4_1 ({ \
struct cpuid_leaf res; \
emul_test_cpuid(1, 0, &res, NULL); \
(res.c & (1U << 19)) != 0; \
})
#define cpu_has_sse4_2 ({ \
struct cpuid_leaf res; \
emul_test_cpuid(1, 0, &res, NULL); \
(res.c & (1U << 20)) != 0; \
})
#define cpu_has_popcnt ({ \
struct cpuid_leaf res; \
emul_test_cpuid(1, 0, &res, NULL); \
(res.c & (1U << 23)) != 0; \
})
#define cpu_has_xsave ({ \
struct cpuid_leaf res; \
emul_test_cpuid(1, 0, &res, NULL); \
/* Intentionally checking OSXSAVE here. */ \
(res.c & (1U << 27)) != 0; \
})
#define cpu_has_avx ({ \
struct cpuid_leaf res; \
emul_test_cpuid(1, 0, &res, NULL); \
if ( !(res.c & (1U << 27)) || ((xgetbv(0) & 6) != 6) ) \
res.c = 0; \
(res.c & (1U << 28)) != 0; \
})
#define cpu_has_f16c ({ \
struct cpuid_leaf res; \
emul_test_cpuid(1, 0, &res, NULL); \
if ( !(res.c & (1U << 27)) || ((xgetbv(0) & 6) != 6) ) \
res.c = 0; \
(res.c & (1U << 29)) != 0; \
})
#define cpu_has_avx2 ({ \
struct cpuid_leaf res; \
emul_test_cpuid(1, 0, &res, NULL); \
if ( !(res.c & (1U << 27)) || ((xgetbv(0) & 6) != 6) ) \
res.b = 0; \
else { \
emul_test_cpuid(7, 0, &res, NULL); \
} \
(res.b & (1U << 5)) != 0; \
})
#define cpu_has_xgetbv1 ({ \
struct cpuid_leaf res; \
emul_test_cpuid(1, 0, &res, NULL); \
if ( !(res.c & (1U << 27)) ) \
res.a = 0; \
else \
emul_test_cpuid(0xd, 1, &res, NULL); \
(res.a & (1U << 2)) != 0; \
})
#define cpu_has_bmi1 ({ \
struct cpuid_leaf res; \
emul_test_cpuid(7, 0, &res, NULL); \
(res.b & (1U << 3)) != 0; \
})
#define cpu_has_bmi2 ({ \
struct cpuid_leaf res; \
emul_test_cpuid(7, 0, &res, NULL); \
(res.b & (1U << 8)) != 0; \
})
#define cpu_has_3dnow_ext ({ \
struct cpuid_leaf res; \
emul_test_cpuid(0x80000001, 0, &res, NULL); \
(res.d & (1U << 30)) != 0; \
})
#define cpu_has_sse4a ({ \
struct cpuid_leaf res; \
emul_test_cpuid(0x80000001, 0, &res, NULL); \
(res.c & (1U << 6)) != 0; \
})
#define cpu_has_xop ({ \
struct cpuid_leaf res; \
emul_test_cpuid(1, 0, &res, NULL); \
if ( !(res.c & (1U << 27)) || ((xgetbv(0) & 6) != 6) ) \
res.c = 0; \
else \
emul_test_cpuid(0x80000001, 0, &res, NULL); \
(res.c & (1U << 11)) != 0; \
})
#define cpu_has_fma4 ({ \
struct cpuid_leaf res; \
emul_test_cpuid(1, 0, &res, NULL); \
if ( !(res.c & (1U << 27)) || ((xgetbv(0) & 6) != 6) ) \
res.c = 0; \
else \
emul_test_cpuid(0x80000001, 0, &res, NULL); \
(res.c & (1U << 16)) != 0; \
})
#define cpu_has_tbm ({ \
struct cpuid_leaf res; \
emul_test_cpuid(0x80000001, 0, &res, NULL); \
(res.c & (1U << 21)) != 0; \
})
#define cpu_has_avx512f ({ \
struct cpuid_leaf res; \
emul_test_cpuid(1, 0, &res, NULL); \
if ( !(res.c & (1U << 27)) || ((xgetbv(0) & 0xe6) != 0xe6) ) \
res.b = 0; \
else \
emul_test_cpuid(7, 0, &res, NULL); \
(res.b & (1U << 16)) != 0; \
})
#define cpu_has_avx512dq ({ \
struct cpuid_leaf res; \
emul_test_cpuid(1, 0, &res, NULL); \
if ( !(res.c & (1U << 27)) || ((xgetbv(0) & 0xe6) != 0xe6) ) \
res.b = 0; \
else \
emul_test_cpuid(7, 0, &res, NULL); \
(res.b & (1U << 17)) != 0; \
})
#define cpu_has_avx512bw ({ \
struct cpuid_leaf res; \
emul_test_cpuid(1, 0, &res, NULL); \
if ( !(res.c & (1U << 27)) || ((xgetbv(0) & 0xe6) != 0xe6) ) \
res.b = 0; \
else \
emul_test_cpuid(7, 0, &res, NULL); \
(res.b & (1U << 30)) != 0; \
})
#define cpu_has_3dnow_ext cp.extd._3dnowext
#define cpu_has_sse4a cp.extd.sse4a
#define cpu_has_xop (cp.extd.xop && xcr0_mask(6))
#define cpu_has_fma4 (cp.extd.fma4 && xcr0_mask(6))
#define cpu_has_tbm cp.extd.tbm
int emul_test_cpuid(
uint32_t leaf,
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.