mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
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:
1 parent
c66ef0fbe1
commit
fd35f32b4b
4 files changed
+55
-184
No files matched your search
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||