]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Bug 369459 - valgrind on arm64 violates the ARMv8 spec (ldxr/stxr)
authorJulian Seward <jseward@acm.org>
Mon, 24 Apr 2017 09:24:57 +0000 (09:24 +0000)
committerJulian Seward <jseward@acm.org>
Mon, 24 Apr 2017 09:24:57 +0000 (09:24 +0000)
This implements a fallback LL/SC implementation as described in bug 344524.

Valgrind side changes:

* Command line plumbing for --sim-hints=fallback-llsc

* memcheck: handle new arm64 guest state in memcheck/mc_machine.c

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

coregrind/m_main.c
coregrind/m_scheduler/scheduler.c
coregrind/m_translate.c
coregrind/pub_core_options.h
memcheck/mc_machine.c
none/tests/cmdline1.stdout.exp
none/tests/cmdline2.stdout.exp

index 9a4b60efebfc9bb4bc65751f978b61e0c774ed37..424daf7f9bac54da5eb7b2d39212a963c9eea71e 100644 (file)
@@ -187,7 +187,7 @@ static void usage_NORETURN ( Bool debug_help )
 "    --sim-hints=hint1,hint2,...  activate unusual sim behaviours [none] \n"
 "         where hint is one of:\n"
 "           lax-ioctls lax-doors fuse-compatible enable-outer\n"
-"           no-inner-prefix no-nptl-pthread-stackcache none\n"
+"           no-inner-prefix no-nptl-pthread-stackcache fallback-llsc none\n"
 "    --fair-sched=no|yes|try   schedule threads fairly on multicore systems [no]\n"
 "    --kernel-variant=variant1,variant2,...\n"
 "         handle non-standard kernel variants [none]\n"
@@ -417,7 +417,7 @@ static void early_process_cmd_line_options ( /*OUT*/Int* need_help )
       else if VG_USETX_CLO (str, "--sim-hints",
                             "lax-ioctls,lax-doors,fuse-compatible,"
                             "enable-outer,no-inner-prefix,"
-                            "no-nptl-pthread-stackcache",
+                            "no-nptl-pthread-stackcache,fallback-llsc",
                             VG_(clo_sim_hints)) {}
    }
 
index 9ae3f212aeeb8e964f50d01b0841918b84be947c..96a24f820ed2127b73d5b4b050654b8b1b7530a8 100644 (file)
@@ -925,6 +925,14 @@ void run_thread_for_a_while ( /*OUT*/HWord* two_words,
    tst->arch.vex.host_EvC_FAILADDR
       = (HWord)VG_(fnptr_to_fnentry)( &VG_(disp_cp_evcheck_fail) );
 
+   /* Invalidate any in-flight LL/SC transactions, in the case that we're
+      using the fallback LL/SC implementation.  See bugs 344524 and 369459. */
+#  if defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
+   tst->arch.vex.guest_LLaddr = (HWord)(-1);
+#  elif defined(VGP_arm64_linux)
+   tst->arch.vex.guest_LLSC_SIZE = 0;
+#  endif
+
    if (0) {
       vki_sigset_t m;
       Int i, err = VG_(sigprocmask)(VKI_SIG_SETMASK, NULL, &m);
@@ -957,10 +965,6 @@ void run_thread_for_a_while ( /*OUT*/HWord* two_words,
    vg_assert(VG_(in_generated_code) == True);
    VG_(in_generated_code) = False;
 
-#if defined(VGA_mips32) || defined(VGA_mips64)
-   tst->arch.vex.guest_LLaddr = (HWord)(-1);
-#endif
-
    if (jumped != (HWord)0) {
       /* We get here if the client took a fault that caused our signal
          handler to longjmp. */
index 2d6d3bad4bc16aad00bca497a6b290980b85cc6b..c467e33c70c385d4ebb653d7d71c1d667233a4d5 100644 (file)
@@ -1663,30 +1663,51 @@ Bool VG_(translate) ( ThreadId tid,
    vex_abiinfo.guest_amd64_assume_fs_is_const = True;
    vex_abiinfo.guest_amd64_assume_gs_is_const = True;
 #  endif
+
 #  if defined(VGP_amd64_darwin)
    vex_abiinfo.guest_amd64_assume_gs_is_const = True;
 #  endif
+
+#  if defined(VGP_amd64_solaris)
+   vex_abiinfo.guest_amd64_assume_fs_is_const = True;
+#  endif
+
 #  if defined(VGP_ppc32_linux)
    vex_abiinfo.guest_ppc_zap_RZ_at_blr        = False;
    vex_abiinfo.guest_ppc_zap_RZ_at_bl         = NULL;
 #  endif
+
 #  if defined(VGP_ppc64be_linux)
    vex_abiinfo.guest_ppc_zap_RZ_at_blr        = True;
    vex_abiinfo.guest_ppc_zap_RZ_at_bl         = const_True;
    vex_abiinfo.host_ppc_calls_use_fndescrs    = True;
 #  endif
+
 #  if defined(VGP_ppc64le_linux)
    vex_abiinfo.guest_ppc_zap_RZ_at_blr        = True;
    vex_abiinfo.guest_ppc_zap_RZ_at_bl         = const_True;
    vex_abiinfo.host_ppc_calls_use_fndescrs    = False;
 #  endif
-#  if defined(VGP_amd64_solaris)
-   vex_abiinfo.guest_amd64_assume_fs_is_const = True;
-#  endif
+
 #  if defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
    ThreadArchState* arch = &VG_(threads)[tid].arch;
    vex_abiinfo.guest_mips_fp_mode64 =
       !!(arch->vex.guest_CP0_status & MIPS_CP0_STATUS_FR);
+   /* Compute guest__use_fallback_LLSC, overiding any settings of
+      VG_(clo_fallback_llsc) that we know would cause the guest to
+      fail (loop). */
+   if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
+      /* We must use the fallback scheme. */
+      vex_abiinfo.guest__use_fallback_LLSC = True;
+   } else {
+      vex_abiinfo.guest__use_fallback_LLSC
+         = SimHintiS(SimHint_fallback_llsc, VG_(clo_sim_hints));
+   }
+#  endif
+
+#  if defined(VGP_arm64_linux)
+   vex_abiinfo.guest__use_fallback_LLSC
+      = SimHintiS(SimHint_fallback_llsc, VG_(clo_sim_hints));
 #  endif
 
    /* Set up closure args. */
index ba2712776b325d21e8f22a40f44697c0bed66e26..703d08a0f52d774b842f8a8b6940cef71d4708a8 100644 (file)
@@ -222,14 +222,15 @@ typedef
       SimHint_fuse_compatible,
       SimHint_enable_outer,
       SimHint_no_inner_prefix,
-      SimHint_no_nptl_pthread_stackcache
+      SimHint_no_nptl_pthread_stackcache,
+      SimHint_fallback_llsc
    }
    SimHint;
 
 // Build mask to check or set SimHint a membership
 #define SimHint2S(a) (1 << (a))
 // SimHint h is member of the Set s ?
-#define SimHintiS(h,s) ((s) & SimHint2S(h))
+#define SimHintiS(h,s) (((s) & SimHint2S(h)) != 0)
 extern UInt VG_(clo_sim_hints);
 
 /* Show symbols in the form 'name+offset' ?  Default: NO */
index f6acc0bd27ace548a5714fd3241e8ec1a29016ec..608a3748a95fd362ac4265788dc4767a6b3676a8 100644 (file)
@@ -1040,6 +1040,10 @@ static Int get_otrack_shadow_offset_wrk ( Int offset, Int szB )
    if (o == GOF(CMSTART) && sz == 8) return -1; // untracked
    if (o == GOF(CMLEN)   && sz == 8) return -1; // untracked
 
+   if (o == GOF(LLSC_SIZE) && sz == 8) return -1; // untracked
+   if (o == GOF(LLSC_ADDR) && sz == 8) return o;
+   if (o == GOF(LLSC_DATA) && sz == 8) return o;
+
    VG_(printf)("MC_(get_otrack_shadow_offset)(arm64)(off=%d,sz=%d)\n",
                offset,szB);
    tl_assert(0);
index 4e8bca40f7e9d8fff0aa6d7fcb78cddd02198444..a4d81758eedea7d39b41bd70aeec39cef0e46cb7 100644 (file)
@@ -101,7 +101,7 @@ usage: valgrind [options] prog-and-args
     --sim-hints=hint1,hint2,...  activate unusual sim behaviours [none] 
          where hint is one of:
            lax-ioctls lax-doors fuse-compatible enable-outer
-           no-inner-prefix no-nptl-pthread-stackcache none
+           no-inner-prefix no-nptl-pthread-stackcache fallback-llsc none
     --fair-sched=no|yes|try   schedule threads fairly on multicore systems [no]
     --kernel-variant=variant1,variant2,...
          handle non-standard kernel variants [none]
index 644013c47e7ba74e1c67a2cb5857c28ab590ed46..461ad2da43b85b968d899d1a9ff56de8ada84abe 100644 (file)
@@ -101,7 +101,7 @@ usage: valgrind [options] prog-and-args
     --sim-hints=hint1,hint2,...  activate unusual sim behaviours [none] 
          where hint is one of:
            lax-ioctls lax-doors fuse-compatible enable-outer
-           no-inner-prefix no-nptl-pthread-stackcache none
+           no-inner-prefix no-nptl-pthread-stackcache fallback-llsc none
     --fair-sched=no|yes|try   schedule threads fairly on multicore systems [no]
     --kernel-variant=variant1,variant2,...
          handle non-standard kernel variants [none]