Index: /trunk/src/VBox/VMM/VMMAll/TMAllCpu.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/TMAllCpu.cpp	(revision 87291)
+++ /trunk/src/VBox/VMM/VMMAll/TMAllCpu.cpp	(revision 87292)
@@ -25,5 +25,9 @@
 #include <VBox/vmm/dbgf.h>
 #include <VBox/vmm/nem.h>
-#include <iprt/asm-amd64-x86.h> /* for SUPGetCpuHzFromGIP */
+#if   defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
+# include <iprt/asm-amd64-x86.h> /* for SUPGetCpuHzFromGIP; ASMReadTSC */
+#elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
+# include <iprt/asm-arm.h>
+#endif
 #include "TMInternal.h"
 #include <VBox/vmm/vmcc.h>
@@ -37,4 +41,23 @@
 
 
+
+/**
+ * Converts from virtual time to raw CPU ticks.
+ *
+ * Mainly to have the ASMMultU64ByU32DivByU32 overflow trickery in one place.
+ *
+ * @returns raw CPU ticks.
+ * @param   pVM             The cross context VM structure.
+ * @param   u64VirtualTime  The virtual time to convert.
+ */
+DECLINLINE(uint64_t) tmCpuTickCalcFromVirtual(PVMCC pVM, uint64_t u64VirtualTime)
+{
+    if (pVM->tm.s.cTSCTicksPerSecond <= UINT32_MAX)
+        return ASMMultU64ByU32DivByU32(u64VirtualTime, (uint32_t)pVM->tm.s.cTSCTicksPerSecond, TMCLOCK_FREQ_VIRTUAL);
+    Assert(pVM->tm.s.cTSCTicksPerSecond <= ((uint64_t)UINT32_MAX << 2)); /* <= 15.99 GHz */
+    return ASMMultU64ByU32DivByU32(u64VirtualTime, (uint32_t)(pVM->tm.s.cTSCTicksPerSecond >> 2), TMCLOCK_FREQ_VIRTUAL >> 2);
+}
+
+
 /**
  * Gets the raw cpu tick from current virtual time.
@@ -45,10 +68,7 @@
 DECLINLINE(uint64_t) tmCpuTickGetRawVirtual(PVMCC pVM, bool fCheckTimers)
 {
-    uint64_t u64;
     if (fCheckTimers)
-        u64 = TMVirtualSyncGet(pVM);
-    else
-        u64 = TMVirtualSyncGetNoCheck(pVM);
-    return ASMMultU64ByU32DivByU32(u64, pVM->tm.s.cTSCTicksPerSecond, TMCLOCK_FREQ_VIRTUAL);
+        return tmCpuTickCalcFromVirtual(pVM, TMVirtualSyncGet(pVM));
+    return tmCpuTickCalcFromVirtual(pVM, TMVirtualSyncGetNoCheck(pVM));
 }
 
@@ -289,7 +309,7 @@
          *        exact opposite of what the hardware implements. */
 #ifdef IN_RING3
-        *poffRealTsc = 0 - pVCpu->tm.s.offTSCRawSrc - SUPGetTscDelta();
+        *poffRealTsc = (uint64_t)0 - pVCpu->tm.s.offTSCRawSrc - (uint64_t)SUPGetTscDelta();
 #else
-        *poffRealTsc = 0 - pVCpu->tm.s.offTSCRawSrc - SUPGetTscDeltaByCpuSetIndex(pVCpu->iHostCpuSet);
+        *poffRealTsc = (uint64_t)0 - pVCpu->tm.s.offTSCRawSrc - (uint64_t)SUPGetTscDeltaByCpuSetIndex(pVCpu->iHostCpuSet);
 #endif
         return true;
@@ -353,5 +373,6 @@
     if (RT_UNLIKELY(cNsToDeadline >= TMCLOCK_FREQ_VIRTUAL))
         return uCpuHz;
-    uint64_t cTicks = ASMMultU64ByU32DivByU32(uCpuHz, cNsToDeadline, TMCLOCK_FREQ_VIRTUAL);
+    AssertCompile(TMCLOCK_FREQ_VIRTUAL <= UINT32_MAX);
+    uint64_t cTicks = ASMMultU64ByU32DivByU32(uCpuHz, (uint32_t)cNsToDeadline, TMCLOCK_FREQ_VIRTUAL);
     if (cTicks > 4000)
         cTicks -= 4000; /* fudge to account for overhead */
@@ -392,7 +413,7 @@
          *        exact opposite of what the hardware implements. */
 #ifdef IN_RING3
-        *poffRealTsc     = 0 - pVCpu->tm.s.offTSCRawSrc - SUPGetTscDelta();
+        *poffRealTsc     = (uint64_t)0 - pVCpu->tm.s.offTSCRawSrc - (uint64_t)SUPGetTscDelta();
 #else
-        *poffRealTsc     = 0 - pVCpu->tm.s.offTSCRawSrc - SUPGetTscDeltaByCpuSetIndex(pVCpu->iHostCpuSet);
+        *poffRealTsc     = (uint64_t)0 - pVCpu->tm.s.offTSCRawSrc - (uint64_t)SUPGetTscDeltaByCpuSetIndex(pVCpu->iHostCpuSet);
 #endif
         *pfOffsettedTsc  = true;
@@ -411,5 +432,5 @@
         uint64_t cNsToDeadline;
         uint64_t u64NowVirtSync = TMVirtualSyncGetWithDeadlineNoCheck(pVM, &cNsToDeadline);
-        uint64_t u64Now = ASMMultU64ByU32DivByU32(u64NowVirtSync, pVM->tm.s.cTSCTicksPerSecond, TMCLOCK_FREQ_VIRTUAL);
+        uint64_t u64Now = tmCpuTickCalcFromVirtual(pVM, u64NowVirtSync);
         u64Now -= pVCpu->tm.s.offTSCRawSrc;
         *poffRealTsc     = u64Now - ASMReadTSC();
@@ -582,5 +603,5 @@
         uint64_t cTSCTicksPerSecond = SUPGetCpuHzFromGip(g_pSUPGlobalInfoPage);
 #elif defined(IN_RING0)
-        uint64_t cTSCTicksPerSecond = SUPGetCpuHzFromGipBySetIndex(g_pSUPGlobalInfoPage, RTMpCpuIdToSetIndex(RTMpCpuId()));
+        uint64_t cTSCTicksPerSecond = SUPGetCpuHzFromGipBySetIndex(g_pSUPGlobalInfoPage, (uint32_t)RTMpCpuIdToSetIndex(RTMpCpuId()));
 #else
         uint64_t cTSCTicksPerSecond = SUPGetCpuHzFromGipBySetIndex(g_pSUPGlobalInfoPage, VMMGetCpu(pVM)->iHostCpuSet);
