]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Expose rdrand and f16c through cpuid also if the host only has avx.
authorMark Wielaard <mark@klomp.org>
Mon, 27 May 2019 20:19:27 +0000 (22:19 +0200)
committerMark Wielaard <mark@klomp.org>
Tue, 28 May 2019 19:54:13 +0000 (21:54 +0200)
The amd64 CPUID dirtyhelpers are mostly static since they emulate some
existing CPU "family". The avx2 ("i7-4910MQ") CPUID variant however
can "dynamicly" enable rdrand and/or f16c if the host supports them.
Do the same for the avx_and_cx16 ("i5-2300") CPUID variant.

https://bugs.kde.org/show_bug.cgi?id=408009

NEWS
VEX/priv/guest_amd64_defs.h
VEX/priv/guest_amd64_helpers.c
VEX/priv/guest_amd64_toIR.c
coregrind/m_machine.c

diff --git a/NEWS b/NEWS
index 753171f7aaf089dffcb55573a8ad3632e7fba171..004e6770093ff4ef2feb69df1d7bf3408b62b7f8 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -52,6 +52,7 @@ where XXXXXX is the bug number as listed below.
 407218  Add support for the copy_file_range syscall
 407307  Intercept stpcpy also in ld.so for arm64
 407764  drd cond_post_wait gets wrong (?) condition on s390x z13 system
+408009  Expose rdrand and f16c even on avx if host cpu supports them
 n-i-bz  Fix minor one time leaks in dhat.
 n-i-bz  Add --run-cxx-freeres=no in outer args to avoid inner crashes.
 
index 4f34b41cbbbbf39d0c1e81e9f9402350e479ccc7..a5de527d26000c36b00ce4014705cc06b42f2e44 100644 (file)
@@ -165,7 +165,9 @@ extern void  amd64g_dirtyhelper_storeF80le ( Addr/*addr*/, ULong/*data*/ );
 extern void  amd64g_dirtyhelper_CPUID_baseline ( VexGuestAMD64State* st );
 extern void  amd64g_dirtyhelper_CPUID_sse3_and_cx16 ( VexGuestAMD64State* st );
 extern void  amd64g_dirtyhelper_CPUID_sse42_and_cx16 ( VexGuestAMD64State* st );
-extern void  amd64g_dirtyhelper_CPUID_avx_and_cx16 ( VexGuestAMD64State* st );
+extern void  amd64g_dirtyhelper_CPUID_avx_and_cx16 ( VexGuestAMD64State* st,
+                                                     ULong hasF16C,
+                                                     ULong hasRDRAND );
 extern void  amd64g_dirtyhelper_CPUID_avx2 ( VexGuestAMD64State* st,
                                              ULong hasF16C, ULong hasRDRAND );
 
index e4cf7e2031d5a605e75e361c52fa9e9e9dc1c1c9..182bae0bc5023d2c7e050914608fbee3fd14e5ba 100644 (file)
@@ -3141,8 +3141,11 @@ void amd64g_dirtyhelper_CPUID_sse42_and_cx16 ( VexGuestAMD64State* st )
    address sizes   : 36 bits physical, 48 bits virtual
    power management:
 */
-void amd64g_dirtyhelper_CPUID_avx_and_cx16 ( VexGuestAMD64State* st )
+void amd64g_dirtyhelper_CPUID_avx_and_cx16 ( VexGuestAMD64State* st,
+                                             ULong hasF16C, ULong hasRDRAND )
 {
+   vassert((hasF16C >> 1) == 0ULL);
+   vassert((hasRDRAND >> 1) == 0ULL);
 #  define SET_ABCD(_a,_b,_c,_d)                \
       do { st->guest_RAX = (ULong)(_a);        \
            st->guest_RBX = (ULong)(_b);        \
@@ -3157,9 +3160,14 @@ void amd64g_dirtyhelper_CPUID_avx_and_cx16 ( VexGuestAMD64State* st )
       case 0x00000000:
          SET_ABCD(0x0000000d, 0x756e6547, 0x6c65746e, 0x49656e69);
          break;
-      case 0x00000001:
-         SET_ABCD(0x000206a7, 0x00100800, 0x1f9ae3bf, 0xbfebfbff);
+      case 0x00000001: {
+         // As a baseline, advertise neither F16C (ecx:29) nor RDRAND (ecx:30),
+         // but patch in support for them as directed by the caller.
+         UInt ecx_extra
+            = (hasF16C ? (1U << 29) : 0) | (hasRDRAND ? (1U << 30) : 0);
+         SET_ABCD(0x000206a7, 0x00100800, (0x1f9ae3bf | ecx_extra), 0xbfebfbff);
          break;
+      }
       case 0x00000002:
          SET_ABCD(0x76035a01, 0x00f0b0ff, 0x00000000, 0x00ca0000);
          break;
index 56e992cd6fc5e8d6717b550af6c8e457883fcfd2..96dee381876d94fdaf96e57c8a23c914bd181a3d 100644 (file)
@@ -22007,7 +22007,8 @@ Long dis_ESC_0F (
 
       vassert(fName); vassert(fAddr);
       IRExpr** args = NULL;
-      if (fAddr == &amd64g_dirtyhelper_CPUID_avx2) {
+      if (fAddr == &amd64g_dirtyhelper_CPUID_avx2
+          || fAddr == &amd64g_dirtyhelper_CPUID_avx_and_cx16) {
          Bool hasF16C   = (archinfo->hwcaps & VEX_HWCAPS_AMD64_F16C) != 0;
          Bool hasRDRAND = (archinfo->hwcaps & VEX_HWCAPS_AMD64_RDRAND) != 0;
          args = mkIRExprVec_3(IRExpr_GSPTR(),
index 3536e5715815c44629191ce30946b738bd9eef11..56a28d108d70dcc10b352cfded4b7c334d350ec6 100644 (file)
@@ -1076,10 +1076,10 @@ Bool VG_(machine_get_hwcaps)( void )
         have_avx2 = (ebx & (1<<5)) != 0; /* True => have AVX2 */
      }
 
-     /* Sanity check for RDRAND and F16C.  These don't actually *need* AVX2, but
-        it's convenient to restrict them to the AVX2 case since the simulated
-        CPUID we'll offer them on has AVX2 as a base. */
-     if (!have_avx2) {
+     /* Sanity check for RDRAND and F16C.  These don't actually *need* AVX, but
+        it's convenient to restrict them to the AVX case since the simulated
+        CPUID we'll offer them on has AVX as a base. */
+     if (!have_avx) {
         have_f16c   = False;
         have_rdrand = False;
      }