Index: trunk/src/VBox/VMM/VMMAll/TMAll.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/TMAll.cpp	(revision 37518)
+++ trunk/src/VBox/VMM/VMMAll/TMAll.cpp	(revision 37527)
@@ -72,93 +72,15 @@
 
 
-#ifndef tmTimerLock
-
-/**
- * Try take the timer lock, wait in ring-3 return VERR_SEM_BUSY in R0/RC.
- *
- * @retval  VINF_SUCCESS on success (always in ring-3).
- * @retval  VERR_SEM_BUSY in RC and R0 if the semaphore is busy.
- *
+/**
+ * Gets the current warp drive percent.
+ *
+ * @returns The warp drive percent.
  * @param   pVM         The VM handle.
- *
- * @thread  EMTs for the time being.
- */
-int tmTimerLock(PVM pVM)
-{
-    VM_ASSERT_EMT(pVM);
-    int rc = PDMCritSectEnter(&pVM->tm.s.TimerCritSect, VERR_SEM_BUSY);
-    return rc;
-}
-
-
-/**
- * Try take the timer lock, no waiting.
- *
- * @retval  VINF_SUCCESS on success.
- * @retval  VERR_SEM_BUSY if busy.
- *
- * @param   pVM         The VM handle.
- */
-int tmTimerTryLock(PVM pVM)
-{
-    int rc = PDMCritSectTryEnter(&pVM->tm.s.TimerCritSect);
-    return rc;
-}
-
-
-/**
- * Release the EMT/TM lock.
- *
- * @param   pVM         The VM handle.
- */
-void tmTimerUnlock(PVM pVM)
-{
-    PDMCritSectLeave(&pVM->tm.s.TimerCritSect);
-}
-
-
-/**
- * Try take the VirtualSync lock, wait in ring-3 return VERR_SEM_BUSY in R0/RC.
- *
- * @retval  VINF_SUCCESS on success (always in ring-3).
- * @retval  VERR_SEM_BUSY in RC and R0 if the semaphore is busy.
- *
- * @param   pVM         The VM handle.
- */
-int tmVirtualSyncLock(PVM pVM)
-{
-    VM_ASSERT_EMT(pVM);
-    int rc = PDMCritSectEnter(&pVM->tm.s.VirtualSyncLock, VERR_SEM_BUSY);
-    return rc;
-}
-
-
-/**
- * Try take the VirtualSync lock, no waiting.
- *
- * @retval  VINF_SUCCESS on success.
- * @retval  VERR_SEM_BUSY if busy.
- *
- * @param   pVM         The VM handle.
- */
-int tmVirtualSyncTryLock(PVM pVM)
-{
-    VM_ASSERT_EMT(pVM);
-    int rc = PDMCritSectTryEnter(&pVM->tm.s.VirtualSyncLock);
-    return rc;
-}
-
-
-/**
- * Release the VirtualSync lock.
- *
- * @param   pVM         The VM handle.
- */
-void tmVirtualSyncUnlock(PVM pVM)
-{
-    PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock);
-}
-
-#endif /* ! macros */
+ */
+VMMDECL(uint32_t) TMGetWarpDrive(PVM pVM)
+{
+    return pVM->tm.s.u32VirtualWarpDrivePercentage;
+}
+
 
 /**
@@ -327,5 +249,5 @@
     PVM pVM = pTimer->CTX_SUFF(pVM);
     if (    VM_IS_EMT(pVM)
-        &&  RT_SUCCESS(tmTimerTryLock(pVM)))
+        &&  RT_SUCCESS(TM_TRY_LOCK_TIMERS(pVM)))
     {
         STAM_PROFILE_START(&pVM->tm.s.CTX_SUFF_Z(StatScheduleOne), a);
@@ -336,5 +258,5 @@
 #endif
         STAM_PROFILE_STOP(&pVM->tm.s.CTX_SUFF_Z(StatScheduleOne), a);
-        tmTimerUnlock(pVM);
+        TM_UNLOCK_TIMERS(pVM);
     }
     else
@@ -568,5 +490,5 @@
 void tmTimerQueueSchedule(PVM pVM, PTMTIMERQUEUE pQueue)
 {
-    TM_ASSERT_LOCK(pVM);
+    TM_ASSERT_TIMER_LOCK_OWNERSHIP(pVM);
 
     /*
@@ -609,5 +531,5 @@
 void tmTimerQueuesSanityChecks(PVM pVM, const char *pszWhere)
 {
-    TM_ASSERT_LOCK(pVM);
+    TM_ASSERT_TIMER_LOCK_OWNERSHIP(pVM);
 
     /*
@@ -1195,5 +1117,5 @@
 
     STAM_COUNTER_INC(&pVM->tm.s.StatTimerSetOpt);
-    tmTimerUnlock(pVM);
+    TM_UNLOCK_TIMERS(pVM);
     return VINF_SUCCESS;
 }
@@ -1215,4 +1137,5 @@
     STAM_PROFILE_START(&pVM->tm.s.CTX_SUFF_Z(StatTimerSetVs), a);
     VM_ASSERT_EMT(pVM);
+    Assert(PDMCritSectIsOwner(&pVM->tm.s.VirtualSyncLock));
     int rc = PDMCritSectEnter(&pVM->tm.s.VirtualSyncLock, VINF_SUCCESS);
     AssertRCReturn(rc, rc);
@@ -1320,5 +1243,5 @@
     {
         /* Try take the TM lock and check the state again. */
-        if (RT_SUCCESS_NP(tmTimerTryLock(pVM)))
+        if (RT_SUCCESS_NP(TM_TRY_LOCK_TIMERS(pVM)))
         {
             if (RT_LIKELY(tmTimerTry(pTimer, TMTIMERSTATE_ACTIVE, enmState1)))
@@ -1328,5 +1251,5 @@
                 return VINF_SUCCESS;
             }
-            tmTimerUnlock(pVM);
+            TM_UNLOCK_TIMERS(pVM);
         }
     }
@@ -1492,5 +1415,5 @@
 
     STAM_COUNTER_INC(&pVM->tm.s.StatTimerSetRelativeOpt);
-    tmTimerUnlock(pVM);
+    TM_UNLOCK_TIMERS(pVM);
     return VINF_SUCCESS;
 }
@@ -1513,4 +1436,5 @@
     STAM_PROFILE_START(pVM->tm.s.CTX_SUFF_Z(StatTimerSetRelativeVs), a);
     VM_ASSERT_EMT(pVM);
+    Assert(PDMCritSectIsOwner(&pVM->tm.s.VirtualSyncLock));
     int rc = PDMCritSectEnter(&pVM->tm.s.VirtualSyncLock, VINF_SUCCESS);
     AssertRCReturn(rc, rc);
@@ -1626,5 +1550,5 @@
      *       get the innermost locks.
      */
-    bool fOwnTMLock = RT_SUCCESS_NP(tmTimerTryLock(pVM));
+    bool fOwnTMLock = RT_SUCCESS_NP(TM_TRY_LOCK_TIMERS(pVM));
 #if 1
     if (    fOwnTMLock
@@ -1778,5 +1702,5 @@
          */
         if (!fOwnTMLock)
-            fOwnTMLock = RT_SUCCESS_NP(tmTimerTryLock(pVM));
+            fOwnTMLock = RT_SUCCESS_NP(TM_TRY_LOCK_TIMERS(pVM));
 
     } /* for (;;) */
@@ -1786,107 +1710,8 @@
      */
     if (fOwnTMLock)
-        tmTimerUnlock(pVM);
+        TM_UNLOCK_TIMERS(pVM);
 
     STAM_PROFILE_STOP(&pTimer->CTX_SUFF(pVM)->tm.s.CTX_SUFF_Z(StatTimerSetRelative), a);
     return rc;
-}
-
-
-/**
- * Arm a timer with a (new) expire time relative to current time.
- *
- * @returns VBox status.
- * @param   pTimer          Timer handle as returned by one of the create functions.
- * @param   cMilliesToNext  Number of milliseconds to the next tick.
- */
-VMMDECL(int) TMTimerSetMillies(PTMTIMER pTimer, uint32_t cMilliesToNext)
-{
-    PVM    pVM   = pTimer->CTX_SUFF(pVM);
-    PVMCPU pVCpu = &pVM->aCpus[0];  /* just take the first VCPU */
-
-    switch (pTimer->enmClock)
-    {
-        case TMCLOCK_VIRTUAL:
-            AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
-            return TMTimerSetRelative(pTimer, cMilliesToNext * UINT64_C(1000000), NULL);
-
-        case TMCLOCK_VIRTUAL_SYNC:
-            AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
-            return TMTimerSetRelative(pTimer, cMilliesToNext * UINT64_C(1000000), NULL);
-
-        case TMCLOCK_REAL:
-            AssertCompile(TMCLOCK_FREQ_REAL == 1000);
-            return TMTimerSetRelative(pTimer, cMilliesToNext, NULL);
-
-        default:
-            AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
-            return VERR_INTERNAL_ERROR;
-    }
-}
-
-
-/**
- * Arm a timer with a (new) expire time relative to current time.
- *
- * @returns VBox status.
- * @param   pTimer          Timer handle as returned by one of the create functions.
- * @param   cMicrosToNext   Number of microseconds to the next tick.
- */
-VMMDECL(int) TMTimerSetMicro(PTMTIMER pTimer, uint64_t cMicrosToNext)
-{
-    PVM    pVM   = pTimer->CTX_SUFF(pVM);
-    PVMCPU pVCpu = &pVM->aCpus[0];  /* just take the first VCPU */
-
-    switch (pTimer->enmClock)
-    {
-        case TMCLOCK_VIRTUAL:
-            AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
-            return TMTimerSetRelative(pTimer, cMicrosToNext * 1000, NULL);
-
-        case TMCLOCK_VIRTUAL_SYNC:
-            AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
-            return TMTimerSetRelative(pTimer, cMicrosToNext * 1000, NULL);
-
-        case TMCLOCK_REAL:
-            AssertCompile(TMCLOCK_FREQ_REAL == 1000);
-            return TMTimerSetRelative(pTimer, cMicrosToNext / 1000, NULL);
-
-        default:
-            AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
-            return VERR_INTERNAL_ERROR;
-    }
-}
-
-
-/**
- * Arm a timer with a (new) expire time relative to current time.
- *
- * @returns VBox status.
- * @param   pTimer          Timer handle as returned by one of the create functions.
- * @param   cNanosToNext    Number of nanoseconds to the next tick.
- */
-VMMDECL(int) TMTimerSetNano(PTMTIMER pTimer, uint64_t cNanosToNext)
-{
-    PVM    pVM   = pTimer->CTX_SUFF(pVM);
-    PVMCPU pVCpu = &pVM->aCpus[0];  /* just take the first VCPU */
-
-    switch (pTimer->enmClock)
-    {
-        case TMCLOCK_VIRTUAL:
-            AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
-            return TMTimerSetRelative(pTimer, cNanosToNext, NULL);
-
-        case TMCLOCK_VIRTUAL_SYNC:
-            AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
-            return TMTimerSetRelative(pTimer, cNanosToNext, NULL);
-
-        case TMCLOCK_REAL:
-            AssertCompile(TMCLOCK_FREQ_REAL == 1000);
-            return TMTimerSetRelative(pTimer, cNanosToNext / 1000000, NULL);
-
-        default:
-            AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
-            return VERR_INTERNAL_ERROR;
-    }
 }
 
@@ -1938,4 +1763,5 @@
     STAM_PROFILE_START(&pVM->tm.s.CTX_SUFF_Z(StatTimerStopVs), a);
     VM_ASSERT_EMT(pVM);
+    Assert(PDMCritSectIsOwner(&pVM->tm.s.VirtualSyncLock));
     int rc = PDMCritSectEnter(&pVM->tm.s.VirtualSyncLock, VINF_SUCCESS);
     AssertRCReturn(rc, rc);
@@ -2149,211 +1975,4 @@
         case TMCLOCK_REAL:
             return TMCLOCK_FREQ_REAL;
-
-        default:
-            AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
-            return 0;
-    }
-}
-
-
-/**
- * Get the current clock time as nanoseconds.
- *
- * @returns The timer clock as nanoseconds.
- * @param   pTimer          Timer handle as returned by one of the create functions.
- */
-VMMDECL(uint64_t) TMTimerGetNano(PTMTIMER pTimer)
-{
-    return TMTimerToNano(pTimer, TMTimerGet(pTimer));
-}
-
-
-/**
- * Get the current clock time as microseconds.
- *
- * @returns The timer clock as microseconds.
- * @param   pTimer          Timer handle as returned by one of the create functions.
- */
-VMMDECL(uint64_t) TMTimerGetMicro(PTMTIMER pTimer)
-{
-    return TMTimerToMicro(pTimer, TMTimerGet(pTimer));
-}
-
-
-/**
- * Get the current clock time as milliseconds.
- *
- * @returns The timer clock as milliseconds.
- * @param   pTimer          Timer handle as returned by one of the create functions.
- */
-VMMDECL(uint64_t) TMTimerGetMilli(PTMTIMER pTimer)
-{
-    return TMTimerToMilli(pTimer, TMTimerGet(pTimer));
-}
-
-
-/**
- * Converts the specified timer clock time to nanoseconds.
- *
- * @returns nanoseconds.
- * @param   pTimer          Timer handle as returned by one of the create functions.
- * @param   u64Ticks        The clock ticks.
- * @remark  There could be rounding errors here. We just do a simple integer divide
- *          without any adjustments.
- */
-VMMDECL(uint64_t) TMTimerToNano(PTMTIMER pTimer, uint64_t u64Ticks)
-{
-    switch (pTimer->enmClock)
-    {
-        case TMCLOCK_VIRTUAL:
-        case TMCLOCK_VIRTUAL_SYNC:
-            AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
-            return u64Ticks;
-
-        case TMCLOCK_REAL:
-            AssertCompile(TMCLOCK_FREQ_REAL == 1000);
-            return u64Ticks * 1000000;
-
-        default:
-            AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
-            return 0;
-    }
-}
-
-
-/**
- * Converts the specified timer clock time to microseconds.
- *
- * @returns microseconds.
- * @param   pTimer          Timer handle as returned by one of the create functions.
- * @param   u64Ticks        The clock ticks.
- * @remark  There could be rounding errors here. We just do a simple integer divide
- *          without any adjustments.
- */
-VMMDECL(uint64_t) TMTimerToMicro(PTMTIMER pTimer, uint64_t u64Ticks)
-{
-    switch (pTimer->enmClock)
-    {
-        case TMCLOCK_VIRTUAL:
-        case TMCLOCK_VIRTUAL_SYNC:
-            AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
-            return u64Ticks / 1000;
-
-        case TMCLOCK_REAL:
-            AssertCompile(TMCLOCK_FREQ_REAL == 1000);
-            return u64Ticks * 1000;
-
-        default:
-            AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
-            return 0;
-    }
-}
-
-
-/**
- * Converts the specified timer clock time to milliseconds.
- *
- * @returns milliseconds.
- * @param   pTimer          Timer handle as returned by one of the create functions.
- * @param   u64Ticks        The clock ticks.
- * @remark  There could be rounding errors here. We just do a simple integer divide
- *          without any adjustments.
- */
-VMMDECL(uint64_t) TMTimerToMilli(PTMTIMER pTimer, uint64_t u64Ticks)
-{
-    switch (pTimer->enmClock)
-    {
-        case TMCLOCK_VIRTUAL:
-        case TMCLOCK_VIRTUAL_SYNC:
-            AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
-            return u64Ticks / 1000000;
-
-        case TMCLOCK_REAL:
-            AssertCompile(TMCLOCK_FREQ_REAL == 1000);
-            return u64Ticks;
-
-        default:
-            AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
-            return 0;
-    }
-}
-
-
-/**
- * Converts the specified nanosecond timestamp to timer clock ticks.
- *
- * @returns timer clock ticks.
- * @param   pTimer          Timer handle as returned by one of the create functions.
- * @param   cNanoSecs       The nanosecond value ticks to convert.
- * @remark  There could be rounding and overflow errors here.
- */
-VMMDECL(uint64_t) TMTimerFromNano(PTMTIMER pTimer, uint64_t cNanoSecs)
-{
-    switch (pTimer->enmClock)
-    {
-        case TMCLOCK_VIRTUAL:
-        case TMCLOCK_VIRTUAL_SYNC:
-            AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
-            return cNanoSecs;
-
-        case TMCLOCK_REAL:
-            AssertCompile(TMCLOCK_FREQ_REAL == 1000);
-            return cNanoSecs / 1000000;
-
-        default:
-            AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
-            return 0;
-    }
-}
-
-
-/**
- * Converts the specified microsecond timestamp to timer clock ticks.
- *
- * @returns timer clock ticks.
- * @param   pTimer          Timer handle as returned by one of the create functions.
- * @param   cMicroSecs      The microsecond value ticks to convert.
- * @remark  There could be rounding and overflow errors here.
- */
-VMMDECL(uint64_t) TMTimerFromMicro(PTMTIMER pTimer, uint64_t cMicroSecs)
-{
-    switch (pTimer->enmClock)
-    {
-        case TMCLOCK_VIRTUAL:
-        case TMCLOCK_VIRTUAL_SYNC:
-            AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
-            return cMicroSecs * 1000;
-
-        case TMCLOCK_REAL:
-            AssertCompile(TMCLOCK_FREQ_REAL == 1000);
-            return cMicroSecs / 1000;
-
-        default:
-            AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
-            return 0;
-    }
-}
-
-
-/**
- * Converts the specified millisecond timestamp to timer clock ticks.
- *
- * @returns timer clock ticks.
- * @param   pTimer          Timer handle as returned by one of the create functions.
- * @param   cMilliSecs      The millisecond value ticks to convert.
- * @remark  There could be rounding and overflow errors here.
- */
-VMMDECL(uint64_t) TMTimerFromMilli(PTMTIMER pTimer, uint64_t cMilliSecs)
-{
-    switch (pTimer->enmClock)
-    {
-        case TMCLOCK_VIRTUAL:
-        case TMCLOCK_VIRTUAL_SYNC:
-            AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
-            return cMilliSecs * 1000000;
-
-        case TMCLOCK_REAL:
-            AssertCompile(TMCLOCK_FREQ_REAL == 1000);
-            return cMilliSecs;
 
         default:
@@ -2472,13 +2091,310 @@
 
 
-/**
- * Gets the current warp drive percent.
- *
- * @returns The warp drive percent.
- * @param   pVM         The VM handle.
- */
-VMMDECL(uint32_t) TMGetWarpDrive(PVM pVM)
-{
-    return pVM->tm.s.u32VirtualWarpDrivePercentage;
+/* -=-=-=-=-=-=- Convenience APIs -=-=-=-=-=-=- */
+
+
+/**
+ * Arm a timer with a (new) expire time relative to current time.
+ *
+ * @returns VBox status.
+ * @param   pTimer          Timer handle as returned by one of the create functions.
+ * @param   cMilliesToNext  Number of milliseconds to the next tick.
+ */
+VMMDECL(int) TMTimerSetMillies(PTMTIMER pTimer, uint32_t cMilliesToNext)
+{
+    PVM    pVM   = pTimer->CTX_SUFF(pVM);
+    PVMCPU pVCpu = &pVM->aCpus[0];  /* just take the first VCPU */
+
+    switch (pTimer->enmClock)
+    {
+        case TMCLOCK_VIRTUAL:
+            AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
+            return TMTimerSetRelative(pTimer, cMilliesToNext * UINT64_C(1000000), NULL);
+
+        case TMCLOCK_VIRTUAL_SYNC:
+            AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
+            return TMTimerSetRelative(pTimer, cMilliesToNext * UINT64_C(1000000), NULL);
+
+        case TMCLOCK_REAL:
+            AssertCompile(TMCLOCK_FREQ_REAL == 1000);
+            return TMTimerSetRelative(pTimer, cMilliesToNext, NULL);
+
+        default:
+            AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
+            return VERR_INTERNAL_ERROR;
+    }
+}
+
+
+/**
+ * Arm a timer with a (new) expire time relative to current time.
+ *
+ * @returns VBox status.
+ * @param   pTimer          Timer handle as returned by one of the create functions.
+ * @param   cMicrosToNext   Number of microseconds to the next tick.
+ */
+VMMDECL(int) TMTimerSetMicro(PTMTIMER pTimer, uint64_t cMicrosToNext)
+{
+    PVM    pVM   = pTimer->CTX_SUFF(pVM);
+    PVMCPU pVCpu = &pVM->aCpus[0];  /* just take the first VCPU */
+
+    switch (pTimer->enmClock)
+    {
+        case TMCLOCK_VIRTUAL:
+            AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
+            return TMTimerSetRelative(pTimer, cMicrosToNext * 1000, NULL);
+
+        case TMCLOCK_VIRTUAL_SYNC:
+            AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
+            return TMTimerSetRelative(pTimer, cMicrosToNext * 1000, NULL);
+
+        case TMCLOCK_REAL:
+            AssertCompile(TMCLOCK_FREQ_REAL == 1000);
+            return TMTimerSetRelative(pTimer, cMicrosToNext / 1000, NULL);
+
+        default:
+            AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
+            return VERR_INTERNAL_ERROR;
+    }
+}
+
+
+/**
+ * Arm a timer with a (new) expire time relative to current time.
+ *
+ * @returns VBox status.
+ * @param   pTimer          Timer handle as returned by one of the create functions.
+ * @param   cNanosToNext    Number of nanoseconds to the next tick.
+ */
+VMMDECL(int) TMTimerSetNano(PTMTIMER pTimer, uint64_t cNanosToNext)
+{
+    PVM    pVM   = pTimer->CTX_SUFF(pVM);
+    PVMCPU pVCpu = &pVM->aCpus[0];  /* just take the first VCPU */
+
+    switch (pTimer->enmClock)
+    {
+        case TMCLOCK_VIRTUAL:
+            AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
+            return TMTimerSetRelative(pTimer, cNanosToNext, NULL);
+
+        case TMCLOCK_VIRTUAL_SYNC:
+            AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
+            return TMTimerSetRelative(pTimer, cNanosToNext, NULL);
+
+        case TMCLOCK_REAL:
+            AssertCompile(TMCLOCK_FREQ_REAL == 1000);
+            return TMTimerSetRelative(pTimer, cNanosToNext / 1000000, NULL);
+
+        default:
+            AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
+            return VERR_INTERNAL_ERROR;
+    }
+}
+
+
+/**
+ * Get the current clock time as nanoseconds.
+ *
+ * @returns The timer clock as nanoseconds.
+ * @param   pTimer          Timer handle as returned by one of the create functions.
+ */
+VMMDECL(uint64_t) TMTimerGetNano(PTMTIMER pTimer)
+{
+    return TMTimerToNano(pTimer, TMTimerGet(pTimer));
+}
+
+
+/**
+ * Get the current clock time as microseconds.
+ *
+ * @returns The timer clock as microseconds.
+ * @param   pTimer          Timer handle as returned by one of the create functions.
+ */
+VMMDECL(uint64_t) TMTimerGetMicro(PTMTIMER pTimer)
+{
+    return TMTimerToMicro(pTimer, TMTimerGet(pTimer));
+}
+
+
+/**
+ * Get the current clock time as milliseconds.
+ *
+ * @returns The timer clock as milliseconds.
+ * @param   pTimer          Timer handle as returned by one of the create functions.
+ */
+VMMDECL(uint64_t) TMTimerGetMilli(PTMTIMER pTimer)
+{
+    return TMTimerToMilli(pTimer, TMTimerGet(pTimer));
+}
+
+
+/**
+ * Converts the specified timer clock time to nanoseconds.
+ *
+ * @returns nanoseconds.
+ * @param   pTimer          Timer handle as returned by one of the create functions.
+ * @param   u64Ticks        The clock ticks.
+ * @remark  There could be rounding errors here. We just do a simple integer divide
+ *          without any adjustments.
+ */
+VMMDECL(uint64_t) TMTimerToNano(PTMTIMER pTimer, uint64_t u64Ticks)
+{
+    switch (pTimer->enmClock)
+    {
+        case TMCLOCK_VIRTUAL:
+        case TMCLOCK_VIRTUAL_SYNC:
+            AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
+            return u64Ticks;
+
+        case TMCLOCK_REAL:
+            AssertCompile(TMCLOCK_FREQ_REAL == 1000);
+            return u64Ticks * 1000000;
+
+        default:
+            AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
+            return 0;
+    }
+}
+
+
+/**
+ * Converts the specified timer clock time to microseconds.
+ *
+ * @returns microseconds.
+ * @param   pTimer          Timer handle as returned by one of the create functions.
+ * @param   u64Ticks        The clock ticks.
+ * @remark  There could be rounding errors here. We just do a simple integer divide
+ *          without any adjustments.
+ */
+VMMDECL(uint64_t) TMTimerToMicro(PTMTIMER pTimer, uint64_t u64Ticks)
+{
+    switch (pTimer->enmClock)
+    {
+        case TMCLOCK_VIRTUAL:
+        case TMCLOCK_VIRTUAL_SYNC:
+            AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
+            return u64Ticks / 1000;
+
+        case TMCLOCK_REAL:
+            AssertCompile(TMCLOCK_FREQ_REAL == 1000);
+            return u64Ticks * 1000;
+
+        default:
+            AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
+            return 0;
+    }
+}
+
+
+/**
+ * Converts the specified timer clock time to milliseconds.
+ *
+ * @returns milliseconds.
+ * @param   pTimer          Timer handle as returned by one of the create functions.
+ * @param   u64Ticks        The clock ticks.
+ * @remark  There could be rounding errors here. We just do a simple integer divide
+ *          without any adjustments.
+ */
+VMMDECL(uint64_t) TMTimerToMilli(PTMTIMER pTimer, uint64_t u64Ticks)
+{
+    switch (pTimer->enmClock)
+    {
+        case TMCLOCK_VIRTUAL:
+        case TMCLOCK_VIRTUAL_SYNC:
+            AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
+            return u64Ticks / 1000000;
+
+        case TMCLOCK_REAL:
+            AssertCompile(TMCLOCK_FREQ_REAL == 1000);
+            return u64Ticks;
+
+        default:
+            AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
+            return 0;
+    }
+}
+
+
+/**
+ * Converts the specified nanosecond timestamp to timer clock ticks.
+ *
+ * @returns timer clock ticks.
+ * @param   pTimer          Timer handle as returned by one of the create functions.
+ * @param   cNanoSecs       The nanosecond value ticks to convert.
+ * @remark  There could be rounding and overflow errors here.
+ */
+VMMDECL(uint64_t) TMTimerFromNano(PTMTIMER pTimer, uint64_t cNanoSecs)
+{
+    switch (pTimer->enmClock)
+    {
+        case TMCLOCK_VIRTUAL:
+        case TMCLOCK_VIRTUAL_SYNC:
+            AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
+            return cNanoSecs;
+
+        case TMCLOCK_REAL:
+            AssertCompile(TMCLOCK_FREQ_REAL == 1000);
+            return cNanoSecs / 1000000;
+
+        default:
+            AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
+            return 0;
+    }
+}
+
+
+/**
+ * Converts the specified microsecond timestamp to timer clock ticks.
+ *
+ * @returns timer clock ticks.
+ * @param   pTimer          Timer handle as returned by one of the create functions.
+ * @param   cMicroSecs      The microsecond value ticks to convert.
+ * @remark  There could be rounding and overflow errors here.
+ */
+VMMDECL(uint64_t) TMTimerFromMicro(PTMTIMER pTimer, uint64_t cMicroSecs)
+{
+    switch (pTimer->enmClock)
+    {
+        case TMCLOCK_VIRTUAL:
+        case TMCLOCK_VIRTUAL_SYNC:
+            AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
+            return cMicroSecs * 1000;
+
+        case TMCLOCK_REAL:
+            AssertCompile(TMCLOCK_FREQ_REAL == 1000);
+            return cMicroSecs / 1000;
+
+        default:
+            AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
+            return 0;
+    }
+}
+
+
+/**
+ * Converts the specified millisecond timestamp to timer clock ticks.
+ *
+ * @returns timer clock ticks.
+ * @param   pTimer          Timer handle as returned by one of the create functions.
+ * @param   cMilliSecs      The millisecond value ticks to convert.
+ * @remark  There could be rounding and overflow errors here.
+ */
+VMMDECL(uint64_t) TMTimerFromMilli(PTMTIMER pTimer, uint64_t cMilliSecs)
+{
+    switch (pTimer->enmClock)
+    {
+        case TMCLOCK_VIRTUAL:
+        case TMCLOCK_VIRTUAL_SYNC:
+            AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
+            return cMilliSecs * 1000000;
+
+        case TMCLOCK_REAL:
+            AssertCompile(TMCLOCK_FREQ_REAL == 1000);
+            return cMilliSecs;
+
+        default:
+            AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
+            return 0;
+    }
 }
 
@@ -2535,5 +2451,5 @@
     if (RT_UNLIKELY(ASMAtomicReadBool(&pVM->tm.s.fHzHintNeedsUpdating)))
     {
-        if (RT_SUCCESS(tmTimerTryLock(pVM)))
+        if (RT_SUCCESS(TM_TRY_LOCK_TIMERS(pVM)))
         {
             ASMAtomicWriteBool(&pVM->tm.s.fHzHintNeedsUpdating, false);
@@ -2576,5 +2492,5 @@
             ASMAtomicWriteU32(&pVM->tm.s.uMaxHzHint, uMaxHzHint);
             Log(("tmGetFrequencyHint: New value %u Hz\n", uMaxHzHint));
-            tmTimerUnlock(pVM);
+            TM_UNLOCK_TIMERS(pVM);
         }
     }
Index: trunk/src/VBox/VMM/VMMAll/TMAllVirtual.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/TMAllVirtual.cpp	(revision 37518)
+++ trunk/src/VBox/VMM/VMMAll/TMAllVirtual.cpp	(revision 37527)
@@ -488,5 +488,5 @@
             *pcNsToDeadline = tmVirtualVirtToNsDeadline(pVM, cNsToDeadline);
         }
-        tmVirtualSyncUnlock(pVM);
+        PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock);
     }
     else
@@ -501,5 +501,5 @@
         Log5(("TMAllVirtual(%u): FF: %d -> 1\n", __LINE__, VMCPU_FF_ISPENDING(pVCpuDst, VMCPU_FF_TIMER)));
         Log4(("TM: %'RU64/-%'8RU64: exp tmr=>ff [vsghcul]\n", u64, pVM->tm.s.offVirtualSync - pVM->tm.s.offVirtualSyncGivenUp));
-        tmVirtualSyncUnlock(pVM);
+        PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock);
 
         if (pcNsToDeadline)
@@ -538,5 +538,5 @@
     {
         u64 = ASMAtomicUoReadU64(&pVM->tm.s.u64VirtualSync);
-        tmVirtualSyncUnlock(pVM);
+        PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock);
         if (pcNsToDeadline)
             *pcNsToDeadline = 0;
@@ -572,5 +572,5 @@
     {
         ASMAtomicWriteU64(&pVM->tm.s.u64VirtualSync, u64);
-        tmVirtualSyncUnlock(pVM);
+        PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock);
         if (pcNsToDeadline)
             *pcNsToDeadline = tmVirtualVirtToNsDeadline(pVM, u64Expire - u64);
@@ -587,5 +587,5 @@
         Log5(("TMAllVirtual(%u): FF: %d -> 1\n", __LINE__, !!VMCPU_FF_ISPENDING(pVCpuDst, VMCPU_FF_TIMER)));
         Log4(("TM: %'RU64/-%'8RU64: exp tmr=>ff [vsgl]\n", u64, pVM->tm.s.offVirtualSync - pVM->tm.s.offVirtualSyncGivenUp));
-        tmVirtualSyncUnlock(pVM);
+        PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock);
 
 #ifdef IN_RING3
@@ -658,5 +658,5 @@
      *       which is less picky or hasn't been adjusted yet
      */
-    if (tmVirtualSyncTryLock(pVM) == VINF_SUCCESS)
+    if (PDMCritSectTryEnter(&pVM->tm.s.VirtualSyncLock) == VINF_SUCCESS)
         return tmVirtualSyncGetLocked(pVM, u64, pcNsToDeadline);
 
@@ -726,5 +726,5 @@
     {
         /* Try grab the lock, things get simpler when owning the lock. */
-        int rcLock = tmVirtualSyncTryLock(pVM);
+        int rcLock = PDMCritSectTryEnter(&pVM->tm.s.VirtualSyncLock);
         if (RT_SUCCESS_NP(rcLock))
             return tmVirtualSyncGetLocked(pVM, u64, pcNsToDeadline);
Index: trunk/src/VBox/VMM/VMMR3/TM.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/TM.cpp	(revision 37518)
+++ trunk/src/VBox/VMM/VMMR3/TM.cpp	(revision 37527)
@@ -1038,5 +1038,5 @@
     LogFlow(("TMR3Reset:\n"));
     VM_ASSERT_EMT(pVM);
-    tmTimerLock(pVM);
+    TM_LOCK_TIMERS(pVM);
 
     /*
@@ -1073,5 +1073,5 @@
     PVMCPU pVCpuDst = &pVM->aCpus[pVM->tm.s.idTimerCpu];
     VMCPU_FF_CLEAR(pVCpuDst, VMCPU_FF_TIMER); /** @todo FIXME: this isn't right. */
-    tmTimerUnlock(pVM);
+    TM_UNLOCK_TIMERS(pVM);
 }
 
@@ -1302,5 +1302,5 @@
 
     /* insert into the list of created timers. */
-    tmTimerLock(pVM);
+    TM_LOCK_TIMERS(pVM);
     pTimer->pBigPrev        = NULL;
     pTimer->pBigNext        = pVM->tm.s.pCreated;
@@ -1311,5 +1311,5 @@
     tmTimerQueuesSanityChecks(pVM, "tmR3TimerCreate");
 #endif
-    tmTimerUnlock(pVM);
+    TM_UNLOCK_TIMERS(pVM);
 
     *ppTimer = pTimer;
@@ -1531,5 +1531,5 @@
      * like create does. All the work is done here.
      */
-    tmTimerLock(pVM);
+    TM_LOCK_TIMERS(pVM);
     for (int cRetries = 1000;; cRetries--)
     {
@@ -1569,10 +1569,10 @@
             case TMTIMERSTATE_PENDING_RESCHEDULE_SET_EXPIRE:
                 AssertMsgFailed(("%p:.enmState=%s %s\n", pTimer, tmTimerState(enmState), pTimer->pszDesc));
-                tmTimerUnlock(pVM);
+                TM_UNLOCK_TIMERS(pVM);
                 if (!RTThreadYield())
                     RTThreadSleep(1);
                 AssertMsgReturn(cRetries > 0, ("Failed waiting for stable state. state=%d (%s)\n", pTimer->enmState, pTimer->pszDesc),
                                 VERR_TM_UNSTABLE_STATE);
-                tmTimerLock(pVM);
+                TM_LOCK_TIMERS(pVM);
                 continue;
 
@@ -1582,10 +1582,10 @@
             case TMTIMERSTATE_FREE:
             case TMTIMERSTATE_DESTROY:
-                tmTimerUnlock(pVM);
+                TM_UNLOCK_TIMERS(pVM);
                 AssertLogRelMsgFailedReturn(("pTimer=%p %s\n", pTimer, tmTimerState(enmState)), VERR_TM_INVALID_STATE);
 
             default:
                 AssertMsgFailed(("Unknown timer state %d (%s)\n", enmState, R3STRING(pTimer->pszDesc)));
-                tmTimerUnlock(pVM);
+                TM_UNLOCK_TIMERS(pVM);
                 return VERR_TM_UNKNOWN_STATE;
         }
@@ -1600,8 +1600,8 @@
             break;
         AssertMsgFailed(("%p:.enmState=%s %s\n", pTimer, tmTimerState(enmState), pTimer->pszDesc));
-        tmTimerUnlock(pVM);
+        TM_UNLOCK_TIMERS(pVM);
         AssertMsgReturn(cRetries > 0, ("Failed waiting for stable state. state=%d (%s)\n", pTimer->enmState, pTimer->pszDesc),
                         VERR_TM_UNSTABLE_STATE);
-        tmTimerLock(pVM);
+        TM_LOCK_TIMERS(pVM);
     }
 
@@ -1661,5 +1661,5 @@
     tmTimerQueuesSanityChecks(pVM, "TMR3TimerDestroy");
 #endif
-    tmTimerUnlock(pVM);
+    TM_UNLOCK_TIMERS(pVM);
     return VINF_SUCCESS;
 }
@@ -1679,5 +1679,5 @@
         return VERR_INVALID_PARAMETER;
 
-    tmTimerLock(pVM);
+    TM_LOCK_TIMERS(pVM);
     PTMTIMER    pCur = pVM->tm.s.pCreated;
     while (pCur)
@@ -1692,5 +1692,5 @@
         }
     }
-    tmTimerUnlock(pVM);
+    TM_UNLOCK_TIMERS(pVM);
 
     LogFlow(("TMR3TimerDestroyDevice: returns VINF_SUCCESS\n"));
@@ -1712,5 +1712,5 @@
         return VERR_INVALID_PARAMETER;
 
-    tmTimerLock(pVM);
+    TM_LOCK_TIMERS(pVM);
     PTMTIMER    pCur = pVM->tm.s.pCreated;
     while (pCur)
@@ -1725,5 +1725,5 @@
         }
     }
-    tmTimerUnlock(pVM);
+    TM_UNLOCK_TIMERS(pVM);
 
     LogFlow(("TMR3TimerDestroyUsb: returns VINF_SUCCESS\n"));
@@ -1745,5 +1745,5 @@
         return VERR_INVALID_PARAMETER;
 
-    tmTimerLock(pVM);
+    TM_LOCK_TIMERS(pVM);
     PTMTIMER    pCur = pVM->tm.s.pCreated;
     while (pCur)
@@ -1758,5 +1758,5 @@
         }
     }
-    tmTimerUnlock(pVM);
+    TM_UNLOCK_TIMERS(pVM);
 
     LogFlow(("TMR3TimerDestroyDriver: returns VINF_SUCCESS\n"));
@@ -1902,5 +1902,5 @@
     Assert(!pVM->tm.s.fRunningQueues);
     ASMAtomicWriteBool(&pVM->tm.s.fRunningQueues, true);
-    tmTimerLock(pVM);
+    TM_LOCK_TIMERS(pVM);
 
     /*
@@ -1911,5 +1911,5 @@
     /* TMCLOCK_VIRTUAL_SYNC (see also TMR3VirtualSyncFF) */
     STAM_PROFILE_ADV_START(&pVM->tm.s.aStatDoQueues[TMCLOCK_VIRTUAL_SYNC], s1);
-    tmVirtualSyncLock(pVM);
+    PDMCritSectEnter(&pVM->tm.s.VirtualSyncLock, VERR_IGNORED);
     ASMAtomicWriteBool(&pVM->tm.s.fRunningVirtualSyncQueue, true);
     VMCPU_FF_CLEAR(pVCpuDst, VMCPU_FF_TIMER);   /* Clear the FF once we started working for real. */
@@ -1921,5 +1921,5 @@
 
     ASMAtomicWriteBool(&pVM->tm.s.fRunningVirtualSyncQueue, false);
-    tmVirtualSyncUnlock(pVM);
+    PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock);
     STAM_PROFILE_ADV_STOP(&pVM->tm.s.aStatDoQueues[TMCLOCK_VIRTUAL_SYNC], s1);
 
@@ -1949,5 +1949,5 @@
     Log2(("TMR3TimerQueuesDo: returns void\n"));
     ASMAtomicWriteBool(&pVM->tm.s.fRunningQueues, false);
-    tmTimerUnlock(pVM);
+    TM_UNLOCK_TIMERS(pVM);
     STAM_PROFILE_STOP(&pVM->tm.s.StatDoQueues, a);
 }
@@ -2379,18 +2379,18 @@
     {
         STAM_PROFILE_START(&pVM->tm.s.StatVirtualSyncFF, a);
-        tmVirtualSyncLock(pVM);
+        PDMCritSectEnter(&pVM->tm.s.VirtualSyncLock, VERR_IGNORED);
         if (pVM->tm.s.fVirtualSyncTicking)
         {
             STAM_PROFILE_STOP(&pVM->tm.s.StatVirtualSyncFF, a); /* before the unlock! */
-            tmVirtualSyncUnlock(pVM);
+            PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock);
             Log2(("TMR3VirtualSyncFF: ticking\n"));
         }
         else
         {
-            tmVirtualSyncUnlock(pVM);
+            PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock);
 
             /* try run it. */
-            tmTimerLock(pVM);
-            tmVirtualSyncLock(pVM);
+            TM_LOCK_TIMERS(pVM);
+            PDMCritSectEnter(&pVM->tm.s.VirtualSyncLock, VERR_IGNORED);
             if (pVM->tm.s.fVirtualSyncTicking)
                 Log2(("TMR3VirtualSyncFF: ticking (2)\n"));
@@ -2408,6 +2408,6 @@
             }
             STAM_PROFILE_STOP(&pVM->tm.s.StatVirtualSyncFF, a); /* before the unlock! */
-            tmVirtualSyncUnlock(pVM);
-            tmTimerUnlock(pVM);
+            PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock);
+            TM_UNLOCK_TIMERS(pVM);
         }
     }
@@ -2495,8 +2495,10 @@
     }
 
-    /* Enter the critical section to make TMTimerSet/Stop happy. */
+    /* Enter the critical sections to make TMTimerSet/Stop happy. */
+    if (pTimer->enmClock == TMCLOCK_VIRTUAL_SYNC)
+        PDMCritSectEnter(&pTimer->pVMR3->tm.s.VirtualSyncLock, VERR_IGNORED);
     PPDMCRITSECT pCritSect = pTimer->pCritSect;
     if (pCritSect)
-        PDMCritSectEnter(pCritSect, VERR_INTERNAL_ERROR);
+        PDMCritSectEnter(pCritSect, VERR_IGNORED);
 
     if (u8State == TMTIMERSTATE_SAVED_PENDING_SCHEDULE)
@@ -2527,4 +2529,6 @@
     if (pCritSect)
         PDMCritSectLeave(pCritSect);
+    if (pTimer->enmClock == TMCLOCK_VIRTUAL_SYNC)
+        PDMCritSectLeave(&pTimer->pVMR3->tm.s.VirtualSyncLock);
 
     /*
@@ -2611,7 +2615,7 @@
      * The shared virtual clock (includes virtual sync which is tied to it).
      */
-    tmTimerLock(pVM);                           /* Paranoia: Exploiting the timer lock here. */
+    TM_LOCK_TIMERS(pVM);                        /* Paranoia: Exploiting the timer lock here. */
     int rc = tmVirtualPauseLocked(pVM);
-    tmTimerUnlock(pVM);
+    TM_UNLOCK_TIMERS(pVM);
     if (RT_FAILURE(rc))
         return rc;
@@ -2675,7 +2679,7 @@
      * The shared virtual clock (includes virtual sync which is tied to it).
      */
-    tmTimerLock(pVM);                           /* Paranoia: Exploiting the timer lock here. */
+    TM_LOCK_TIMERS(pVM);                        /* Paranoia: Exploiting the timer lock here. */
     rc = tmVirtualResumeLocked(pVM);
-    tmTimerUnlock(pVM);
+    TM_UNLOCK_TIMERS(pVM);
 
     return rc;
@@ -2722,5 +2726,5 @@
      * the warp drive settings.
      */
-    tmTimerLock(pVM);                           /* Paranoia: Exploiting the timer lock here. */
+    TM_LOCK_TIMERS(pVM);                        /* Paranoia: Exploiting the timer lock here. */
     bool fPaused = !!pVM->tm.s.cVirtualTicking;
     if (fPaused) /** @todo this isn't really working, but wtf. */
@@ -2734,5 +2738,5 @@
     if (fPaused)
         TMR3NotifyResume(pVM, pVCpu);
-    tmTimerUnlock(pVM);
+    TM_UNLOCK_TIMERS(pVM);
     return VINF_SUCCESS;
 }
@@ -2963,5 +2967,5 @@
                                                 "HzHint",
                                                 "State");
-    tmTimerLock(pVM);
+    TM_LOCK_TIMERS(pVM);
     for (PTMTIMERR3 pTimer = pVM->tm.s.pCreated; pTimer; pTimer = pTimer->pBigNext)
     {
@@ -2979,5 +2983,5 @@
                         pTimer->pszDesc);
     }
-    tmTimerUnlock(pVM);
+    TM_UNLOCK_TIMERS(pVM);
 }
 
@@ -3007,5 +3011,5 @@
     for (unsigned iQueue = 0; iQueue < TMCLOCK_MAX; iQueue++)
     {
-        tmTimerLock(pVM);
+        TM_LOCK_TIMERS(pVM);
         for (PTMTIMERR3 pTimer = TMTIMER_GET_HEAD(&pVM->tm.s.paTimerQueuesR3[iQueue]);
              pTimer;
@@ -3025,5 +3029,5 @@
                             pTimer->pszDesc);
         }
-        tmTimerUnlock(pVM);
+        TM_UNLOCK_TIMERS(pVM);
     }
 }
Index: trunk/src/VBox/VMM/include/TMInternal.h
===================================================================
--- trunk/src/VBox/VMM/include/TMInternal.h	(revision 37518)
+++ trunk/src/VBox/VMM/include/TMInternal.h	(revision 37527)
@@ -722,23 +722,4 @@
 typedef TMCPU *PTMCPU;
 
-#if 0 /* enable this to rule out locking bugs on single cpu guests. */
-# define tmTimerLock(pVM)                VINF_SUCCESS
-# define tmTimerTryLock(pVM)             VINF_SUCCESS
-# define tmTimerUnlock(pVM)              ((void)0)
-# define tmVirtualSyncLock(pVM)     VINF_SUCCESS
-# define tmVirtualSyncTryLock(pVM)  VINF_SUCCESS
-# define tmVirtualSyncUnlock(pVM)   ((void)0)
-# define TM_ASSERT_LOCK(pVM)        VM_ASSERT_EMT(pVM)
-#else
-int                     tmTimerLock(PVM pVM);
-int                     tmTimerTryLock(PVM pVM);
-void                    tmTimerUnlock(PVM pVM);
-/** Checks that the caller owns the timer lock.  */
-#define TM_ASSERT_LOCK(pVM) Assert(PDMCritSectIsOwner(&pVM->tm.s.TimerCritSect))
-int                     tmVirtualSyncLock(PVM pVM);
-int                     tmVirtualSyncTryLock(PVM pVM);
-void                    tmVirtualSyncUnlock(PVM pVM);
-#endif
-
 const char             *tmTimerState(TMTIMERSTATE enmState);
 void                    tmTimerQueueSchedule(PVM pVM, PTMTIMERQUEUE pQueue);
@@ -756,4 +737,36 @@
 
 
+/**
+ * Try take the timer lock, wait in ring-3 return VERR_SEM_BUSY in R0/RC.
+ *
+ * @retval  VINF_SUCCESS on success (always in ring-3).
+ * @retval  VERR_SEM_BUSY in RC and R0 if the semaphore is busy.
+ *
+ * @param   a_pVM       The VM handle.
+ *
+ * @remarks The virtual sync timer queue requires the virtual sync lock.
+ */
+#define TM_LOCK_TIMERS(a_pVM)       PDMCritSectEnter(&(a_pVM)->tm.s.TimerCritSect, VERR_SEM_BUSY)
+
+/**
+ * Try take the timer lock, no waiting.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_SEM_BUSY if busy.
+ *
+ * @param   a_pVM       The VM handle.
+ *
+ * @remarks The virtual sync timer queue requires the virtual sync lock.
+ */
+#define TM_TRY_LOCK_TIMERS(a_pVM)   PDMCritSectTryEnter(&(a_pVM)->tm.s.TimerCritSect)
+
+/** Lock the timers (sans the virtual sync queue). */
+#define TM_UNLOCK_TIMERS(a_pVM)     do { PDMCritSectLeave(&(a_pVM)->tm.s.TimerCritSect); } while (0)
+
+/** Checks that the caller owns the timer lock.  */
+#define TM_ASSERT_TIMER_LOCK_OWNERSHIP(a_pVM) \
+    Assert(PDMCritSectIsOwner(&(a_pVM)->tm.s.TimerCritSect))
+
+
 /** @} */
 
