Author: sewardj
Date: Sat May 3 21:22:55 2014
New Revision: 13931
Log:
ARM64: add support for cache management instructions (Valgrind side):
dc cvau, regX
ic ivau, regX
mrs regX, ctr_el0
Fixes #333228 and #333230.
Modified:
trunk/coregrind/m_libcproc.c
trunk/coregrind/m_machine.c
trunk/coregrind/m_scheduler/scheduler.c
trunk/coregrind/pub_core_libcproc.h
trunk/memcheck/mc_machine.c
Modified: trunk/coregrind/m_libcproc.c
==============================================================================
--- trunk/coregrind/m_libcproc.c (original)
+++ trunk/coregrind/m_libcproc.c Sat May 3 21:22:55 2014
@@ -893,6 +893,34 @@
}
+/* ---------------------------------------------------------------------
+ dcache flushing
+ ------------------------------------------------------------------ */
+
+void VG_(flush_dcache) ( void *ptr, SizeT nbytes )
+{
+ /* Currently this is only required on ARM64. */
+# if defined(VGA_arm64)
+ Addr startaddr = (Addr) ptr;
+ Addr endaddr = startaddr + nbytes;
+ Addr cls;
+ Addr addr;
+
+ ULong ctr_el0;
+ __asm__ __volatile__ ("mrs %0, ctr_el0" : "=r"(ctr_el0));
+ cls = 4 * (1ULL << (0xF & (ctr_el0 >> 16)));
+
+ /* Stay sane .. */
+ vg_assert(cls == 64);
+
+ startaddr &= ~(cls - 1);
+ for (addr = startaddr; addr < endaddr; addr += cls) {
+ __asm__ __volatile__("dc cvau, %0" : : "r" (addr));
+ }
+ __asm__ __volatile__("dsb ish");
+# endif
+}
+
/*--------------------------------------------------------------------*/
/*--- end ---*/
/*--------------------------------------------------------------------*/
Modified: trunk/coregrind/m_machine.c
==============================================================================
--- trunk/coregrind/m_machine.c (original)
+++ trunk/coregrind/m_machine.c Sat May 3 21:22:55 2014
@@ -1454,6 +1454,19 @@
VG_(machine_get_cache_info)(&vai);
+ /* 0 denotes 'not set'. The range of legitimate values here,
+ after being set that is, is 2 though 17 inclusive. */
+ vg_assert(vai.arm64_dMinLine_lg2_szB == 0);
+ vg_assert(vai.arm64_iMinLine_lg2_szB == 0);
+ ULong ctr_el0;
+ __asm__ __volatile__("mrs %0, ctr_el0" : "=r"(ctr_el0));
+ vai.arm64_dMinLine_lg2_szB = ((ctr_el0 >> 16) & 0xF) + 2;
+ vai.arm64_iMinLine_lg2_szB = ((ctr_el0 >> 0) & 0xF) + 2;
+ VG_(debugLog)(1, "machine", "ARM64: ctr_el0.dMinLine_szB = %d, "
+ "ctr_el0.iMinLine_szB = %d\n",
+ 1 << vai.arm64_dMinLine_lg2_szB,
+ 1 << vai.arm64_iMinLine_lg2_szB);
+
return True;
}
Modified: trunk/coregrind/m_scheduler/scheduler.c
==============================================================================
--- trunk/coregrind/m_scheduler/scheduler.c (original)
+++ trunk/coregrind/m_scheduler/scheduler.c Sat May 3 21:22:55 2014
@@ -1466,21 +1466,20 @@
VG_(umsg)(
"valgrind: Unrecognised instruction at address %#lx.\n", addr);
VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
-#define M(a) VG_(umsg)(a "\n");
- M("Your program just tried to execute an instruction that Valgrind" );
- M("did not recognise. There are two possible reasons for this." );
- M("1. Your program has a bug and erroneously jumped to a non-code" );
- M(" location. If you are running Memcheck and you just saw a" );
- M(" warning about a bad jump, it's probably your program's fault.");
- M("2. The instruction is legitimate but Valgrind doesn't handle it,");
- M(" i.e. it's Valgrind's fault. If you think this is the case or");
- M(" you are not sure, please let us know and we'll try to fix it.");
- M("Either way, Valgrind will now raise a SIGILL signal which will" );
- M("probably kill your program." );
-#undef M
+# define M(a) VG_(umsg)(a "\n");
+ M("Your program just tried to execute an instruction that Valgrind" );
+ M("did not recognise. There are two possible reasons for this." );
+ M("1. Your program has a bug and erroneously jumped to a non-code" );
+ M(" location. If you are running Memcheck and you just saw a" );
+ M(" warning about a bad jump, it's probably your program's fault.");
+ M("2. The instruction is legitimate but Valgrind doesn't handle it,");
+ M(" i.e. it's Valgrind's fault. If you think this is the case or");
+ M(" you are not sure, please let us know and we'll try to fix it.");
+ M("Either way, Valgrind will now raise a SIGILL signal which will" );
+ M("probably kill your program." );
+# undef M
}
-
-#if defined(VGA_s390x)
+# if defined(VGA_s390x)
/* Now that the complaint is out we need to adjust the guest_IA. The
reason is that -- after raising the exception -- execution will
continue with the insn that follows the invalid insn. As the first
@@ -1492,12 +1491,12 @@
UChar byte = ((UChar *)addr)[0];
UInt insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
Addr next_insn_addr = addr + insn_length;
-
VG_(set_IP)(tid, next_insn_addr);
-#endif
+# endif
VG_(synth_sigill)(tid, addr);
break;
}
+
case VEX_TRC_JMP_TINVAL:
VG_(discard_translations)(
(Addr64)VG_(threads)[tid].arch.vex.guest_TISTART,
@@ -1508,6 +1507,14 @@
VG_(printf)("dump translations done.\n");
break;
+ case VEX_TRC_JMP_FLUSHDCACHE: {
+ void* start = (void*)VG_(threads)[tid].arch.vex.guest_TISTART;
+ SizeT len = VG_(threads)[tid].arch.vex.guest_TILEN;
+ VG_(debugLog)(2, "sched", "flush_dcache(%p, %lu)\n", start, len);
+ VG_(flush_dcache)(start, len);
+ break;
+ }
+
case VG_TRC_INVARIANT_FAILED:
/* This typically happens if, after running generated code,
it is detected that host CPU settings (eg, FPU/Vector
Modified: trunk/coregrind/pub_core_libcproc.h
==============================================================================
--- trunk/coregrind/pub_core_libcproc.h (original)
+++ trunk/coregrind/pub_core_libcproc.h Sat May 3 21:22:55 2014
@@ -87,6 +87,8 @@
// icache invalidation
extern void VG_(invalidate_icache) ( void *ptr, SizeT nbytes );
+// dcache flushing
+extern void VG_(flush_dcache) ( void *ptr, SizeT nbytes );
#endif // __PUB_CORE_LIBCPROC_H
Modified: trunk/memcheck/mc_machine.c
==============================================================================
--- trunk/memcheck/mc_machine.c (original)
+++ trunk/memcheck/mc_machine.c Sat May 3 21:22:55 2014
@@ -1055,6 +1055,9 @@
if (o == GOF(FPCR) && sz == 4) return -1; // untracked
if (o == GOF(FPSR) && sz == 4) return -1; // untracked
+ if (o == GOF(TISTART) && sz == 8) return -1; // untracked
+ if (o == GOF(TILEN) && sz == 8) return -1; // untracked
+
VG_(printf)("MC_(get_otrack_shadow_offset)(arm64)(off=%d,sz=%d)\n",
offset,szB);
tl_assert(0);
|