]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Virtualize CPUID. Rather than just using the host CPU's CPUID,
authorJeremy Fitzhardinge <jeremy@valgrind.org>
Sun, 25 Jan 2004 02:38:29 +0000 (02:38 +0000)
committerJeremy Fitzhardinge <jeremy@valgrind.org>
Sun, 25 Jan 2004 02:38:29 +0000 (02:38 +0000)
we now completely virtualize it.  The feature flags returned are the
intersection of the set the CPU supports, and the set of flags Valgrind
supports.  This turns out to be a small number of features, like FPU,
TSC, MMX, SSE, SSE2, FXSR.  All mention of things which are only useful
to kernel-mode code are also suppressed.  This CPUID doesn't support
any extended feature flags, or extended CPUID operations.  It returns a
vendor string of "ValgrindVCPU".

If the host CPU doesn't support CPUID, then we make sure we treat it as
an illegal instruction (I'm not sure if we handle the eflags bit toggle
test right).  This is because the CPUID helper doesn't actually use the
cpuid instruction in all cases, so it may succeed where the host CPU
wouldn't (other instructions which depend on feature flags will end up
generating those instructions, so they'll endup generating a SIGILL if
client code uses them on a CPU which doesn't support them).

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2225

coregrind/vg_constants.h
coregrind/vg_helpers.S
coregrind/vg_include.h
coregrind/vg_to_ucode.c

index f588fafdf1dec2242eab73a55aeb7faa44f36cbc..74f3023de99731ce3bd2963c594b84fec06de578 100644 (file)
 /* Assembly code stubs make this request */
 #define VG_USERREQ__SIGNAL_RETURNS          0x4001
 
+/* CPU features */
+#define VG_X86_FEAT_FPU                (0*32 + 0)
+#define VG_X86_FEAT_VME                (0*32 + 1)
+#define VG_X86_FEAT_DE         (0*32 + 2)
+#define VG_X86_FEAT_PSE                (0*32 + 3)
+#define VG_X86_FEAT_TSC                (0*32 + 4)
+#define VG_X86_FEAT_MSR                (0*32 + 5)
+#define VG_X86_FEAT_PAE                (0*32 + 6)
+#define VG_X86_FEAT_MCE                (0*32 + 7)
+#define VG_X86_FEAT_CX8                (0*32 + 8)
+#define VG_X86_FEAT_APIC       (0*32 + 9)
+#define VG_X86_FEAT_SEP                (0*32 + 11)
+#define VG_X86_FEAT_MTRR       (0*32 + 12)
+#define VG_X86_FEAT_PGE                (0*32 + 13)
+#define VG_X86_FEAT_MCA                (0*32 + 14)
+#define VG_X86_FEAT_CMOV       (0*32 + 15)
+#define VG_X86_FEAT_PAT                (0*32 + 16)
+#define VG_X86_FEAT_PSE36      (0*32 + 17)
+#define VG_X86_FEAT_CLFSH      (0*32 + 19)
+#define VG_X86_FEAT_DS         (0*32 + 21)
+#define VG_X86_FEAT_ACPI       (0*32 + 22)
+#define VG_X86_FEAT_MMX                (0*32 + 23)
+#define VG_X86_FEAT_FXSR       (0*32 + 24)
+#define VG_X86_FEAT_SSE                (0*32 + 25)
+#define VG_X86_FEAT_SSE2       (0*32 + 26)
+#define VG_X86_FEAT_SS         (0*32 + 27)
+#define VG_X86_FEAT_HT         (0*32 + 28)
+#define VG_X86_FEAT_TM         (0*32 + 29)
+#define VG_X86_FEAT_PBE                (0*32 + 31)
+
+#define VG_X86_FEAT_EST                (1*32 + 7)
+#define VG_X86_FEAT_TM2                (1*32 + 8)
+#define VG_X86_FEAT_CNXTID     (1*32 + 10)
+
+/* Used internally to mark whether CPUID is even implemented */
+#define VG_X86_FEAT_CPUID      (2*32 + 0)
+
+/* The set of features we're willing to support for the client */
+#define VG_SUPPORTED_FEATURES                  \
+       ((1 << VG_X86_FEAT_FPU)  |              \
+        (1 << VG_X86_FEAT_TSC)  |              \
+        (1 << VG_X86_FEAT_CMOV) |              \
+        (1 << VG_X86_FEAT_MMX)  |              \
+        (1 << VG_X86_FEAT_FXSR) |              \
+        (1 << VG_X86_FEAT_SSE)  |              \
+        (1 << VG_X86_FEAT_SSE2))
 /* Various environment variables we pay attention to */
 
 /* The directory we look for all our auxillary files in */
index f2e8cd048994a963b7be5ea1fcda579f2c230f2d..5d2c313ab6a5b6bf26b770dd29fe52ebedb600c1 100644 (file)
@@ -193,7 +193,8 @@ out_done:
    For simulating the cpuid instruction, we will
    issue a "real" cpuid instruction and then mask out
    the bits of the features we do not support currently (3dnow mostly).
-
+   We also claim to not support most CPUID operations.
+       
    Dirk Mueller <mueller@kde.org>
 
    http://www.sandpile.org/ia32/cpuid.htm
@@ -213,19 +214,39 @@ VG_(helper_CPUID):
        pushl   %edx
        movl    32(%esp), %eax
 
-        cmpl   $0x80000001, %eax
-        je     cpuid_no3dnow
+       /* eax==0 - max valid request+processor vendor */
+       cmpl    $0, %eax
+       jne     1f
 
-       cpuid
-       jmp     cpuid__99
+       movl    $1, %eax        /* only support request 1 */
+       movl    valgrind_brand+0, %ebx
+       movl    valgrind_brand+4, %edx
+       movl    valgrind_brand+8, %ecx
+       jmp     99f
 
-cpuid_no3dnow:
-       cpuid
-       
-       andl    $0x3fffffff, %edx
+       /* eax==1 - CPU features and model ID */
+1:     cmpl    $1, %eax
+       jne     2f
+
+       cpuid   /* get host CPU's capabilities */
+
+       movl    $0111, %eax
+       movl    $0, %ebx                        /* clear APIC id, CLFLUSH size, Brand ID */
+       movl    $0, %ecx                        /* clear extended feature bits */
+       andl    $VG_SUPPORTED_FEATURES, %edx    /* mask off feature bits we don't support */
+       jmp     99f
+
+       /* eax=0x80000000 - extended cpuid functions */
+2:     cmpl    $0x80000000, %eax
+       jne     99f
 
-cpuid__99:
-       movl    %edx, 20(%esp)
+       /* leave eax==0x80000000 - we don't support any other extended operations */
+       movl    valgrind_brand+0, %ebx  /* AMD load the brand string again - */
+       movl    valgrind_brand+4, %edx  /* Intel leaves them "reserved" */
+       movl    valgrind_brand+8, %ecx
+       
+       
+99:    movl    %edx, 20(%esp)
        movl    %ecx, 24(%esp)
        movl    %ebx, 28(%esp)
        movl    %eax, 32(%esp)
@@ -235,7 +256,10 @@ cpuid__99:
        popl    %ebx
        popl    %eax
        ret
-
+.data
+valgrind_brand:
+       .ascii "ValgrindVCPU"
+.text
 
 /* Fetch the FPU status register.
    On entry:
index 006de0f0eb9c76be45d611cad2b7ef003722076d..fcb3efb543de25f580834d5a6d0f2d1a69126c7b 100644 (file)
@@ -1136,39 +1136,6 @@ extern Bool   VG_(is_chained_jumpsite)    ( Addr jumpsite );
    Exports of vg_to_ucode.c
    ------------------------------------------------------------------ */
 
-#define VG_X86_FEAT_FPU                (0*32 + 0)
-#define VG_X86_FEAT_VME                (0*32 + 1)
-#define VG_X86_FEAT_DE         (0*32 + 2)
-#define VG_X86_FEAT_PSE                (0*32 + 3)
-#define VG_X86_FEAT_TSC                (0*32 + 4)
-#define VG_X86_FEAT_MSR                (0*32 + 5)
-#define VG_X86_FEAT_PAE                (0*32 + 6)
-#define VG_X86_FEAT_MCE                (0*32 + 7)
-#define VG_X86_FEAT_CX8                (0*32 + 8)
-#define VG_X86_FEAT_APIC       (0*32 + 9)
-#define VG_X86_FEAT_SEP                (0*32 + 11)
-#define VG_X86_FEAT_MTRR       (0*32 + 12)
-#define VG_X86_FEAT_PGE                (0*32 + 13)
-#define VG_X86_FEAT_MCA                (0*32 + 14)
-#define VG_X86_FEAT_CMOV       (0*32 + 15)
-#define VG_X86_FEAT_PAT                (0*32 + 16)
-#define VG_X86_FEAT_PSE36      (0*32 + 17)
-#define VG_X86_FEAT_CLFSH      (0*32 + 19)
-#define VG_X86_FEAT_DS         (0*32 + 21)
-#define VG_X86_FEAT_ACPI       (0*32 + 22)
-#define VG_X86_FEAT_MMX                (0*32 + 23)
-#define VG_X86_FEAT_FXSR       (0*32 + 24)
-#define VG_X86_FEAT_SSE                (0*32 + 25)
-#define VG_X86_FEAT_SSE2       (0*32 + 26)
-#define VG_X86_FEAT_SS         (0*32 + 27)
-#define VG_X86_FEAT_HT         (0*32 + 28)
-#define VG_X86_FEAT_TM         (0*32 + 29)
-#define VG_X86_FEAT_PBE                (0*32 + 31)
-
-#define VG_X86_FEAT_EST                (1*32 + 7)
-#define VG_X86_FEAT_TM2                (1*32 + 8)
-#define VG_X86_FEAT_CNXTID     (1*32 + 10)
-
 Bool VG_(cpu_has_feature)(UInt feat);
 
 extern Int   VG_(disBB)          ( UCodeBlock* cb, Addr eip0 );
index d8441470bed0e2900c84ff4cb66b19549397efb5..d62459ddf001b239a9cd78b34688149c293b3930 100644 (file)
@@ -45,7 +45,7 @@
 /*--- for now.                                             ---*/
 /*------------------------------------------------------------*/
 
-#define VG_N_FEATURE_WORDS     2
+#define VG_N_FEATURE_WORDS     3
 
 static Int cpuid_level = -2;   /* -2 -> not initialized */
 static UInt cpu_features[VG_N_FEATURE_WORDS];
@@ -108,6 +108,8 @@ static void get_cpu_features(void)
       return;
    }
 
+   cpu_features[2] |= (1 << (VG_X86_FEAT_CPUID%32));
+
    cpuid_level = cpuid_eax(0);
 
    if (cpuid_level >= 1)
@@ -6503,6 +6505,9 @@ static Addr disInstr ( UCodeBlock* cb, Addr eip, Bool* isEnd )
       /* =-=-=-=-=-=-=-=-=- CPUID -=-=-=-=-=-=-=-=-=-=-= */
 
       case 0xA2: /* CPUID */
+        if (!VG_(cpu_has_feature)(VG_X86_FEAT_CPUID))
+           goto decode_failure;
+
          t1 = newTemp(cb);
          t2 = newTemp(cb);
          t3 = newTemp(cb);