x86emul/test: factor out emul_test_{read_cr,cpuid}
authorWei Liu <wei.liu2@citrix.com>
Fri, 9 Dec 2016 11:45:08 +0000 (11:45 +0000)
committerWei Liu <wei.liu2@citrix.com>
Tue, 13 Dec 2016 10:25:57 +0000 (10:25 +0000)
While at it, move xgetbv, all cpu_has_* and cache_line_size macros to
x86_emulate.h.

Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
tools/tests/x86_emulator/test_x86_emulator.c
tools/tests/x86_emulator/x86_emulate.c
tools/tests/x86_emulator/x86_emulate.h

index 0d80bff3ca5f98864db765e939c39353897ef99c..e40f0eaa302f83fd0015535a68d9b98d9ab10a32 100644 (file)
@@ -92,105 +92,6 @@ static int cmpxchg(
     return X86EMUL_OKAY;
 }
 
-static int cpuid(
-    unsigned int *eax,
-    unsigned int *ebx,
-    unsigned int *ecx,
-    unsigned int *edx,
-    struct x86_emulate_ctxt *ctxt)
-{
-    unsigned int leaf = *eax;
-
-    asm ("cpuid" : "+a" (*eax), "+c" (*ecx), "=d" (*edx), "=b" (*ebx));
-
-    /* The emulator doesn't itself use MOVBE, so we can always run the test. */
-    if ( leaf == 1 )
-        *ecx |= 1U << 22;
-
-    return X86EMUL_OKAY;
-}
-
-#define cache_line_size() ({ \
-    unsigned int eax = 1, ebx, ecx = 0, edx; \
-    cpuid(&eax, &ebx, &ecx, &edx, NULL); \
-    edx & (1U << 19) ? (ebx >> 5) & 0x7f8 : 0; \
-})
-
-#define cpu_has_mmx ({ \
-    unsigned int eax = 1, ecx = 0, edx; \
-    cpuid(&eax, &ecx, &ecx, &edx, NULL); \
-    (edx & (1U << 23)) != 0; \
-})
-
-#define cpu_has_sse ({ \
-    unsigned int eax = 1, ecx = 0, edx; \
-    cpuid(&eax, &ecx, &ecx, &edx, NULL); \
-    (edx & (1U << 25)) != 0; \
-})
-
-#define cpu_has_sse2 ({ \
-    unsigned int eax = 1, ecx = 0, edx; \
-    cpuid(&eax, &ecx, &ecx, &edx, NULL); \
-    (edx & (1U << 26)) != 0; \
-})
-
-#define cpu_has_xsave ({ \
-    unsigned int eax = 1, ecx = 0; \
-    cpuid(&eax, &eax, &ecx, &eax, NULL); \
-    /* Intentionally checking OSXSAVE here. */ \
-    (ecx & (1U << 27)) != 0; \
-})
-
-static inline uint64_t xgetbv(uint32_t xcr)
-{
-    uint32_t lo, hi;
-
-    asm ( ".byte 0x0f, 0x01, 0xd0" : "=a" (lo), "=d" (hi) : "c" (xcr) );
-
-    return ((uint64_t)hi << 32) | lo;
-}
-
-#define cpu_has_avx ({ \
-    unsigned int eax = 1, ecx = 0; \
-    cpuid(&eax, &eax, &ecx, &eax, NULL); \
-    if ( !(ecx & (1U << 27)) || ((xgetbv(0) & 6) != 6) ) \
-        ecx = 0; \
-    (ecx & (1U << 28)) != 0; \
-})
-
-#define cpu_has_avx2 ({ \
-    unsigned int eax = 1, ebx, ecx = 0; \
-    cpuid(&eax, &ebx, &ecx, &eax, NULL); \
-    if ( !(ecx & (1U << 27)) || ((xgetbv(0) & 6) != 6) ) \
-        ebx = 0; \
-    else { \
-        eax = 7, ecx = 0; \
-        cpuid(&eax, &ebx, &ecx, &eax, NULL); \
-    } \
-    (ebx & (1U << 5)) != 0; \
-})
-
-static int read_cr(
-    unsigned int reg,
-    unsigned long *val,
-    struct x86_emulate_ctxt *ctxt)
-{
-    /* Fake just enough state for the emulator's _get_fpu() to be happy. */
-    switch ( reg )
-    {
-    case 0:
-        *val = 0x00000001; /* PE */
-        return X86EMUL_OKAY;
-
-    case 4:
-        /* OSFXSR, OSXMMEXCPT, and maybe OSXSAVE */
-        *val = 0x00000600 | (cpu_has_xsave ? 0x00040000 : 0);
-        return X86EMUL_OKAY;
-    }
-
-    return X86EMUL_UNHANDLEABLE;
-}
-
 int get_fpu(
     void (*exception_callback)(void *, struct cpu_user_regs *),
     void *exception_callback_arg,
@@ -221,8 +122,8 @@ static struct x86_emulate_ops emulops = {
     .insn_fetch = fetch,
     .write      = write,
     .cmpxchg    = cmpxchg,
-    .cpuid      = cpuid,
-    .read_cr    = read_cr,
+    .cpuid      = emul_test_cpuid,
+    .read_cr    = emul_test_read_cr,
     .get_fpu    = get_fpu,
 };
 
index 963dd7181532a2a32da01ec489df2a434ed64dd2..07cfceaadd009833936294be872152d0fa2bb5fc 100644 (file)
@@ -38,4 +38,46 @@ bool emul_test_make_stack_executable(void)
                     MMAP_SZ, PROT_READ|PROT_WRITE|PROT_EXEC) == 0;
 }
 
+int emul_test_cpuid(
+    unsigned int *eax,
+    unsigned int *ebx,
+    unsigned int *ecx,
+    unsigned int *edx,
+    struct x86_emulate_ctxt *ctxt)
+{
+    unsigned int leaf = *eax;
+
+    asm ("cpuid" : "+a" (*eax), "+c" (*ecx), "=d" (*edx), "=b" (*ebx));
+
+    /*
+     * The emulator doesn't itself use MOVBE, so we can always run the
+     * respective tests.
+     */
+    if ( leaf == 1 )
+        *ecx |= 1U << 22;
+
+    return X86EMUL_OKAY;
+}
+
+int emul_test_read_cr(
+    unsigned int reg,
+    unsigned long *val,
+    struct x86_emulate_ctxt *ctxt)
+{
+    /* Fake just enough state for the emulator's _get_fpu() to be happy. */
+    switch ( reg )
+    {
+    case 0:
+        *val = 0x00000001; /* PE */
+        return X86EMUL_OKAY;
+
+    case 4:
+        /* OSFXSR, OSXMMEXCPT, and maybe OSXSAVE */
+        *val = 0x00000600 | (cpu_has_xsave ? 0x00040000 : 0);
+        return X86EMUL_OKAY;
+    }
+
+    return X86EMUL_UNHANDLEABLE;
+}
+
 #include "x86_emulate/x86_emulate.c"
index a9b874cf540844e79dcf6c29cb46c0d1f500c71c..4cc3f72d853467c3c958c65d712feb583a180517 100644 (file)
 bool emul_test_make_stack_executable(void);
 
 #include "x86_emulate/x86_emulate.h"
+
+static inline uint64_t xgetbv(uint32_t xcr)
+{
+    uint32_t lo, hi;
+
+    asm ( ".byte 0x0f, 0x01, 0xd0" : "=a" (lo), "=d" (hi) : "c" (xcr) );
+
+    return ((uint64_t)hi << 32) | lo;
+}
+
+#define cache_line_size() ({                \
+    unsigned int eax = 1, ebx, ecx = 0, edx; \
+    emul_test_cpuid(&eax, &ebx, &ecx, &edx, NULL); \
+    edx & (1U << 19) ? (ebx >> 5) & 0x7f8 : 0; \
+})
+
+#define cpu_has_mmx ({ \
+    unsigned int eax = 1, ecx = 0, edx; \
+    emul_test_cpuid(&eax, &ecx, &ecx, &edx, NULL); \
+    (edx & (1U << 23)) != 0; \
+})
+
+#define cpu_has_sse ({ \
+    unsigned int eax = 1, ecx = 0, edx; \
+    emul_test_cpuid(&eax, &ecx, &ecx, &edx, NULL); \
+    (edx & (1U << 25)) != 0; \
+})
+
+#define cpu_has_sse2 ({ \
+    unsigned int eax = 1, ecx = 0, edx; \
+    emul_test_cpuid(&eax, &ecx, &ecx, &edx, NULL); \
+    (edx & (1U << 26)) != 0; \
+})
+
+#define cpu_has_xsave ({ \
+    unsigned int eax = 1, ecx = 0; \
+    emul_test_cpuid(&eax, &eax, &ecx, &eax, NULL); \
+    /* Intentionally checking OSXSAVE here. */ \
+    (ecx & (1U << 27)) != 0; \
+})
+
+#define cpu_has_avx ({ \
+    unsigned int eax = 1, ecx = 0; \
+    emul_test_cpuid(&eax, &eax, &ecx, &eax, NULL); \
+    if ( !(ecx & (1U << 27)) || ((xgetbv(0) & 6) != 6) ) \
+        ecx = 0; \
+    (ecx & (1U << 28)) != 0; \
+})
+
+#define cpu_has_avx2 ({ \
+    unsigned int eax = 1, ebx, ecx = 0; \
+    emul_test_cpuid(&eax, &ebx, &ecx, &eax, NULL); \
+    if ( !(ecx & (1U << 27)) || ((xgetbv(0) & 6) != 6) ) \
+        ebx = 0; \
+    else { \
+        eax = 7, ecx = 0; \
+        emul_test_cpuid(&eax, &ebx, &ecx, &eax, NULL); \
+    } \
+    (ebx & (1U << 5)) != 0; \
+})
+
+int emul_test_cpuid(
+    unsigned int *eax,
+    unsigned int *ebx,
+    unsigned int *ecx,
+    unsigned int *edx,
+    struct x86_emulate_ctxt *ctxt);
+
+int emul_test_read_cr(
+    unsigned int reg,
+    unsigned long *val,
+    struct x86_emulate_ctxt *ctxt);