Index: /trunk/include/VBox/vmm/tm.h
===================================================================
--- /trunk/include/VBox/vmm/tm.h	(revision 87765)
+++ /trunk/include/VBox/vmm/tm.h	(revision 87766)
@@ -215,8 +215,8 @@
  *
  * @param   pVM             The cross context VM structure.
- * @param   pTimer          The timer handle.
+ * @param   hTimer          The timer handle.
  * @param   pvUser          User argument specified upon timer creation.
  */
-typedef DECLCALLBACKTYPE(void, FNTMTIMERINT,(PVM pVM, PTMTIMER pTimer, void *pvUser));
+typedef DECLCALLBACKTYPE(void, FNTMTIMERINT,(PVM pVM, TMTIMERHANDLE hTimer, void *pvUser));
 /** Pointer to internal timer callback function. */
 typedef FNTMTIMERINT *PFNTMTIMERINT;
@@ -231,31 +231,28 @@
 typedef FNTMTIMEREXT *PFNTMTIMEREXT;
 
-VMMDECL(PTMTIMERR3)     TMTimerR3Ptr(PTMTIMER pTimer);
-VMMDECL(PTMTIMERR0)     TMTimerR0Ptr(PTMTIMER pTimer);
-VMMDECL(PTMTIMERRC)     TMTimerRCPtr(PTMTIMER pTimer);
-VMMDECL(int)            TMTimerLock(PTMTIMER pTimer, int rcBusy);
-VMMDECL(void)           TMTimerUnlock(PTMTIMER pTimer);
-VMMDECL(bool)           TMTimerIsLockOwner(PTMTIMER pTimer);
-VMMDECL(int)            TMTimerSet(PTMTIMER pTimer, uint64_t u64Expire);
-VMMDECL(int)            TMTimerSetRelative(PTMTIMER pTimer, uint64_t cTicksToNext, uint64_t *pu64Now);
-VMMDECL(int)            TMTimerSetFrequencyHint(PTMTIMER pTimer, uint32_t uHz);
-VMMDECL(uint64_t)       TMTimerGet(PTMTIMER pTimer);
-VMMDECL(int)            TMTimerStop(PTMTIMER pTimer);
-VMMDECL(bool)           TMTimerIsActive(PTMTIMER pTimer);
-
-VMMDECL(int)            TMTimerSetMillies(PTMTIMER pTimer, uint32_t cMilliesToNext);
-VMMDECL(int)            TMTimerSetMicro(PTMTIMER pTimer, uint64_t cMicrosToNext);
-VMMDECL(int)            TMTimerSetNano(PTMTIMER pTimer, uint64_t cNanosToNext);
-VMMDECL(uint64_t)       TMTimerGetNano(PTMTIMER pTimer);
-VMMDECL(uint64_t)       TMTimerGetMicro(PTMTIMER pTimer);
-VMMDECL(uint64_t)       TMTimerGetMilli(PTMTIMER pTimer);
-VMMDECL(uint64_t)       TMTimerGetFreq(PTMTIMER pTimer);
-VMMDECL(uint64_t)       TMTimerGetExpire(PTMTIMER pTimer);
-VMMDECL(uint64_t)       TMTimerToNano(PTMTIMER pTimer, uint64_t cTicks);
-VMMDECL(uint64_t)       TMTimerToMicro(PTMTIMER pTimer, uint64_t cTicks);
-VMMDECL(uint64_t)       TMTimerToMilli(PTMTIMER pTimer, uint64_t cTicks);
-VMMDECL(uint64_t)       TMTimerFromNano(PTMTIMER pTimer, uint64_t cNanoSecs);
-VMMDECL(uint64_t)       TMTimerFromMicro(PTMTIMER pTimer, uint64_t cMicroSecs);
-VMMDECL(uint64_t)       TMTimerFromMilli(PVMCC pVM, PTMTIMER pTimer, uint64_t cMilliSecs);
+VMMDECL(int)            TMTimerLock(PVMCC pVM, TMTIMERHANDLE hTimer, int rcBusy);
+VMMDECL(void)           TMTimerUnlock(PVMCC pVM, TMTIMERHANDLE hTimer);
+VMMDECL(bool)           TMTimerIsLockOwner(PVMCC pVM, TMTIMERHANDLE hTimer);
+VMMDECL(int)            TMTimerSet(PVMCC pVM, TMTIMERHANDLE hTimer, uint64_t u64Expire);
+VMMDECL(int)            TMTimerSetRelative(PVMCC pVM, TMTIMERHANDLE hTimer, uint64_t cTicksToNext, uint64_t *pu64Now);
+VMMDECL(int)            TMTimerSetFrequencyHint(PVMCC pVM, TMTIMERHANDLE hTimer, uint32_t uHz);
+VMMDECL(uint64_t)       TMTimerGet(PVMCC pVM, TMTIMERHANDLE hTimer);
+VMMDECL(int)            TMTimerStop(PVMCC pVM, TMTIMERHANDLE hTimer);
+VMMDECL(bool)           TMTimerIsActive(PVMCC pVM, TMTIMERHANDLE hTimer);
+
+VMMDECL(int)            TMTimerSetMillies(PVMCC pVM, TMTIMERHANDLE hTimer, uint32_t cMilliesToNext);
+VMMDECL(int)            TMTimerSetMicro(PVMCC pVM, TMTIMERHANDLE hTimer, uint64_t cMicrosToNext);
+VMMDECL(int)            TMTimerSetNano(PVMCC pVM, TMTIMERHANDLE hTimer, uint64_t cNanosToNext);
+VMMDECL(uint64_t)       TMTimerGetNano(PVMCC pVM, TMTIMERHANDLE hTimer);
+VMMDECL(uint64_t)       TMTimerGetMicro(PVMCC pVM, TMTIMERHANDLE hTimer);
+VMMDECL(uint64_t)       TMTimerGetMilli(PVMCC pVM, TMTIMERHANDLE hTimer);
+VMMDECL(uint64_t)       TMTimerGetFreq(PVMCC pVM, TMTIMERHANDLE hTimer);
+VMMDECL(uint64_t)       TMTimerGetExpire(PVMCC pVM, TMTIMERHANDLE hTimer);
+VMMDECL(uint64_t)       TMTimerToNano(PVMCC pVM, TMTIMERHANDLE hTimer, uint64_t cTicks);
+VMMDECL(uint64_t)       TMTimerToMicro(PVMCC pVM, TMTIMERHANDLE hTimer, uint64_t cTicks);
+VMMDECL(uint64_t)       TMTimerToMilli(PVMCC pVM, TMTIMERHANDLE hTimer, uint64_t cTicks);
+VMMDECL(uint64_t)       TMTimerFromNano(PVMCC pVM, TMTIMERHANDLE hTimer, uint64_t cNanoSecs);
+VMMDECL(uint64_t)       TMTimerFromMicro(PVMCC pVM, TMTIMERHANDLE hTimer, uint64_t cMicroSecs);
+VMMDECL(uint64_t)       TMTimerFromMilli(PVMCC pVM, TMTIMERHANDLE hTimer, uint64_t cMilliSecs);
 
 VMMDECL(bool)           TMTimerPollBool(PVMCC pVM, PVMCPUCC pVCpu);
@@ -275,17 +272,20 @@
 VMM_INT_DECL(void)      TMR3Reset(PVM pVM);
 VMM_INT_DECL(int)       TMR3GetImportRC(PVM pVM, const char *pszSymbol, PRTRCPTR pRCPtrValue);
-VMM_INT_DECL(int)       TMR3TimerCreateDevice(PVM pVM, PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, void *pvUser, uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer);
-VMM_INT_DECL(int)       TMR3TimerCreateUsb(PVM pVM, PPDMUSBINS pUsbIns, TMCLOCK enmClock, PFNTMTIMERUSB pfnCallback, void *pvUser, uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer);
-VMM_INT_DECL(int)       TMR3TimerCreateDriver(PVM pVM, PPDMDRVINS pDrvIns, TMCLOCK enmClock, PFNTMTIMERDRV pfnCallback, void *pvUser, uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer);
+VMM_INT_DECL(int)       TMR3TimerCreateDevice(PVM pVM, PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback,
+                                              void *pvUser, uint32_t fFlags, const char *pszDesc, PTMTIMERHANDLE phTimer);
+VMM_INT_DECL(int)       TMR3TimerCreateUsb(PVM pVM, PPDMUSBINS pUsbIns, TMCLOCK enmClock, PFNTMTIMERUSB pfnCallback,
+                                           void *pvUser, uint32_t fFlags, const char *pszDesc, PTMTIMERHANDLE phTimer);
+VMM_INT_DECL(int)       TMR3TimerCreateDriver(PVM pVM, PPDMDRVINS pDrvIns, TMCLOCK enmClock, PFNTMTIMERDRV pfnCallback,
+                                              void *pvUser, uint32_t fFlags, const char *pszDesc, PTMTIMERHANDLE phTimer);
 VMMR3DECL(int)          TMR3TimerCreate(PVM pVM, TMCLOCK enmClock, PFNTMTIMERINT pfnCallback, void *pvUser, uint32_t fFlags,
-                                        const char *pszDesc, PPTMTIMERR3 ppTimer);
-VMMR3DECL(int)          TMR3TimerDestroy(PTMTIMER pTimer);
+                                        const char *pszDesc, PTMTIMERHANDLE phTimer);
+VMMR3DECL(int)          TMR3TimerDestroy(PVM pVM, TMTIMERHANDLE hTimer);
 VMM_INT_DECL(int)       TMR3TimerDestroyDevice(PVM pVM, PPDMDEVINS pDevIns);
 VMM_INT_DECL(int)       TMR3TimerDestroyUsb(PVM pVM, PPDMUSBINS pUsbIns);
 VMM_INT_DECL(int)       TMR3TimerDestroyDriver(PVM pVM, PPDMDRVINS pDrvIns);
-VMMR3DECL(int)          TMR3TimerSave(PTMTIMERR3 pTimer, PSSMHANDLE pSSM);
-VMMR3DECL(int)          TMR3TimerLoad(PTMTIMERR3 pTimer, PSSMHANDLE pSSM);
+VMMR3DECL(int)          TMR3TimerSave(PVMCC pVM, TMTIMERHANDLE hTimer, PSSMHANDLE pSSM);
+VMMR3DECL(int)          TMR3TimerLoad(PVMCC pVM, TMTIMERHANDLE hTimer, PSSMHANDLE pSSM);
 VMMR3DECL(int)          TMR3TimerSkip(PSSMHANDLE pSSM, bool *pfActive);
-VMMR3DECL(int)          TMR3TimerSetCritSect(PTMTIMERR3 pTimer, PPDMCRITSECT pCritSect);
+VMMR3DECL(int)          TMR3TimerSetCritSect(PVMCC pVM, TMTIMERHANDLE hTimer, PPDMCRITSECT pCritSect);
 VMMR3DECL(void)         TMR3TimerQueuesDo(PVM pVM);
 VMMR3_INT_DECL(void)    TMR3VirtualSyncFF(PVM pVM, PVMCPU pVCpu);
Index: /trunk/src/VBox/Devices/VMMDev/VMMDev.cpp
===================================================================
--- /trunk/src/VBox/Devices/VMMDev/VMMDev.cpp	(revision 87765)
+++ /trunk/src/VBox/Devices/VMMDev/VMMDev.cpp	(revision 87766)
@@ -513,9 +513,9 @@
 static DECLCALLBACK(void) vmmDevHeartbeatFlatlinedTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
 {
-    RT_NOREF(pDevIns);
+    RT_NOREF(pDevIns, pTimer);
     PVMMDEV pThis = (PVMMDEV)pvUser;
     if (pThis->fHeartbeatActive)
     {
-        uint64_t cNsElapsed = TMTimerGetNano(pTimer) - pThis->nsLastHeartbeatTS;
+        uint64_t cNsElapsed = PDMDevHlpTimerGetNano(pDevIns, pThis->hFlatlinedTimer) - pThis->nsLastHeartbeatTS;
         if (   !pThis->fFlatlined
             && cNsElapsed >= pThis->cNsHeartbeatInterval)
Index: /trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp	(revision 87765)
+++ /trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp	(revision 87766)
@@ -2335,5 +2335,5 @@
     VMCPU_ASSERT_EMT(pVCpu);
     uint64_t const cTicksToNext = uTimer << cShift;
-    return TMTimerSetRelative(pVCpu->cpum.s.CTX_SUFF(pNestedVmxPreemptTimer), cTicksToNext, pu64EntryTick);
+    return TMTimerSetRelative(pVCpu->CTX_SUFF(pVM), pVCpu->cpum.s.hNestedVmxPreemptTimer, cTicksToNext, pu64EntryTick);
 }
 
@@ -2353,18 +2353,22 @@
     /*
      * CPUM gets initialized before TM, so we defer creation of timers till CPUMR3InitCompleted().
-     * However, we still get called during CPUMR3Init() and hence we need to check if we  have
+     * However, we still get called during CPUMR3Init() and hence we need to check if we have
      * a valid timer object before trying to stop it.
      */
-    PTMTIMER pTimer = pVCpu->cpum.s.CTX_SUFF(pNestedVmxPreemptTimer);
-    if (!pTimer)
-        return VERR_NOT_FOUND;
-
-    int rc = TMTimerLock(pTimer, VERR_IGNORED);
-    if (rc == VINF_SUCCESS)
-    {
-        if (TMTimerIsActive(pTimer))
-            TMTimerStop(pTimer);
-        TMTimerUnlock(pTimer);
-    }
+    int rc;
+    TMTIMERHANDLE hTimer = pVCpu->cpum.s.hNestedVmxPreemptTimer;
+    if (hTimer != NIL_TMTIMERHANDLE)
+    {
+        PVMCC pVM = pVCpu->CTX_SUFF(pVM);
+        rc = TMTimerLock(pVM, hTimer, VERR_IGNORED);
+        if (rc == VINF_SUCCESS)
+        {
+            if (TMTimerIsActive(pVM, hTimer))
+                TMTimerStop(pVM, hTimer);
+            TMTimerUnlock(pVM, hTimer);
+        }
+    }
+    else
+        rc = VERR_NOT_FOUND;
     return rc;
 }
Index: /trunk/src/VBox/VMM/VMMAll/GIMAllHv.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/GIMAllHv.cpp	(revision 87765)
+++ /trunk/src/VBox/VMM/VMMAll/GIMAllHv.cpp	(revision 87766)
@@ -509,6 +509,7 @@
 VMM_INT_DECL(void) gimHvStartStimer(PVMCPUCC pVCpu, PCGIMHVSTIMER pHvStimer)
 {
-    PTMTIMER pTimer = pHvStimer->CTX_SUFF(pTimer);
-    Assert(TMTimerIsLockOwner(pTimer));
+    PVMCC pVM = pVCpu->CTX_SUFF(pVM);
+    TMTIMERHANDLE hTimer = pHvStimer->hTimer;
+    Assert(TMTimerIsLockOwner(pVM, hTimer));
 
     uint64_t const uTimerCount = pHvStimer->uStimerCountMsr;
@@ -520,5 +521,5 @@
         if (MSR_GIM_HV_STIMER_IS_PERIODIC(pHvStimer->uStimerConfigMsr))
         {
-            TMTimerSetNano(pTimer, uTimerCountNS);
+            TMTimerSetNano(pVM, hTimer, uTimerCountNS);
             LogFlow(("GIM%u: HyperV: Started relative periodic STIMER%u with uTimerCountNS=%RU64\n", pVCpu->idCpu,
                      pHvStimer->idxStimer, uTimerCountNS));
@@ -532,5 +533,5 @@
             {
                 uint64_t const uRelativeNS = uTimerCountNS - uCurRefTimeNS;
-                TMTimerSetNano(pTimer, uRelativeNS);
+                TMTimerSetNano(pVM, hTimer, uRelativeNS);
                 LogFlow(("GIM%u: HyperV: Started one-shot relative STIMER%u with uRelativeNS=%RU64\n", pVCpu->idCpu,
                          pHvStimer->idxStimer, uRelativeNS));
@@ -554,12 +555,11 @@
 {
     VMCPU_ASSERT_EMT_OR_NOT_RUNNING(pVCpu);
-    RT_NOREF(pVCpu);
-
-    PTMTIMER pTimer = pHvStimer->CTX_SUFF(pTimer);
-    Assert(TMTimerIsLockOwner(pTimer));
-    RT_NOREF(pTimer);
-
-    if (TMTimerIsActive(pHvStimer->CTX_SUFF(pTimer)))
-        TMTimerStop(pHvStimer->CTX_SUFF(pTimer));
+    PVMCC pVM = pVCpu->CTX_SUFF(pVM);
+
+    TMTIMERHANDLE hTimer = pHvStimer->hTimer;
+    Assert(TMTimerIsLockOwner(pVM, hTimer));
+
+    if (TMTimerIsActive(pVM, hTimer))
+        TMTimerStop(pVM, hTimer);
 }
 
@@ -757,5 +757,5 @@
 {
     NOREF(pRange);
-    PVM    pVM = pVCpu->CTX_SUFF(pVM);
+    PVMCC  pVM = pVCpu->CTX_SUFF(pVM);
     PGIMHV pHv = &pVM->gim.s.u.Hv;
 
@@ -1153,8 +1153,7 @@
                 Assert(idxStimer < RT_ELEMENTS(pHvCpu->aStimers));
                 PGIMHVSTIMER pHvStimer = &pHvCpu->aStimers[idxStimer];
-                PTMTIMER     pTimer    = pHvStimer->CTX_SUFF(pTimer);
 
                 /* Lock to prevent concurrent access from the timer callback. */
-                int rc = TMTimerLock(pTimer, VERR_IGNORED);
+                int rc = TMTimerLock(pVM, pHvStimer->hTimer, VERR_IGNORED);
                 if (rc == VINF_SUCCESS)
                 {
@@ -1176,5 +1175,5 @@
                         if (!MSR_GIM_HV_STIMER_IS_AUTO_ENABLED(uRawValue))
                         {
-                            if (!TMTimerIsActive(pHvStimer->CTX_SUFF(pTimer)))
+                            if (!TMTimerIsActive(pVM, pHvStimer->hTimer))
                             {
                                 gimHvStartStimer(pVCpu, pHvStimer);
@@ -1197,5 +1196,5 @@
                     }
 
-                    TMTimerUnlock(pTimer);
+                    TMTimerUnlock(pVM, pHvStimer->hTimer);
                 }
                 return rc;
@@ -1239,11 +1238,10 @@
             if (MSR_GIM_HV_STIMER_IS_AUTO_ENABLED(pHvStimer->uStimerConfigMsr))
             {
-                PTMTIMER pTimer = pHvStimer->CTX_SUFF(pTimer);
-                int rc = TMTimerLock(pTimer, rcBusy);
+                int rc = TMTimerLock(pVM, pHvStimer->hTimer, rcBusy);
                 if (rc == VINF_SUCCESS)
                 {
                     pHvStimer->uStimerCountMsr = uRawValue;
                     gimHvStartStimer(pVCpu, pHvStimer);
-                    TMTimerUnlock(pTimer);
+                    TMTimerUnlock(pVM, pHvStimer->hTimer);
                     Log(("GIM%u: HyperV: Set STIMER_COUNT%u=%RU64 %RU64 msec, auto-started timer\n", pVCpu->idCpu, idxStimer,
                          uRawValue, (uRawValue * 100) / RT_NS_1MS_64));
Index: /trunk/src/VBox/VMM/VMMAll/PDMAllQueue.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/PDMAllQueue.cpp	(revision 87765)
+++ /trunk/src/VBox/VMM/VMMAll/PDMAllQueue.cpp	(revision 87766)
@@ -111,5 +111,5 @@
 #endif
 
-    if (!pQueue->pTimer)
+    if (pQueue->hTimer == NIL_TMTIMERHANDLE)
         pdmQueueSetFF(pQueue);
     STAM_REL_COUNTER_INC(&pQueue->StatInsert);
Index: /trunk/src/VBox/VMM/VMMAll/TMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/TMAll.cpp	(revision 87765)
+++ /trunk/src/VBox/VMM/VMMAll/TMAll.cpp	(revision 87766)
@@ -1102,69 +1102,23 @@
 
 /**
- * Gets the host context ring-3 pointer of the timer.
- *
- * @returns HC R3 pointer.
- * @param   pTimer      Timer handle as returned by one of the create functions.
- */
-VMMDECL(PTMTIMERR3) TMTimerR3Ptr(PTMTIMER pTimer)
-{
-#ifdef IN_RING0
-    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
-#endif
-    return (PTMTIMERR3)MMHyperCCToR3(pTimer->CTX_SUFF(pVM), pTimer);
-}
-
-
-/**
- * Gets the host context ring-0 pointer of the timer.
- *
- * @returns HC R0 pointer.
- * @param   pTimer      Timer handle as returned by one of the create functions.
- */
-VMMDECL(PTMTIMERR0) TMTimerR0Ptr(PTMTIMER pTimer)
-{
-#ifdef IN_RING0
-    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
-#endif
-    return (PTMTIMERR0)MMHyperCCToR0(pTimer->CTX_SUFF(pVM), pTimer);
-}
-
-
-/**
- * Gets the RC pointer of the timer.
- *
- * @returns RC pointer.
- * @param   pTimer      Timer handle as returned by one of the create functions.
- */
-VMMDECL(PTMTIMERRC) TMTimerRCPtr(PTMTIMER pTimer)
-{
-#ifdef IN_RING0
-    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
-#endif
-    return (PTMTIMERRC)MMHyperCCToRC(pTimer->CTX_SUFF(pVM), pTimer);
-}
-
-
-/**
  * Locks the timer clock.
  *
  * @returns VINF_SUCCESS on success, @a rcBusy if busy, and VERR_NOT_SUPPORTED
  *          if the clock does not have a lock.
- * @param   pTimer              The timer which clock lock we wish to take.
- * @param   rcBusy              What to return in ring-0 and raw-mode context
- *                              if the lock is busy.  Pass VINF_SUCCESS to
- *                              acquired the critical section thru a ring-3
-                                call if necessary.
+ * @param   pVM         The cross context VM structure.
+ * @param   hTimer      Timer handle as returned by one of the create functions.
+ * @param   rcBusy      What to return in ring-0 and raw-mode context if the
+ *                      lock is busy.  Pass VINF_SUCCESS to acquired the
+ *                      critical section thru a ring-3 call if necessary.
  *
  * @remarks Currently only supported on timers using the virtual sync clock.
  */
-VMMDECL(int) TMTimerLock(PTMTIMER pTimer, int rcBusy)
-{
-#ifdef IN_RING0
-    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
-#endif
+VMMDECL(int) TMTimerLock(PVMCC pVM, TMTIMERHANDLE hTimer, int rcBusy)
+{
+    PTMTIMER pTimer;
+    TMTIMER_HANDLE_TO_PTR_RETURN(pVM, hTimer, pTimer);
     AssertPtr(pTimer);
     AssertReturn(pTimer->enmClock == TMCLOCK_VIRTUAL_SYNC, VERR_NOT_SUPPORTED);
-    return PDMCritSectEnter(&pTimer->CTX_SUFF(pVM)->tm.s.VirtualSyncLock, rcBusy);
+    return PDMCritSectEnter(&pVM->tm.s.VirtualSyncLock, rcBusy);
 }
 
@@ -1173,14 +1127,13 @@
  * Unlocks a timer clock locked by TMTimerLock.
  *
- * @param   pTimer              The timer which clock to unlock.
- */
-VMMDECL(void) TMTimerUnlock(PTMTIMER pTimer)
-{
-#ifdef IN_RING0
-    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
-#endif
-    AssertPtr(pTimer);
+ * @param   pVM         The cross context VM structure.
+ * @param   hTimer      Timer handle as returned by one of the create functions.
+ */
+VMMDECL(void) TMTimerUnlock(PVMCC pVM, TMTIMERHANDLE hTimer)
+{
+    PTMTIMER pTimer;
+    TMTIMER_HANDLE_TO_PTR_RETURN_VOID(pVM, hTimer, pTimer);
     AssertReturnVoid(pTimer->enmClock == TMCLOCK_VIRTUAL_SYNC);
-    PDMCritSectLeave(&pTimer->CTX_SUFF(pVM)->tm.s.VirtualSyncLock);
+    PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock);
 }
 
@@ -1190,14 +1143,14 @@
  *
  * @returns @c true if its the owner, @c false if not.
- * @param   pTimer              The timer handle.
- */
-VMMDECL(bool) TMTimerIsLockOwner(PTMTIMER pTimer)
-{
-#ifdef IN_RING0
-    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
-#endif
+ * @param   pVM         The cross context VM structure.
+ * @param   hTimer      Timer handle as returned by one of the create functions.
+ */
+VMMDECL(bool) TMTimerIsLockOwner(PVMCC pVM, TMTIMERHANDLE hTimer)
+{
+    PTMTIMER pTimer;
+    TMTIMER_HANDLE_TO_PTR_RETURN_EX(pVM, hTimer, false, pTimer);
     AssertPtr(pTimer);
     AssertReturn(pTimer->enmClock == TMCLOCK_VIRTUAL_SYNC, false);
-    return PDMCritSectIsOwner(&pTimer->CTX_SUFF(pVM)->tm.s.VirtualSyncLock);
+    return PDMCritSectIsOwner(&pVM->tm.s.VirtualSyncLock);
 }
 
@@ -1319,13 +1272,12 @@
  *
  * @returns VBox status code.
- * @param   pTimer          Timer handle as returned by one of the create functions.
- * @param   u64Expire       New expire time.
- */
-VMMDECL(int) TMTimerSet(PTMTIMER pTimer, uint64_t u64Expire)
-{
-#ifdef IN_RING0
-    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
-#endif
-    PVMCC pVM = pTimer->CTX_SUFF(pVM);
+ * @param   pVM         The cross context VM structure.
+ * @param   hTimer      Timer handle as returned by one of the create functions.
+ * @param   u64Expire   New expire time.
+ */
+VMMDECL(int) TMTimerSet(PVMCC pVM, TMTIMERHANDLE hTimer, uint64_t u64Expire)
+{
+    PTMTIMER pTimer;
+    TMTIMER_HANDLE_TO_PTR_RETURN(pVM, hTimer, pTimer);
     STAM_COUNTER_INC(&pTimer->StatSetAbsolute);
 
@@ -1627,15 +1579,12 @@
  *
  * @returns VBox status code.
- * @param   pTimer          Timer handle as returned by one of the create functions.
+ * @param   pVM             The cross context VM structure.
+ * @param   hTimer          Timer handle as returned by one of the create functions.
  * @param   cTicksToNext    Clock ticks until the next time expiration.
  * @param   pu64Now         Where to return the current time stamp used.
  *                          Optional.
  */
-VMMDECL(int) TMTimerSetRelative(PTMTIMER pTimer, uint64_t cTicksToNext, uint64_t *pu64Now)
-{
-#ifdef IN_RING0
-    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
-#endif
-    PVMCC pVM = pTimer->CTX_SUFF(pVM);
+static int tmTimerSetRelative(PVMCC pVM, PTMTIMER pTimer, uint64_t cTicksToNext, uint64_t *pu64Now)
+{
     STAM_COUNTER_INC(&pTimer->StatSetRelative);
 
@@ -1849,4 +1798,22 @@
 
 /**
+ * Arm a timer with a expire time relative to the current time.
+ *
+ * @returns VBox status code.
+ * @param   pVM             The cross context VM structure.
+ * @param   hTimer          Timer handle as returned by one of the create functions.
+ * @param   cTicksToNext    Clock ticks until the next time expiration.
+ * @param   pu64Now         Where to return the current time stamp used.
+ *                          Optional.
+ */
+VMMDECL(int) TMTimerSetRelative(PVMCC pVM, TMTIMERHANDLE hTimer, uint64_t cTicksToNext, uint64_t *pu64Now)
+{
+    PTMTIMER pTimer;
+    TMTIMER_HANDLE_TO_PTR_RETURN(pVM, hTimer, pTimer);
+    return tmTimerSetRelative(pVM, pTimer, cTicksToNext, pu64Now);
+}
+
+
+/**
  * Drops a hint about the frequency of the timer.
  *
@@ -1855,7 +1822,7 @@
  *
  * @returns VBox status code.
- * @param   pTimer          Timer handle as returned by one of the create
- *                          functions.
- * @param   uHzHint         The frequency hint.  Pass 0 to clear the hint.
+ * @param   pVM         The cross context VM structure.
+ * @param   hTimer      Timer handle as returned by one of the create functions.
+ * @param   uHzHint     The frequency hint.  Pass 0 to clear the hint.
  *
  * @remarks We're using an integer hertz value here since anything above 1 HZ
@@ -1863,9 +1830,8 @@
  *          range where it makes sense is >= 100 HZ.
  */
-VMMDECL(int) TMTimerSetFrequencyHint(PTMTIMER pTimer, uint32_t uHzHint)
-{
-#ifdef IN_RING0
-    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
-#endif
+VMMDECL(int) TMTimerSetFrequencyHint(PVMCC pVM, TMTIMERHANDLE hTimer, uint32_t uHzHint)
+{
+    PTMTIMER pTimer;
+    TMTIMER_HANDLE_TO_PTR_RETURN(pVM, hTimer, pTimer);
     TMTIMER_ASSERT_CRITSECT(pTimer);
 
@@ -1873,5 +1839,4 @@
     pTimer->uHzHint = uHzHint;
 
-    PVM pVM = pTimer->CTX_SUFF(pVM);
     uint32_t const uMaxHzHint = pVM->tm.s.uMaxHzHint;
     if (   uHzHint    >  uMaxHzHint
@@ -1959,12 +1924,11 @@
  *
  * @returns VBox status code.
- * @param   pTimer          Timer handle as returned by one of the create functions.
- */
-VMMDECL(int) TMTimerStop(PTMTIMER pTimer)
-{
-#ifdef IN_RING0
-    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
-#endif
-    PVMCC pVM = pTimer->CTX_SUFF(pVM);
+ * @param   pVM         The cross context VM structure.
+ * @param   hTimer      Timer handle as returned by one of the create functions.
+ */
+VMMDECL(int) TMTimerStop(PVMCC pVM, TMTIMERHANDLE hTimer)
+{
+    PTMTIMER pTimer;
+    TMTIMER_HANDLE_TO_PTR_RETURN(pVM, hTimer, pTimer);
     STAM_COUNTER_INC(&pTimer->StatStop);
 
@@ -2070,12 +2034,11 @@
  *
  * @returns Current clock time.
- * @param   pTimer          Timer handle as returned by one of the create functions.
- */
-VMMDECL(uint64_t) TMTimerGet(PTMTIMER pTimer)
-{
-#ifdef IN_RING0
-    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
-#endif
-    PVMCC pVM = pTimer->CTX_SUFF(pVM);
+ * @param   pVM         The cross context VM structure.
+ * @param   hTimer      Timer handle as returned by one of the create functions.
+ */
+VMMDECL(uint64_t) TMTimerGet(PVMCC pVM, TMTIMERHANDLE hTimer)
+{
+    PTMTIMER pTimer;
+    TMTIMER_HANDLE_TO_PTR_RETURN_EX(pVM, hTimer, UINT64_MAX, pTimer);
     STAM_COUNTER_INC(&pTimer->StatGet);
 
@@ -2106,11 +2069,11 @@
  *
  * @returns Clock frequency (as Hz of course).
- * @param   pTimer          Timer handle as returned by one of the create functions.
- */
-VMMDECL(uint64_t) TMTimerGetFreq(PTMTIMER pTimer)
-{
-#ifdef IN_RING0
-    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
-#endif
+ * @param   pVM         The cross context VM structure.
+ * @param   hTimer      Timer handle as returned by one of the create functions.
+ */
+VMMDECL(uint64_t) TMTimerGetFreq(PVMCC pVM, TMTIMERHANDLE hTimer)
+{
+    PTMTIMER pTimer;
+    TMTIMER_HANDLE_TO_PTR_RETURN_EX(pVM, hTimer, 0, pTimer);
     switch (pTimer->enmClock)
     {
@@ -2134,11 +2097,11 @@
  *
  * @returns Expire time of the timer.
- * @param   pTimer          Timer handle as returned by one of the create functions.
- */
-VMMDECL(uint64_t) TMTimerGetExpire(PTMTIMER pTimer)
-{
-#ifdef IN_RING0
-    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
-#endif
+ * @param   pVM         The cross context VM structure.
+ * @param   hTimer      Timer handle as returned by one of the create functions.
+ */
+VMMDECL(uint64_t) TMTimerGetExpire(PVMCC pVM, TMTIMERHANDLE hTimer)
+{
+    PTMTIMER pTimer;
+    TMTIMER_HANDLE_TO_PTR_RETURN_EX(pVM, hTimer, UINT64_MAX, pTimer);
     TMTIMER_ASSERT_CRITSECT(pTimer);
     int cRetries = 1000;
@@ -2155,5 +2118,5 @@
                 Log2(("TMTimerGetExpire: returns ~0 (pTimer=%p:{.enmState=%s, .pszDesc='%s'})\n",
                       pTimer, tmTimerState(pTimer->enmState), R3STRING(pTimer->pszDesc)));
-                return ~(uint64_t)0;
+                return UINT64_MAX;
 
             case TMTIMERSTATE_ACTIVE:
@@ -2180,8 +2143,8 @@
                 Log2(("TMTimerGetExpire: returns ~0 (pTimer=%p:{.enmState=%s, .pszDesc='%s'})\n",
                       pTimer, tmTimerState(pTimer->enmState), R3STRING(pTimer->pszDesc)));
-                return ~(uint64_t)0;
+                return UINT64_MAX;
             default:
                 AssertMsgFailed(("Unknown timer state %d (%s)\n", enmState, R3STRING(pTimer->pszDesc)));
-                return ~(uint64_t)0;
+                return UINT64_MAX;
         }
     } while (cRetries-- > 0);
@@ -2190,5 +2153,5 @@
     Log2(("TMTimerGetExpire: returns ~0 (pTimer=%p:{.enmState=%s, .pszDesc='%s'})\n",
           pTimer, tmTimerState(pTimer->enmState), R3STRING(pTimer->pszDesc)));
-    return ~(uint64_t)0;
+    return UINT64_MAX;
 }
 
@@ -2199,11 +2162,11 @@
  * @returns True if active.
  * @returns False if not active.
- * @param   pTimer          Timer handle as returned by one of the create functions.
- */
-VMMDECL(bool) TMTimerIsActive(PTMTIMER pTimer)
-{
-#ifdef IN_RING0
-    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
-#endif
+ * @param   pVM         The cross context VM structure.
+ * @param   hTimer      Timer handle as returned by one of the create functions.
+ */
+VMMDECL(bool) TMTimerIsActive(PVMCC pVM, TMTIMERHANDLE hTimer)
+{
+    PTMTIMER pTimer;
+    TMTIMER_HANDLE_TO_PTR_RETURN_EX(pVM, hTimer, false, pTimer);
     TMTIMERSTATE enmState = pTimer->enmState;
     switch (enmState)
@@ -2250,22 +2213,25 @@
  *
  * @returns VBox status code.
- * @param   pTimer          Timer handle as returned by one of the create functions.
+ * @param   pVM             The cross context VM structure.
+ * @param   hTimer          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)
-{
+VMMDECL(int) TMTimerSetMillies(PVMCC pVM, TMTIMERHANDLE hTimer, uint32_t cMilliesToNext)
+{
+    PTMTIMER pTimer;
+    TMTIMER_HANDLE_TO_PTR_RETURN(pVM, hTimer, pTimer);
     switch (pTimer->enmClock)
     {
         case TMCLOCK_VIRTUAL:
             AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
-            return TMTimerSetRelative(pTimer, cMilliesToNext * UINT64_C(1000000), NULL);
+            return tmTimerSetRelative(pVM, pTimer, cMilliesToNext * UINT64_C(1000000), NULL);
 
         case TMCLOCK_VIRTUAL_SYNC:
             AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
-            return TMTimerSetRelative(pTimer, cMilliesToNext * UINT64_C(1000000), NULL);
+            return tmTimerSetRelative(pVM, pTimer, cMilliesToNext * UINT64_C(1000000), NULL);
 
         case TMCLOCK_REAL:
             AssertCompile(TMCLOCK_FREQ_REAL == 1000);
-            return TMTimerSetRelative(pTimer, cMilliesToNext, NULL);
+            return tmTimerSetRelative(pVM, pTimer, cMilliesToNext, NULL);
 
         default:
@@ -2280,22 +2246,25 @@
  *
  * @returns VBox status code.
- * @param   pTimer          Timer handle as returned by one of the create functions.
+ * @param   pVM             The cross context VM structure.
+ * @param   hTimer          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)
-{
+VMMDECL(int) TMTimerSetMicro(PVMCC pVM, TMTIMERHANDLE hTimer, uint64_t cMicrosToNext)
+{
+    PTMTIMER pTimer;
+    TMTIMER_HANDLE_TO_PTR_RETURN(pVM, hTimer, pTimer);
     switch (pTimer->enmClock)
     {
         case TMCLOCK_VIRTUAL:
             AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
-            return TMTimerSetRelative(pTimer, cMicrosToNext * 1000, NULL);
+            return tmTimerSetRelative(pVM, pTimer, cMicrosToNext * 1000, NULL);
 
         case TMCLOCK_VIRTUAL_SYNC:
             AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
-            return TMTimerSetRelative(pTimer, cMicrosToNext * 1000, NULL);
+            return tmTimerSetRelative(pVM, pTimer, cMicrosToNext * 1000, NULL);
 
         case TMCLOCK_REAL:
             AssertCompile(TMCLOCK_FREQ_REAL == 1000);
-            return TMTimerSetRelative(pTimer, cMicrosToNext / 1000, NULL);
+            return tmTimerSetRelative(pVM, pTimer, cMicrosToNext / 1000, NULL);
 
         default:
@@ -2310,22 +2279,25 @@
  *
  * @returns VBox status code.
- * @param   pTimer          Timer handle as returned by one of the create functions.
+ * @param   pVM             The cross context VM structure.
+ * @param   hTimer          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)
-{
+VMMDECL(int) TMTimerSetNano(PVMCC pVM, TMTIMERHANDLE hTimer, uint64_t cNanosToNext)
+{
+    PTMTIMER pTimer;
+    TMTIMER_HANDLE_TO_PTR_RETURN(pVM, hTimer, pTimer);
     switch (pTimer->enmClock)
     {
         case TMCLOCK_VIRTUAL:
             AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
-            return TMTimerSetRelative(pTimer, cNanosToNext, NULL);
+            return tmTimerSetRelative(pVM, pTimer, cNanosToNext, NULL);
 
         case TMCLOCK_VIRTUAL_SYNC:
             AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
-            return TMTimerSetRelative(pTimer, cNanosToNext, NULL);
+            return tmTimerSetRelative(pVM, pTimer, cNanosToNext, NULL);
 
         case TMCLOCK_REAL:
             AssertCompile(TMCLOCK_FREQ_REAL == 1000);
-            return TMTimerSetRelative(pTimer, cNanosToNext / 1000000, NULL);
+            return tmTimerSetRelative(pVM, pTimer, cNanosToNext / 1000000, NULL);
 
         default:
@@ -2340,9 +2312,10 @@
  *
  * @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));
+ * @param   pVM         The cross context VM structure.
+ * @param   hTimer      Timer handle as returned by one of the create functions.
+ */
+VMMDECL(uint64_t) TMTimerGetNano(PVMCC pVM, TMTIMERHANDLE hTimer)
+{
+    return TMTimerToNano(pVM, hTimer, TMTimerGet(pVM, hTimer));
 }
 
@@ -2352,9 +2325,10 @@
  *
  * @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));
+ * @param   pVM         The cross context VM structure.
+ * @param   hTimer      Timer handle as returned by one of the create functions.
+ */
+VMMDECL(uint64_t) TMTimerGetMicro(PVMCC pVM, TMTIMERHANDLE hTimer)
+{
+    return TMTimerToMicro(pVM, hTimer, TMTimerGet(pVM, hTimer));
 }
 
@@ -2364,9 +2338,10 @@
  *
  * @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));
+ * @param   pVM         The cross context VM structure.
+ * @param   hTimer      Timer handle as returned by one of the create functions.
+ */
+VMMDECL(uint64_t) TMTimerGetMilli(PVMCC pVM, TMTIMERHANDLE hTimer)
+{
+    return TMTimerToMilli(pVM, hTimer, TMTimerGet(pVM, hTimer));
 }
 
@@ -2376,14 +2351,14 @@
  *
  * @returns nanoseconds.
- * @param   pTimer          Timer handle as returned by one of the create functions.
- * @param   u64Ticks        The clock ticks.
+ * @param   pVM         The cross context VM structure.
+ * @param   hTimer      Timer handle as returned by one of the create functions.
+ * @param   cTicks      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)
-{
-#ifdef IN_RING0
-    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
-#endif
+VMMDECL(uint64_t) TMTimerToNano(PVMCC pVM, TMTIMERHANDLE hTimer, uint64_t cTicks)
+{
+    PTMTIMER pTimer;
+    TMTIMER_HANDLE_TO_PTR_RETURN_EX(pVM, hTimer, 0, pTimer);
     switch (pTimer->enmClock)
     {
@@ -2391,9 +2366,9 @@
         case TMCLOCK_VIRTUAL_SYNC:
             AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
-            return u64Ticks;
+            return cTicks;
 
         case TMCLOCK_REAL:
             AssertCompile(TMCLOCK_FREQ_REAL == 1000);
-            return u64Ticks * 1000000;
+            return cTicks * 1000000;
 
         default:
@@ -2408,14 +2383,14 @@
  *
  * @returns microseconds.
- * @param   pTimer          Timer handle as returned by one of the create functions.
- * @param   u64Ticks        The clock ticks.
+ * @param   pVM         The cross context VM structure.
+ * @param   hTimer      Timer handle as returned by one of the create functions.
+ * @param   cTicks      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)
-{
-#ifdef IN_RING0
-    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
-#endif
+VMMDECL(uint64_t) TMTimerToMicro(PVMCC pVM, TMTIMERHANDLE hTimer, uint64_t cTicks)
+{
+    PTMTIMER pTimer;
+    TMTIMER_HANDLE_TO_PTR_RETURN_EX(pVM, hTimer, 0, pTimer);
     switch (pTimer->enmClock)
     {
@@ -2423,9 +2398,9 @@
         case TMCLOCK_VIRTUAL_SYNC:
             AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
-            return u64Ticks / 1000;
+            return cTicks / 1000;
 
         case TMCLOCK_REAL:
             AssertCompile(TMCLOCK_FREQ_REAL == 1000);
-            return u64Ticks * 1000;
+            return cTicks * 1000;
 
         default:
@@ -2440,14 +2415,14 @@
  *
  * @returns milliseconds.
- * @param   pTimer          Timer handle as returned by one of the create functions.
- * @param   u64Ticks        The clock ticks.
+ * @param   pVM         The cross context VM structure.
+ * @param   hTimer      Timer handle as returned by one of the create functions.
+ * @param   cTicks      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)
-{
-#ifdef IN_RING0
-    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
-#endif
+VMMDECL(uint64_t) TMTimerToMilli(PVMCC pVM, TMTIMERHANDLE hTimer, uint64_t cTicks)
+{
+    PTMTIMER pTimer;
+    TMTIMER_HANDLE_TO_PTR_RETURN_EX(pVM, hTimer, 0, pTimer);
     switch (pTimer->enmClock)
     {
@@ -2455,9 +2430,9 @@
         case TMCLOCK_VIRTUAL_SYNC:
             AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
-            return u64Ticks / 1000000;
+            return cTicks / 1000000;
 
         case TMCLOCK_REAL:
             AssertCompile(TMCLOCK_FREQ_REAL == 1000);
-            return u64Ticks;
+            return cTicks;
 
         default:
@@ -2472,13 +2447,13 @@
  *
  * @returns timer clock ticks.
- * @param   pTimer          Timer handle as returned by one of the create functions.
- * @param   cNanoSecs       The nanosecond value ticks to convert.
+ * @param   pVM         The cross context VM structure.
+ * @param   hTimer      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)
-{
-#ifdef IN_RING0
-    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
-#endif
+VMMDECL(uint64_t) TMTimerFromNano(PVMCC pVM, TMTIMERHANDLE hTimer, uint64_t cNanoSecs)
+{
+    PTMTIMER pTimer;
+    TMTIMER_HANDLE_TO_PTR_RETURN_EX(pVM, hTimer, 0, pTimer);
     switch (pTimer->enmClock)
     {
@@ -2503,13 +2478,13 @@
  *
  * @returns timer clock ticks.
- * @param   pTimer          Timer handle as returned by one of the create functions.
- * @param   cMicroSecs      The microsecond value ticks to convert.
+ * @param   pVM         The cross context VM structure.
+ * @param   hTimer      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)
-{
-#ifdef IN_RING0
-    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
-#endif
+VMMDECL(uint64_t) TMTimerFromMicro(PVMCC pVM, TMTIMERHANDLE hTimer, uint64_t cMicroSecs)
+{
+    PTMTIMER pTimer;
+    TMTIMER_HANDLE_TO_PTR_RETURN_EX(pVM, hTimer, 0, pTimer);
     switch (pTimer->enmClock)
     {
@@ -2534,16 +2509,13 @@
  *
  * @returns timer clock ticks.
- * @param   pVM             The cross context VM structure.
- * @param   pTimer          Timer handle as returned by one of the create functions.
- * @param   cMilliSecs      The millisecond value ticks to convert.
+ * @param   pVM         The cross context VM structure.
+ * @param   hTimer      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(PVMCC pVM, PTMTIMER pTimer, uint64_t cMilliSecs)
-{
-    RT_NOREF(pVM);
-    Assert(pVM == pTimer->CTX_SUFF(pVM));
-#ifdef IN_RING0
-    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
-#endif
+VMMDECL(uint64_t) TMTimerFromMilli(PVMCC pVM, TMTIMERHANDLE hTimer, uint64_t cMilliSecs)
+{
+    PTMTIMER pTimer;
+    TMTIMER_HANDLE_TO_PTR_RETURN_EX(pVM, hTimer, 0, pTimer);
     switch (pTimer->enmClock)
     {
Index: /trunk/src/VBox/VMM/VMMR0/PDMR0DevHlp.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/PDMR0DevHlp.cpp	(revision 87765)
+++ /trunk/src/VBox/VMM/VMMR0/PDMR0DevHlp.cpp	(revision 87766)
@@ -415,16 +415,9 @@
 
 
-/** Converts a timer handle to a pointer (used to be exposed, will be
- *  rewritten later). */
-DECLINLINE(PTMTIMERR0) pdmR0DevHlp_TimerToPtr(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    return (PTMTIMERR0)MMHyperR3ToCC(pDevIns->Internal.s.pGVM, hTimer);
-}
-
 /** @interface_method_impl{PDMDEVHLPR0,pfnTimerFromMicro} */
 static DECLCALLBACK(uint64_t) pdmR0DevHlp_TimerFromMicro(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMicroSecs)
 {
-    return TMTimerFromMicro(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), cMicroSecs);
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMTimerFromMicro(pDevIns->Internal.s.pGVM, hTimer, cMicroSecs);
 }
 
@@ -434,5 +427,5 @@
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
-    return TMTimerFromMilli(pDevIns->Internal.s.pGVM, pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), cMilliSecs);
+    return TMTimerFromMilli(pDevIns->Internal.s.pGVM, hTimer, cMilliSecs);
 }
 
@@ -441,5 +434,6 @@
 static DECLCALLBACK(uint64_t) pdmR0DevHlp_TimerFromNano(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cNanoSecs)
 {
-    return TMTimerFromNano(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), cNanoSecs);
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMTimerFromNano(pDevIns->Internal.s.pGVM, hTimer, cNanoSecs);
 }
 
@@ -447,5 +441,6 @@
 static DECLCALLBACK(uint64_t) pdmR0DevHlp_TimerGet(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
 {
-    return TMTimerGet(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer));
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMTimerGet(pDevIns->Internal.s.pGVM, hTimer);
 }
 
@@ -454,5 +449,6 @@
 static DECLCALLBACK(uint64_t) pdmR0DevHlp_TimerGetFreq(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
 {
-    return TMTimerGetFreq(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer));
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMTimerGetFreq(pDevIns->Internal.s.pGVM, hTimer);
 }
 
@@ -461,5 +457,6 @@
 static DECLCALLBACK(uint64_t) pdmR0DevHlp_TimerGetNano(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
 {
-    return TMTimerGetNano(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer));
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMTimerGetNano(pDevIns->Internal.s.pGVM, hTimer);
 }
 
@@ -468,5 +465,6 @@
 static DECLCALLBACK(bool) pdmR0DevHlp_TimerIsActive(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
 {
-    return TMTimerIsActive(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer));
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMTimerIsActive(pDevIns->Internal.s.pGVM, hTimer);
 }
 
@@ -475,5 +473,6 @@
 static DECLCALLBACK(bool) pdmR0DevHlp_TimerIsLockOwner(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
 {
-    return TMTimerIsLockOwner(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer));
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMTimerIsLockOwner(pDevIns->Internal.s.pGVM, hTimer);
 }
 
@@ -482,5 +481,6 @@
 static DECLCALLBACK(VBOXSTRICTRC) pdmR0DevHlp_TimerLockClock(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, int rcBusy)
 {
-    return TMTimerLock(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), rcBusy);
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMTimerLock(pDevIns->Internal.s.pGVM, hTimer, rcBusy);
 }
 
@@ -490,5 +490,6 @@
                                                               PPDMCRITSECT pCritSect, int rcBusy)
 {
-    VBOXSTRICTRC rc = TMTimerLock(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), rcBusy);
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    VBOXSTRICTRC rc = TMTimerLock(pDevIns->Internal.s.pGVM, hTimer, rcBusy);
     if (rc == VINF_SUCCESS)
     {
@@ -497,5 +498,5 @@
             return rc;
         AssertRC(VBOXSTRICTRC_VAL(rc));
-        TMTimerUnlock(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer));
+        TMTimerUnlock(pDevIns->Internal.s.pGVM, hTimer);
     }
     else
@@ -508,5 +509,6 @@
 static DECLCALLBACK(int) pdmR0DevHlp_TimerSet(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t uExpire)
 {
-    return TMTimerSet(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), uExpire);
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMTimerSet(pDevIns->Internal.s.pGVM, hTimer, uExpire);
 }
 
@@ -515,5 +517,6 @@
 static DECLCALLBACK(int) pdmR0DevHlp_TimerSetFrequencyHint(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint32_t uHz)
 {
-    return TMTimerSetFrequencyHint(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), uHz);
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMTimerSetFrequencyHint(pDevIns->Internal.s.pGVM, hTimer, uHz);
 }
 
@@ -522,5 +525,6 @@
 static DECLCALLBACK(int) pdmR0DevHlp_TimerSetMicro(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMicrosToNext)
 {
-    return TMTimerSetMicro(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), cMicrosToNext);
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMTimerSetMicro(pDevIns->Internal.s.pGVM, hTimer, cMicrosToNext);
 }
 
@@ -529,5 +533,6 @@
 static DECLCALLBACK(int) pdmR0DevHlp_TimerSetMillies(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMilliesToNext)
 {
-    return TMTimerSetMillies(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), cMilliesToNext);
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMTimerSetMillies(pDevIns->Internal.s.pGVM, hTimer, cMilliesToNext);
 }
 
@@ -536,5 +541,6 @@
 static DECLCALLBACK(int) pdmR0DevHlp_TimerSetNano(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cNanosToNext)
 {
-    return TMTimerSetNano(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), cNanosToNext);
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMTimerSetNano(pDevIns->Internal.s.pGVM, hTimer, cNanosToNext);
 }
 
@@ -543,5 +549,6 @@
 static DECLCALLBACK(int) pdmR0DevHlp_TimerSetRelative(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cTicksToNext, uint64_t *pu64Now)
 {
-    return TMTimerSetRelative(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), cTicksToNext, pu64Now);
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMTimerSetRelative(pDevIns->Internal.s.pGVM, hTimer, cTicksToNext, pu64Now);
 }
 
@@ -550,5 +557,6 @@
 static DECLCALLBACK(int) pdmR0DevHlp_TimerStop(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
 {
-    return TMTimerStop(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer));
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMTimerStop(pDevIns->Internal.s.pGVM, hTimer);
 }
 
@@ -557,5 +565,6 @@
 static DECLCALLBACK(void) pdmR0DevHlp_TimerUnlockClock(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
 {
-    TMTimerUnlock(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer));
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    TMTimerUnlock(pDevIns->Internal.s.pGVM, hTimer);
 }
 
@@ -564,5 +573,6 @@
 static DECLCALLBACK(void) pdmR0DevHlp_TimerUnlockClock2(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PPDMCRITSECT pCritSect)
 {
-    TMTimerUnlock(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer));
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    TMTimerUnlock(pDevIns->Internal.s.pGVM, hTimer);
     int rc = PDMCritSectLeave(pCritSect);
     AssertRC(rc);
Index: /trunk/src/VBox/VMM/VMMR3/CPUM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/CPUM.cpp	(revision 87765)
+++ /trunk/src/VBox/VMM/VMMR3/CPUM.cpp	(revision 87766)
@@ -2099,16 +2099,12 @@
 
 /**
- * Callback that fires when the nested VMX-preemption timer expired.
- *
- * @param   pVM     The cross context VM structure.
- * @param   pTimer  Pointer to timer.
- * @param   pvUser  Opaque pointer to the virtual-CPU.
- */
-static DECLCALLBACK(void) cpumR3VmxPreemptTimerCallback(PVM pVM, PTMTIMER pTimer, void *pvUser)
-{
-    RT_NOREF2(pVM, pTimer);
-    Assert(pvUser);
-
+ * @callback_method_impl{FNTMTIMERINT,
+ *  Callback that fires when the nested VMX-preemption timer expired.}
+ */
+static DECLCALLBACK(void) cpumR3VmxPreemptTimerCallback(PVM pVM, TMTIMERHANDLE hTimer, void *pvUser)
+{
+    RT_NOREF(pVM, hTimer);
     PVMCPU pVCpu = (PVMCPUR3)pvUser;
+    AssertPtr(pVCpu);
     VMCPU_FF_SET(pVCpu, VMCPU_FF_VMX_PREEMPT_TIMER);
 }
@@ -2224,4 +2220,6 @@
 
         pVCpu->cpum.s.Host.fXStateMask = fXStateHostMask;
+
+        pVCpu->cpum.s.hNestedVmxPreemptTimer = NIL_TMTIMERHANDLE;
     }
 
@@ -2334,6 +2332,9 @@
         {
             PVMCPU pVCpu = pVM->apCpusR3[idCpu];
-            int rc = TMR3TimerDestroy(pVCpu->cpum.s.pNestedVmxPreemptTimerR3); AssertRC(rc);
-            pVCpu->cpum.s.pNestedVmxPreemptTimerR0 = NIL_RTR0PTR;
+            if (pVCpu->cpum.s.hNestedVmxPreemptTimer != NIL_TMTIMERHANDLE)
+            {
+                int rc = TMR3TimerDestroy(pVM, pVCpu->cpum.s.hNestedVmxPreemptTimer); AssertRC(rc);
+                pVCpu->cpum.s.hNestedVmxPreemptTimer = NIL_TMTIMERHANDLE;
+            }
         }
 
@@ -4502,6 +4503,6 @@
             cpumR3MsrRegStats(pVM);
 
-            /* Create VMX-preemption timer for nested guests if required. */
-/** @todo r=bird: this should be one in CPUMR3Init, not here.   */
+            /* Create VMX-preemption timer for nested guests if required.  Must be
+               done here as CPUM is initialized before TM. */
             if (pVM->cpum.s.GuestFeatures.fVmx)
             {
@@ -4513,7 +4514,6 @@
                     char *pszTimerName = MMR3HeapAPrintf(pVM, MM_TAG_CPUM_CTX, "Nested Guest VMX-preempt. timer %u", idCpu);
                     int rc = TMR3TimerCreate(pVM, TMCLOCK_VIRTUAL_SYNC, cpumR3VmxPreemptTimerCallback, pVCpu,
-                                             TMTIMER_FLAGS_RING0, pszTimerName, &pVCpu->cpum.s.pNestedVmxPreemptTimerR3);
+                                             TMTIMER_FLAGS_RING0, pszTimerName, &pVCpu->cpum.s.hNestedVmxPreemptTimer);
                     AssertLogRelRCReturn(rc, rc);
-                    pVCpu->cpum.s.pNestedVmxPreemptTimerR0 = TMTimerR0Ptr(pVCpu->cpum.s.pNestedVmxPreemptTimerR3);
                 }
             }
Index: /trunk/src/VBox/VMM/VMMR3/GIMHv.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/GIMHv.cpp	(revision 87765)
+++ /trunk/src/VBox/VMM/VMMR3/GIMHv.cpp	(revision 87766)
@@ -187,5 +187,5 @@
 static int    gimR3HvInitDebugSupport(PVM pVM);
 static void   gimR3HvTermDebugSupport(PVM pVM);
-static DECLCALLBACK(void) gimR3HvTimerCallback(PVM pVM, PTMTIMER pTimer, void *pvUser);
+static DECLCALLBACK(void) gimR3HvTimerCallback(PVM pVM, TMTIMERHANDLE pTimer, void *pvUser);
 
 /**
@@ -202,4 +202,15 @@
 
     PGIMHV pHv = &pVM->gim.s.u.Hv;
+
+    /*
+     * Initialize timer handles and such.
+     */
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU       pVCpu     = pVM->apCpusR3[idCpu];
+        PGIMHVCPU    pHvCpu    = &pVCpu->gim.s.u.HvCpu;
+        for (uint8_t idxStimer = 0; idxStimer < RT_ELEMENTS(pHvCpu->aStimers); idxStimer++)
+            pHvCpu->aStimers[idxStimer].hTimer = NIL_TMTIMERHANDLE;
+    }
 
     /*
@@ -510,7 +521,6 @@
                             idxStimer);
                 rc = TMR3TimerCreate(pVM, TMCLOCK_VIRTUAL_SYNC, gimR3HvTimerCallback, pHvStimer /* pvUser */,
-                                     TMTIMER_FLAGS_RING0, pHvStimer->szTimerDesc, &pHvStimer->pTimerR3);
+                                     TMTIMER_FLAGS_RING0, pHvStimer->szTimerDesc, &pHvStimer->hTimer);
                 AssertLogRelRCReturn(rc, rc);
-                pHvStimer->pTimerR0 = TMTimerR0Ptr(pHvStimer->pTimerR3);
             }
         }
@@ -605,5 +615,6 @@
             {
                 PGIMHVSTIMER pHvStimer = &pHvCpu->aStimers[idxStimer];
-                TMR3TimerDestroy(pHvStimer->pTimerR3);
+                TMR3TimerDestroy(pVM, pHvStimer->hTimer);
+                pHvStimer->hTimer = NIL_TMTIMERHANDLE;
             }
         }
@@ -1082,16 +1093,14 @@
 
 /**
- * Hyper-V synthetic timer callback.
- *
- * @param   pVM         The cross context VM structure.
- * @param   pTimer      Pointer to timer.
- * @param   pvUser      Pointer to the synthetic timer.
- */
-static DECLCALLBACK(void) gimR3HvTimerCallback(PVM pVM, PTMTIMER pTimer, void *pvUser)
+ * @callback_method_impl{FNTMTIMERINT, Hyper-V synthetic timer callback.}
+ */
+static DECLCALLBACK(void) gimR3HvTimerCallback(PVM pVM, TMTIMERHANDLE hTimer, void *pvUser)
 {
     PGIMHVSTIMER pHvStimer = (PGIMHVSTIMER)pvUser;
     Assert(pHvStimer);
-    Assert(TMTimerIsLockOwner(pTimer)); RT_NOREF(pTimer);
+    Assert(TMTimerIsLockOwner(pVM, hTimer));
     Assert(pHvStimer->idCpu < pVM->cCpus);
+    Assert(pHvStimer->hTimer == hTimer);
+    RT_NOREF(hTimer);
 
     PVMCPU    pVCpu  = pVM->apCpusR3[pHvStimer->idCpu];
Index: /trunk/src/VBox/VMM/VMMR3/PDMAsyncCompletionFile.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMAsyncCompletionFile.cpp	(revision 87765)
+++ /trunk/src/VBox/VMM/VMMR3/PDMAsyncCompletionFile.cpp	(revision 87766)
@@ -363,5 +363,5 @@
                 {
                     ASMAtomicWriteU64(&pEpClassFile->cMilliesNext, tsDelay);
-                    TMTimerSetMillies(pEpClassFile->pTimer, tsDelay);
+                    TMTimerSetMillies(pVM, pEpClassFile->hTimer, tsDelay);
                 }
 
@@ -733,6 +733,10 @@
 }
 
-static DECLCALLBACK(void) pdmacR3TimerCallback(PVM pVM, PTMTIMER pTimer, void *pvUser)
-{
+/**
+ * @callback_method_impl{FNTMTIMERINT, }
+ */
+static DECLCALLBACK(void) pdmacR3TimerCallback(PVM pVM, TMTIMERHANDLE hTimer, void *pvUser)
+{
+    Assert(hTimer == pEpClassFile->hTimer);
     uint64_t tsCur = RTTimeProgramMilliTS();
     uint64_t cMilliesNext = UINT64_MAX;
@@ -784,5 +788,5 @@
     {
         ASMAtomicWriteU64(&pEpClassFile->cMilliesNext, cMilliesNext);
-        TMTimerSetMillies(pEpClassFile->pTimer, cMilliesNext);
+        TMTimerSetMillies(pVM, hTimer, cMilliesNext);
     }
 }
@@ -868,5 +872,5 @@
 # ifdef PDM_ASYNC_COMPLETION_FILE_WITH_DELAY
     rc = TMR3TimerCreate(pEpClassFile->Core.pVM, TMCLOCK_REAL, pdmacR3TimerCallback, pEpClassFile,
-                         TMTIMER_FLAGS_NO_RING0, "AC Delay", &pEpClassFile->pTimer);
+                         TMTIMER_FLAGS_NO_RING0, "AC Delay", &pEpClassFile->hTimer);
     AssertRC(rc);
     pEpClassFile->cMilliesNext = UINT64_MAX;
Index: /trunk/src/VBox/VMM/VMMR3/PDMBlkCache.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMBlkCache.cpp	(revision 87765)
+++ /trunk/src/VBox/VMM/VMMR3/PDMBlkCache.cpp	(revision 87766)
@@ -736,5 +736,5 @@
     if (   !(cbDirtyOld - cbCommitted)
         && pBlkCache->pCache->u32CommitTimeoutMs != 0)
-        TMTimerStop(pBlkCache->pCache->pTimerCommit);
+        TMTimerStop(pBlkCache->pCache->pVM, pBlkCache->pCache->hTimerCommit);
 }
 
@@ -808,5 +808,5 @@
         {
             /* Arm the commit timer. */
-            TMTimerSetMillies(pCache->pTimerCommit, pCache->u32CommitTimeoutMs);
+            TMTimerSetMillies(pCache->pVM, pCache->hTimerCommit, pCache->u32CommitTimeoutMs);
         }
     }
@@ -833,10 +833,10 @@
 
 /**
- * Commit timer callback.
- */
-static DECLCALLBACK(void) pdmBlkCacheCommitTimerCallback(PVM pVM, PTMTIMER pTimer, void *pvUser)
+ * @callback_method_impl{FNTMTIMERINT, Commit timer callback.}
+ */
+static DECLCALLBACK(void) pdmBlkCacheCommitTimerCallback(PVM pVM, TMTIMERHANDLE hTimer, void *pvUser)
 {
     PPDMBLKCACHEGLOBAL pCache = (PPDMBLKCACHEGLOBAL)pvUser;
-    NOREF(pVM); NOREF(pTimer);
+    RT_NOREF(pVM, hTimer);
 
     LogFlowFunc(("Commit interval expired, commiting dirty entries\n"));
@@ -1158,5 +1158,5 @@
         if (pBlkCacheGlobal->u32CommitTimeoutMs > 0)
             rc = TMR3TimerCreate(pVM, TMCLOCK_REAL, pdmBlkCacheCommitTimerCallback, pBlkCacheGlobal,
-                                 TMTIMER_FLAGS_NO_RING0,  "BlkCache-Commit", &pBlkCacheGlobal->pTimerCommit);
+                                 TMTIMER_FLAGS_NO_RING0,  "BlkCache-Commit", &pBlkCacheGlobal->hTimerCommit);
 
         if (RT_SUCCESS(rc))
@@ -2778,5 +2778,4 @@
 VMMR3DECL(int) PDMR3BlkCacheClear(PPDMBLKCACHE pBlkCache)
 {
-    int rc = VINF_SUCCESS;
     PPDMBLKCACHEGLOBAL pCache = pBlkCache->pCache;
 
@@ -2796,5 +2795,5 @@
 
     pdmBlkCacheLockLeave(pCache);
-    return rc;
-}
-
+    return VINF_SUCCESS;
+}
+
Index: /trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp	(revision 87765)
+++ /trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp	(revision 87766)
@@ -439,19 +439,8 @@
         Assert(fFlags & TMTIMER_FLAGS_NO_RING0 /* just to make sure all devices has been considered */);
 
-    PTMTIMER pTimer = NULL;
-    int rc = TMR3TimerCreateDevice(pVM, pDevIns, enmClock, pfnCallback, pvUser, fFlags, pszDesc, &pTimer);
-    *phTimer = (uintptr_t)pTimer;
+    int rc = TMR3TimerCreateDevice(pVM, pDevIns, enmClock, pfnCallback, pvUser, fFlags, pszDesc, phTimer);
 
     LogFlow(("pdmR3DevHlp_TimerCreate: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
     return rc;
-}
-
-
-/** Converts timer handle to pointer (used to exposed, will be replace soon.) */
-DECLINLINE(PTMTIMERR3) pdmR3DevHlp_TimerToPtr(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    RT_NOREF(pDevIns);
-    return (PTMTIMERR3)hTimer;
 }
 
@@ -460,5 +449,6 @@
 static DECLCALLBACK(uint64_t) pdmR3DevHlp_TimerFromMicro(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMicroSecs)
 {
-    return TMTimerFromMicro(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer), cMicroSecs);
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMTimerFromMicro(pDevIns->Internal.s.pVMR3, hTimer, cMicroSecs);
 }
 
@@ -468,5 +458,5 @@
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
-    return TMTimerFromMilli(pDevIns->Internal.s.pVMR3, pdmR3DevHlp_TimerToPtr(pDevIns, hTimer), cMilliSecs);
+    return TMTimerFromMilli(pDevIns->Internal.s.pVMR3, hTimer, cMilliSecs);
 }
 
@@ -475,5 +465,6 @@
 static DECLCALLBACK(uint64_t) pdmR3DevHlp_TimerFromNano(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cNanoSecs)
 {
-    return TMTimerFromNano(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer), cNanoSecs);
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMTimerFromNano(pDevIns->Internal.s.pVMR3, hTimer, cNanoSecs);
 }
 
@@ -481,5 +472,6 @@
 static DECLCALLBACK(uint64_t) pdmR3DevHlp_TimerGet(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
 {
-    return TMTimerGet(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer));
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMTimerGet(pDevIns->Internal.s.pVMR3, hTimer);
 }
 
@@ -488,5 +480,6 @@
 static DECLCALLBACK(uint64_t) pdmR3DevHlp_TimerGetFreq(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
 {
-    return TMTimerGetFreq(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer));
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMTimerGetFreq(pDevIns->Internal.s.pVMR3, hTimer);
 }
 
@@ -495,5 +488,6 @@
 static DECLCALLBACK(uint64_t) pdmR3DevHlp_TimerGetNano(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
 {
-    return TMTimerGetNano(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer));
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMTimerGetNano(pDevIns->Internal.s.pVMR3, hTimer);
 }
 
@@ -502,5 +496,6 @@
 static DECLCALLBACK(bool) pdmR3DevHlp_TimerIsActive(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
 {
-    return TMTimerIsActive(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer));
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMTimerIsActive(pDevIns->Internal.s.pVMR3, hTimer);
 }
 
@@ -509,5 +504,6 @@
 static DECLCALLBACK(bool) pdmR3DevHlp_TimerIsLockOwner(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
 {
-    return TMTimerIsLockOwner(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer));
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMTimerIsLockOwner(pDevIns->Internal.s.pVMR3, hTimer);
 }
 
@@ -516,5 +512,6 @@
 static DECLCALLBACK(VBOXSTRICTRC) pdmR3DevHlp_TimerLockClock(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, int rcBusy)
 {
-    return TMTimerLock(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer), rcBusy);
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMTimerLock(pDevIns->Internal.s.pVMR3, hTimer, rcBusy);
 }
 
@@ -524,5 +521,6 @@
                                                               PPDMCRITSECT pCritSect, int rcBusy)
 {
-    VBOXSTRICTRC rc = TMTimerLock(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer), rcBusy);
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    VBOXSTRICTRC rc = TMTimerLock(pDevIns->Internal.s.pVMR3, hTimer, rcBusy);
     if (rc == VINF_SUCCESS)
     {
@@ -531,5 +529,5 @@
             return rc;
         AssertRC(VBOXSTRICTRC_VAL(rc));
-        TMTimerUnlock(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer));
+        TMTimerUnlock(pDevIns->Internal.s.pVMR3, hTimer);
     }
     else
@@ -542,5 +540,6 @@
 static DECLCALLBACK(int) pdmR3DevHlp_TimerSet(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t uExpire)
 {
-    return TMTimerSet(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer), uExpire);
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMTimerSet(pDevIns->Internal.s.pVMR3, hTimer, uExpire);
 }
 
@@ -549,5 +548,6 @@
 static DECLCALLBACK(int) pdmR3DevHlp_TimerSetFrequencyHint(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint32_t uHz)
 {
-    return TMTimerSetFrequencyHint(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer), uHz);
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMTimerSetFrequencyHint(pDevIns->Internal.s.pVMR3, hTimer, uHz);
 }
 
@@ -556,5 +556,6 @@
 static DECLCALLBACK(int) pdmR3DevHlp_TimerSetMicro(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMicrosToNext)
 {
-    return TMTimerSetMicro(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer), cMicrosToNext);
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMTimerSetMicro(pDevIns->Internal.s.pVMR3, hTimer, cMicrosToNext);
 }
 
@@ -563,5 +564,6 @@
 static DECLCALLBACK(int) pdmR3DevHlp_TimerSetMillies(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMilliesToNext)
 {
-    return TMTimerSetMillies(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer), cMilliesToNext);
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMTimerSetMillies(pDevIns->Internal.s.pVMR3, hTimer, cMilliesToNext);
 }
 
@@ -570,5 +572,6 @@
 static DECLCALLBACK(int) pdmR3DevHlp_TimerSetNano(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cNanosToNext)
 {
-    return TMTimerSetNano(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer), cNanosToNext);
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMTimerSetNano(pDevIns->Internal.s.pVMR3, hTimer, cNanosToNext);
 }
 
@@ -577,5 +580,6 @@
 static DECLCALLBACK(int) pdmR3DevHlp_TimerSetRelative(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cTicksToNext, uint64_t *pu64Now)
 {
-    return TMTimerSetRelative(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer), cTicksToNext, pu64Now);
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMTimerSetRelative(pDevIns->Internal.s.pVMR3, hTimer, cTicksToNext, pu64Now);
 }
 
@@ -584,5 +588,6 @@
 static DECLCALLBACK(int) pdmR3DevHlp_TimerStop(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
 {
-    return TMTimerStop(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer));
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMTimerStop(pDevIns->Internal.s.pVMR3, hTimer);
 }
 
@@ -591,5 +596,6 @@
 static DECLCALLBACK(void) pdmR3DevHlp_TimerUnlockClock(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
 {
-    TMTimerUnlock(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer));
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    TMTimerUnlock(pDevIns->Internal.s.pVMR3, hTimer);
 }
 
@@ -598,5 +604,6 @@
 static DECLCALLBACK(void) pdmR3DevHlp_TimerUnlockClock2(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PPDMCRITSECT pCritSect)
 {
-    TMTimerUnlock(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer));
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    TMTimerUnlock(pDevIns->Internal.s.pVMR3, hTimer);
     int rc = PDMCritSectLeave(pCritSect);
     AssertRC(rc);
@@ -607,5 +614,6 @@
 static DECLCALLBACK(int) pdmR3DevHlp_TimerSetCritSect(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PPDMCRITSECT pCritSect)
 {
-    return TMR3TimerSetCritSect(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer), pCritSect);
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMR3TimerSetCritSect(pDevIns->Internal.s.pVMR3, hTimer, pCritSect);
 }
 
@@ -614,5 +622,6 @@
 static DECLCALLBACK(int) pdmR3DevHlp_TimerSave(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PSSMHANDLE pSSM)
 {
-    return TMR3TimerSave(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer), pSSM);
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMR3TimerSave(pDevIns->Internal.s.pVMR3, hTimer, pSSM);
 }
 
@@ -621,5 +630,6 @@
 static DECLCALLBACK(int) pdmR3DevHlp_TimerLoad(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PSSMHANDLE pSSM)
 {
-    return TMR3TimerLoad(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer), pSSM);
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMR3TimerLoad(pDevIns->Internal.s.pVMR3, hTimer, pSSM);
 }
 
@@ -628,5 +638,6 @@
 static DECLCALLBACK(int) pdmR3DevHlp_TimerDestroy(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
 {
-    return TMR3TimerDestroy(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer));
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return TMR3TimerDestroy(pDevIns->Internal.s.pVMR3, hTimer);
 }
 
Index: /trunk/src/VBox/VMM/VMMR3/PDMDriver.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMDriver.cpp	(revision 87765)
+++ /trunk/src/VBox/VMM/VMMR3/PDMDriver.cpp	(revision 87766)
@@ -1337,8 +1337,5 @@
         fFlags |= TMTIMER_FLAGS_NO_RING0;
 
-    PTMTIMERR3 pTimer = NULL;
-    int rc = TMR3TimerCreateDriver(pDrvIns->Internal.s.pVMR3, pDrvIns, enmClock, pfnCallback, pvUser, fFlags, pszDesc, &pTimer);
-    if (RT_SUCCESS(rc))
-        *phTimer = (TMTIMERHANDLE)pTimer;
+    int rc = TMR3TimerCreateDriver(pDrvIns->Internal.s.pVMR3, pDrvIns, enmClock, pfnCallback, pvUser, fFlags, pszDesc, phTimer);
 
     LogFlow(("pdmR3DrvHlp_TMTimerCreate: caller='%s'/%d: returns %Rrc *phTimer=%p\n", pDrvIns->pReg->szName, pDrvIns->iInstance, rc, *phTimer));
Index: /trunk/src/VBox/VMM/VMMR3/PDMQueue.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMQueue.cpp	(revision 87765)
+++ /trunk/src/VBox/VMM/VMMR3/PDMQueue.cpp	(revision 87766)
@@ -39,5 +39,5 @@
 DECLINLINE(void)            pdmR3QueueFreeItem(PPDMQUEUE pQueue, PPDMQUEUEITEMCORE pItem);
 static bool                 pdmR3QueueFlush(PPDMQUEUE pQueue);
-static DECLCALLBACK(void)   pdmR3QueueTimer(PVM pVM, PTMTIMER pTimer, void *pvUser);
+static DECLCALLBACK(void)   pdmR3QueueTimer(PVM pVM, TMTIMERHANDLE hTimer, void *pvUser);
 
 
@@ -89,5 +89,5 @@
     pQueue->pszName = pszName;
     pQueue->cMilliesInterval = cMilliesInterval;
-    //pQueue->pTimer = NULL;
+    pQueue->hTimer = NIL_TMTIMERHANDLE;
     pQueue->cbItem = (uint32_t)cbItem;
     pQueue->cItems = cItems;
@@ -113,12 +113,12 @@
     if (cMilliesInterval)
     {
-        rc = TMR3TimerCreate(pVM, TMCLOCK_REAL, pdmR3QueueTimer, pQueue, TMTIMER_FLAGS_NO_RING0, "Queue timer", &pQueue->pTimer);
+        rc = TMR3TimerCreate(pVM, TMCLOCK_REAL, pdmR3QueueTimer, pQueue, TMTIMER_FLAGS_NO_RING0, "Queue timer", &pQueue->hTimer);
         if (RT_SUCCESS(rc))
         {
-            rc = TMTimerSetMillies(pQueue->pTimer, cMilliesInterval);
+            rc = TMTimerSetMillies(pVM, pQueue->hTimer, cMilliesInterval);
             if (RT_FAILURE(rc))
             {
                 AssertMsgFailed(("TMTimerSetMillies failed rc=%Rrc\n", rc));
-                int rc2 = TMR3TimerDestroy(pQueue->pTimer); AssertRC(rc2);
+                int rc2 = TMR3TimerDestroy(pVM, pQueue->hTimer); AssertRC(rc2);
             }
         }
@@ -398,5 +398,5 @@
      * Unlink it.
      */
-    if (pQueue->pTimer)
+    if (pQueue->hTimer != NIL_TMTIMERHANDLE)
     {
         if (pUVM->pdm.s.pQueuesTimer != pQueue)
@@ -448,8 +448,8 @@
      * Destroy the timer and free it.
      */
-    if (pQueue->pTimer)
-    {
-        TMR3TimerDestroy(pQueue->pTimer);
-        pQueue->pTimer = NULL;
+    if (pQueue->hTimer != NIL_TMTIMERHANDLE)
+    {
+        TMR3TimerDestroy(pVM, pQueue->hTimer);
+        pQueue->hTimer = NIL_TMTIMERHANDLE;
     }
     if (pQueue->pVMRC)
@@ -856,15 +856,10 @@
 
 /**
- * Timer handler for PDM queues.
- * This is called by for a single queue.
- *
- * @param   pVM     The cross context VM structure.
- * @param   pTimer  Pointer to timer.
- * @param   pvUser  Pointer to the queue.
- */
-static DECLCALLBACK(void) pdmR3QueueTimer(PVM pVM, PTMTIMER pTimer, void *pvUser)
+ * @callback_method_impl{FNTMTIMERINT, Timer handler for one PDM queue.}
+ */
+static DECLCALLBACK(void) pdmR3QueueTimer(PVM pVM, TMTIMERHANDLE hTimer, void *pvUser)
 {
     PPDMQUEUE pQueue = (PPDMQUEUE)pvUser;
-    Assert(pTimer == pQueue->pTimer); NOREF(pTimer); NOREF(pVM);
+    Assert(hTimer == pQueue->hTimer);
 
     if (   pQueue->pPendingR3
@@ -872,5 +867,5 @@
         || pQueue->pPendingRC)
         pdmR3QueueFlush(pQueue);
-    int rc = TMTimerSetMillies(pQueue->pTimer, pQueue->cMilliesInterval);
+    int rc = TMTimerSetMillies(pVM, hTimer, pQueue->cMilliesInterval);
     AssertRC(rc);
 }
Index: /trunk/src/VBox/VMM/VMMR3/PDMUsb.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMUsb.cpp	(revision 87765)
+++ /trunk/src/VBox/VMM/VMMR3/PDMUsb.cpp	(revision 87766)
@@ -1833,8 +1833,5 @@
         pszDesc = pszDesc2;
 
-    PTMTIMERR3 pTimer = NULL;
-    int rc = TMR3TimerCreateUsb(pVM, pUsbIns, enmClock, pfnCallback, pvUser, fFlags, pszDesc, &pTimer);
-    if (RT_SUCCESS(rc))
-        *phTimer = (TMTIMERHANDLE)pTimer;
+    int rc = TMR3TimerCreateUsb(pVM, pUsbIns, enmClock, pfnCallback, pvUser, fFlags, pszDesc, phTimer);
 
     LogFlow(("pdmR3UsbHlp_TMTimerCreate: caller='%s'/%d: returns %Rrc *phTimer=%p\n", pUsbIns->pReg->szName, pUsbIns->iInstance, rc, *phTimer));
@@ -1843,17 +1840,9 @@
 
 
-/** Converts timer handle to pointer (will be replace soon.) */
-DECLINLINE(PTMTIMERR3) pdmR3UsbHlp_TimerToPtr(PPDMUSBINS pUsbIns, TMTIMERHANDLE hTimer)
-{
-    PDMUSB_ASSERT_USBINS(pUsbIns);
-    RT_NOREF(pUsbIns);
-    return (PTMTIMERR3)hTimer;
-}
-
-
 /** @interface_method_impl{PDMUSBHLP,pfnTimerFromMicro} */
 static DECLCALLBACK(uint64_t) pdmR3UsbHlp_TimerFromMicro(PPDMUSBINS pUsbIns, TMTIMERHANDLE hTimer, uint64_t cMicroSecs)
 {
-    return TMTimerFromMicro(pdmR3UsbHlp_TimerToPtr(pUsbIns, hTimer), cMicroSecs);
+    PDMUSB_ASSERT_USBINS(pUsbIns);
+    return TMTimerFromMicro(pUsbIns->Internal.s.pVM, hTimer, cMicroSecs);
 }
 
@@ -1863,5 +1852,5 @@
 {
     PDMUSB_ASSERT_USBINS(pUsbIns);
-    return TMTimerFromMilli(pUsbIns->Internal.s.pVM, pdmR3UsbHlp_TimerToPtr(pUsbIns, hTimer), cMilliSecs);
+    return TMTimerFromMilli(pUsbIns->Internal.s.pVM, hTimer, cMilliSecs);
 }
 
@@ -1870,5 +1859,6 @@
 static DECLCALLBACK(uint64_t) pdmR3UsbHlp_TimerFromNano(PPDMUSBINS pUsbIns, TMTIMERHANDLE hTimer, uint64_t cNanoSecs)
 {
-    return TMTimerFromNano(pdmR3UsbHlp_TimerToPtr(pUsbIns, hTimer), cNanoSecs);
+    PDMUSB_ASSERT_USBINS(pUsbIns);
+    return TMTimerFromNano(pUsbIns->Internal.s.pVM, hTimer, cNanoSecs);
 }
 
@@ -1876,5 +1866,6 @@
 static DECLCALLBACK(uint64_t) pdmR3UsbHlp_TimerGet(PPDMUSBINS pUsbIns, TMTIMERHANDLE hTimer)
 {
-    return TMTimerGet(pdmR3UsbHlp_TimerToPtr(pUsbIns, hTimer));
+    PDMUSB_ASSERT_USBINS(pUsbIns);
+    return TMTimerGet(pUsbIns->Internal.s.pVM, hTimer);
 }
 
@@ -1883,5 +1874,6 @@
 static DECLCALLBACK(uint64_t) pdmR3UsbHlp_TimerGetFreq(PPDMUSBINS pUsbIns, TMTIMERHANDLE hTimer)
 {
-    return TMTimerGetFreq(pdmR3UsbHlp_TimerToPtr(pUsbIns, hTimer));
+    PDMUSB_ASSERT_USBINS(pUsbIns);
+    return TMTimerGetFreq(pUsbIns->Internal.s.pVM, hTimer);
 }
 
@@ -1890,5 +1882,6 @@
 static DECLCALLBACK(uint64_t) pdmR3UsbHlp_TimerGetNano(PPDMUSBINS pUsbIns, TMTIMERHANDLE hTimer)
 {
-    return TMTimerGetNano(pdmR3UsbHlp_TimerToPtr(pUsbIns, hTimer));
+    PDMUSB_ASSERT_USBINS(pUsbIns);
+    return TMTimerGetNano(pUsbIns->Internal.s.pVM, hTimer);
 }
 
@@ -1897,5 +1890,6 @@
 static DECLCALLBACK(bool) pdmR3UsbHlp_TimerIsActive(PPDMUSBINS pUsbIns, TMTIMERHANDLE hTimer)
 {
-    return TMTimerIsActive(pdmR3UsbHlp_TimerToPtr(pUsbIns, hTimer));
+    PDMUSB_ASSERT_USBINS(pUsbIns);
+    return TMTimerIsActive(pUsbIns->Internal.s.pVM, hTimer);
 }
 
@@ -1904,5 +1898,6 @@
 static DECLCALLBACK(bool) pdmR3UsbHlp_TimerIsLockOwner(PPDMUSBINS pUsbIns, TMTIMERHANDLE hTimer)
 {
-    return TMTimerIsLockOwner(pdmR3UsbHlp_TimerToPtr(pUsbIns, hTimer));
+    PDMUSB_ASSERT_USBINS(pUsbIns);
+    return TMTimerIsLockOwner(pUsbIns->Internal.s.pVM, hTimer);
 }
 
@@ -1911,5 +1906,6 @@
 static DECLCALLBACK(int) pdmR3UsbHlp_TimerLockClock(PPDMUSBINS pUsbIns, TMTIMERHANDLE hTimer)
 {
-    return TMTimerLock(pdmR3UsbHlp_TimerToPtr(pUsbIns, hTimer), VERR_IGNORED);
+    PDMUSB_ASSERT_USBINS(pUsbIns);
+    return TMTimerLock(pUsbIns->Internal.s.pVM, hTimer, VERR_IGNORED);
 }
 
@@ -1918,5 +1914,6 @@
 static DECLCALLBACK(int) pdmR3UsbHlp_TimerLockClock2(PPDMUSBINS pUsbIns, TMTIMERHANDLE hTimer, PPDMCRITSECT pCritSect)
 {
-    int rc = TMTimerLock(pdmR3UsbHlp_TimerToPtr(pUsbIns, hTimer), VERR_IGNORED);
+    PDMUSB_ASSERT_USBINS(pUsbIns);
+    int rc = TMTimerLock(pUsbIns->Internal.s.pVM, hTimer, VERR_IGNORED);
     if (rc == VINF_SUCCESS)
     {
@@ -1925,5 +1922,5 @@
             return rc;
         AssertRC(rc);
-        TMTimerUnlock(pdmR3UsbHlp_TimerToPtr(pUsbIns, hTimer));
+        TMTimerUnlock(pUsbIns->Internal.s.pVM, hTimer);
     }
     else
@@ -1936,5 +1933,6 @@
 static DECLCALLBACK(int) pdmR3UsbHlp_TimerSet(PPDMUSBINS pUsbIns, TMTIMERHANDLE hTimer, uint64_t uExpire)
 {
-    return TMTimerSet(pdmR3UsbHlp_TimerToPtr(pUsbIns, hTimer), uExpire);
+    PDMUSB_ASSERT_USBINS(pUsbIns);
+    return TMTimerSet(pUsbIns->Internal.s.pVM, hTimer, uExpire);
 }
 
@@ -1943,5 +1941,6 @@
 static DECLCALLBACK(int) pdmR3UsbHlp_TimerSetFrequencyHint(PPDMUSBINS pUsbIns, TMTIMERHANDLE hTimer, uint32_t uHz)
 {
-    return TMTimerSetFrequencyHint(pdmR3UsbHlp_TimerToPtr(pUsbIns, hTimer), uHz);
+    PDMUSB_ASSERT_USBINS(pUsbIns);
+    return TMTimerSetFrequencyHint(pUsbIns->Internal.s.pVM, hTimer, uHz);
 }
 
@@ -1950,5 +1949,6 @@
 static DECLCALLBACK(int) pdmR3UsbHlp_TimerSetMicro(PPDMUSBINS pUsbIns, TMTIMERHANDLE hTimer, uint64_t cMicrosToNext)
 {
-    return TMTimerSetMicro(pdmR3UsbHlp_TimerToPtr(pUsbIns, hTimer), cMicrosToNext);
+    PDMUSB_ASSERT_USBINS(pUsbIns);
+    return TMTimerSetMicro(pUsbIns->Internal.s.pVM, hTimer, cMicrosToNext);
 }
 
@@ -1957,5 +1957,6 @@
 static DECLCALLBACK(int) pdmR3UsbHlp_TimerSetMillies(PPDMUSBINS pUsbIns, TMTIMERHANDLE hTimer, uint64_t cMilliesToNext)
 {
-    return TMTimerSetMillies(pdmR3UsbHlp_TimerToPtr(pUsbIns, hTimer), cMilliesToNext);
+    PDMUSB_ASSERT_USBINS(pUsbIns);
+    return TMTimerSetMillies(pUsbIns->Internal.s.pVM, hTimer, cMilliesToNext);
 }
 
@@ -1964,5 +1965,6 @@
 static DECLCALLBACK(int) pdmR3UsbHlp_TimerSetNano(PPDMUSBINS pUsbIns, TMTIMERHANDLE hTimer, uint64_t cNanosToNext)
 {
-    return TMTimerSetNano(pdmR3UsbHlp_TimerToPtr(pUsbIns, hTimer), cNanosToNext);
+    PDMUSB_ASSERT_USBINS(pUsbIns);
+    return TMTimerSetNano(pUsbIns->Internal.s.pVM, hTimer, cNanosToNext);
 }
 
@@ -1971,5 +1973,6 @@
 static DECLCALLBACK(int) pdmR3UsbHlp_TimerSetRelative(PPDMUSBINS pUsbIns, TMTIMERHANDLE hTimer, uint64_t cTicksToNext, uint64_t *pu64Now)
 {
-    return TMTimerSetRelative(pdmR3UsbHlp_TimerToPtr(pUsbIns, hTimer), cTicksToNext, pu64Now);
+    PDMUSB_ASSERT_USBINS(pUsbIns);
+    return TMTimerSetRelative(pUsbIns->Internal.s.pVM, hTimer, cTicksToNext, pu64Now);
 }
 
@@ -1978,5 +1981,6 @@
 static DECLCALLBACK(int) pdmR3UsbHlp_TimerStop(PPDMUSBINS pUsbIns, TMTIMERHANDLE hTimer)
 {
-    return TMTimerStop(pdmR3UsbHlp_TimerToPtr(pUsbIns, hTimer));
+    PDMUSB_ASSERT_USBINS(pUsbIns);
+    return TMTimerStop(pUsbIns->Internal.s.pVM, hTimer);
 }
 
@@ -1985,5 +1989,6 @@
 static DECLCALLBACK(void) pdmR3UsbHlp_TimerUnlockClock(PPDMUSBINS pUsbIns, TMTIMERHANDLE hTimer)
 {
-    TMTimerUnlock(pdmR3UsbHlp_TimerToPtr(pUsbIns, hTimer));
+    PDMUSB_ASSERT_USBINS(pUsbIns);
+    TMTimerUnlock(pUsbIns->Internal.s.pVM, hTimer);
 }
 
@@ -1992,5 +1997,6 @@
 static DECLCALLBACK(void) pdmR3UsbHlp_TimerUnlockClock2(PPDMUSBINS pUsbIns, TMTIMERHANDLE hTimer, PPDMCRITSECT pCritSect)
 {
-    TMTimerUnlock(pdmR3UsbHlp_TimerToPtr(pUsbIns, hTimer));
+    PDMUSB_ASSERT_USBINS(pUsbIns);
+    TMTimerUnlock(pUsbIns->Internal.s.pVM, hTimer);
     int rc = PDMCritSectLeave(pCritSect);
     AssertRC(rc);
@@ -2001,5 +2007,6 @@
 static DECLCALLBACK(int) pdmR3UsbHlp_TimerSetCritSect(PPDMUSBINS pUsbIns, TMTIMERHANDLE hTimer, PPDMCRITSECT pCritSect)
 {
-    return TMR3TimerSetCritSect(pdmR3UsbHlp_TimerToPtr(pUsbIns, hTimer), pCritSect);
+    PDMUSB_ASSERT_USBINS(pUsbIns);
+    return TMR3TimerSetCritSect(pUsbIns->Internal.s.pVM, hTimer, pCritSect);
 }
 
@@ -2008,5 +2015,6 @@
 static DECLCALLBACK(int) pdmR3UsbHlp_TimerSave(PPDMUSBINS pUsbIns, TMTIMERHANDLE hTimer, PSSMHANDLE pSSM)
 {
-    return TMR3TimerSave(pdmR3UsbHlp_TimerToPtr(pUsbIns, hTimer), pSSM);
+    PDMUSB_ASSERT_USBINS(pUsbIns);
+    return TMR3TimerSave(pUsbIns->Internal.s.pVM, hTimer, pSSM);
 }
 
@@ -2015,5 +2023,6 @@
 static DECLCALLBACK(int) pdmR3UsbHlp_TimerLoad(PPDMUSBINS pUsbIns, TMTIMERHANDLE hTimer, PSSMHANDLE pSSM)
 {
-    return TMR3TimerLoad(pdmR3UsbHlp_TimerToPtr(pUsbIns, hTimer), pSSM);
+    PDMUSB_ASSERT_USBINS(pUsbIns);
+    return TMR3TimerLoad(pUsbIns->Internal.s.pVM, hTimer, pSSM);
 }
 
@@ -2022,5 +2031,6 @@
 static DECLCALLBACK(int) pdmR3UsbHlp_TimerDestroy(PPDMUSBINS pUsbIns, TMTIMERHANDLE hTimer)
 {
-    return TMR3TimerDestroy(pdmR3UsbHlp_TimerToPtr(pUsbIns, hTimer));
+    PDMUSB_ASSERT_USBINS(pUsbIns);
+    return TMR3TimerDestroy(pUsbIns->Internal.s.pVM, hTimer);
 }
 
Index: /trunk/src/VBox/VMM/VMMR3/TM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/TM.cpp	(revision 87765)
+++ /trunk/src/VBox/VMM/VMMR3/TM.cpp	(revision 87766)
@@ -180,5 +180,5 @@
 static DECLCALLBACK(int)    tmR3SetWarpDrive(PUVM pUVM, uint32_t u32Percent);
 #ifndef VBOX_WITHOUT_NS_ACCOUNTING
-static DECLCALLBACK(void)   tmR3CpuLoadTimer(PVM pVM, PTMTIMER pTimer, void *pvUser);
+static DECLCALLBACK(void)   tmR3CpuLoadTimer(PVM pVM, TMTIMERHANDLE hTimer, void *pvUser);
 #endif
 static DECLCALLBACK(void)   tmR3TimerInfo(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);
@@ -1100,8 +1100,8 @@
      * Create a timer for refreshing the CPU load stats.
      */
-    PTMTIMER pTimer;
-    rc = TMR3TimerCreate(pVM, TMCLOCK_REAL, tmR3CpuLoadTimer, NULL, TMTIMER_FLAGS_NO_RING0, "CPU Load Timer", &pTimer);
+    TMTIMERHANDLE hTimer;
+    rc = TMR3TimerCreate(pVM, TMCLOCK_REAL, tmR3CpuLoadTimer, NULL, TMTIMER_FLAGS_NO_RING0, "CPU Load Timer", &hTimer);
     if (RT_SUCCESS(rc))
-        rc = TMTimerSetMillies(pTimer, 1000);
+        rc = TMTimerSetMillies(pVM, hTimer, 1000);
 #endif
 
@@ -1542,4 +1542,5 @@
     pTimer->u64Expire       = 0;
     pTimer->enmClock        = enmClock;
+    pTimer->hSelf           = (TMTIMERHANDLE)pTimer;
     pTimer->pVMR3           = pVM;
     pTimer->pVMR0           = pVM->pVMR0ForCall; /** @todo fix properly */
@@ -1602,9 +1603,9 @@
  * @param   pszDesc         Pointer to description string which must stay around
  *                          until the timer is fully destroyed (i.e. a bit after TMTimerDestroy()).
- * @param   ppTimer         Where to store the timer on success.
+ * @param   phTimer         Where to store the timer handle on success.
  */
 VMM_INT_DECL(int) TMR3TimerCreateDevice(PVM pVM, PPDMDEVINS pDevIns, TMCLOCK enmClock,
                                         PFNTMTIMERDEV pfnCallback, void *pvUser,
-                                        uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer)
+                                        uint32_t fFlags, const char *pszDesc, PTMTIMERHANDLE phTimer)
 {
     AssertReturn(!(fFlags & ~(TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_RING0 | TMTIMER_FLAGS_NO_RING0)),
@@ -1614,14 +1615,16 @@
      * Allocate and init stuff.
      */
-    int rc = tmr3TimerCreate(pVM, enmClock, fFlags, pszDesc, ppTimer);
+    PTMTIMER pTimer;
+    int rc = tmr3TimerCreate(pVM, enmClock, fFlags, pszDesc, &pTimer);
     if (RT_SUCCESS(rc))
     {
-        (*ppTimer)->enmType         = TMTIMERTYPE_DEV;
-        (*ppTimer)->u.Dev.pfnTimer  = pfnCallback;
-        (*ppTimer)->u.Dev.pDevIns   = pDevIns;
-        (*ppTimer)->pvUser          = pvUser;
+        pTimer->enmType         = TMTIMERTYPE_DEV;
+        pTimer->u.Dev.pfnTimer  = pfnCallback;
+        pTimer->u.Dev.pDevIns   = pDevIns;
+        pTimer->pvUser          = pvUser;
         if (!(fFlags & TMTIMER_FLAGS_NO_CRIT_SECT))
-            (*ppTimer)->pCritSect = PDMR3DevGetCritSect(pVM, pDevIns);
-        Log(("TM: Created device timer %p clock %d callback %p '%s'\n", (*ppTimer), enmClock, pfnCallback, pszDesc));
+            pTimer->pCritSect = PDMR3DevGetCritSect(pVM, pDevIns);
+        *phTimer = pTimer->hSelf;
+        Log(("TM: Created device timer %p clock %d callback %p '%s'\n", phTimer, enmClock, pfnCallback, pszDesc));
     }
 
@@ -1644,9 +1647,9 @@
  * @param   pszDesc         Pointer to description string which must stay around
  *                          until the timer is fully destroyed (i.e. a bit after TMTimerDestroy()).
- * @param   ppTimer         Where to store the timer on success.
+ * @param   phTimer         Where to store the timer handle on success.
  */
 VMM_INT_DECL(int) TMR3TimerCreateUsb(PVM pVM, PPDMUSBINS pUsbIns, TMCLOCK enmClock,
                                      PFNTMTIMERUSB pfnCallback, void *pvUser,
-                                     uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer)
+                                     uint32_t fFlags, const char *pszDesc, PTMTIMERHANDLE phTimer)
 {
     AssertReturn(!(fFlags & ~(TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_NO_RING0)), VERR_INVALID_PARAMETER);
@@ -1655,19 +1658,21 @@
      * Allocate and init stuff.
      */
-    int rc = tmr3TimerCreate(pVM, enmClock, fFlags, pszDesc, ppTimer);
+    PTMTIMER pTimer;
+    int rc = tmr3TimerCreate(pVM, enmClock, fFlags, pszDesc, &pTimer);
     if (RT_SUCCESS(rc))
     {
-        (*ppTimer)->enmType         = TMTIMERTYPE_USB;
-        (*ppTimer)->u.Usb.pfnTimer  = pfnCallback;
-        (*ppTimer)->u.Usb.pUsbIns   = pUsbIns;
-        (*ppTimer)->pvUser          = pvUser;
+        pTimer->enmType         = TMTIMERTYPE_USB;
+        pTimer->u.Usb.pfnTimer  = pfnCallback;
+        pTimer->u.Usb.pUsbIns   = pUsbIns;
+        pTimer->pvUser          = pvUser;
         //if (!(fFlags & TMTIMER_FLAGS_NO_CRIT_SECT))
         //{
         //    if (pDevIns->pCritSectR3)
-        //        (*ppTimer)->pCritSect = pUsbIns->pCritSectR3;
+        //        pTimer->pCritSect = pUsbIns->pCritSectR3;
         //    else
-        //        (*ppTimer)->pCritSect = IOMR3GetCritSect(pVM);
+        //        pTimer->pCritSect = IOMR3GetCritSect(pVM);
         //}
-        Log(("TM: Created USB device timer %p clock %d callback %p '%s'\n", (*ppTimer), enmClock, pfnCallback, pszDesc));
+        *phTimer = pTimer->hSelf;
+        Log(("TM: Created USB device timer %p clock %d callback %p '%s'\n", *phTimer, enmClock, pfnCallback, pszDesc));
     }
 
@@ -1688,8 +1693,8 @@
  * @param   pszDesc         Pointer to description string which must stay around
  *                          until the timer is fully destroyed (i.e. a bit after TMTimerDestroy()).
- * @param   ppTimer         Where to store the timer on success.
+ * @param   phTimer         Where to store the timer handle on success.
  */
 VMM_INT_DECL(int) TMR3TimerCreateDriver(PVM pVM, PPDMDRVINS pDrvIns, TMCLOCK enmClock, PFNTMTIMERDRV pfnCallback, void *pvUser,
-                                        uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer)
+                                        uint32_t fFlags, const char *pszDesc, PTMTIMERHANDLE phTimer)
 {
     AssertReturn(!(fFlags & ~(TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_RING0 | TMTIMER_FLAGS_NO_RING0)),
@@ -1699,12 +1704,14 @@
      * Allocate and init stuff.
      */
-    int rc = tmr3TimerCreate(pVM, enmClock, fFlags, pszDesc, ppTimer);
+    PTMTIMER pTimer;
+    int rc = tmr3TimerCreate(pVM, enmClock, fFlags, pszDesc, &pTimer);
     if (RT_SUCCESS(rc))
     {
-        (*ppTimer)->enmType         = TMTIMERTYPE_DRV;
-        (*ppTimer)->u.Drv.pfnTimer  = pfnCallback;
-        (*ppTimer)->u.Drv.pDrvIns   = pDrvIns;
-        (*ppTimer)->pvUser          = pvUser;
-        Log(("TM: Created device timer %p clock %d callback %p '%s'\n", (*ppTimer), enmClock, pfnCallback, pszDesc));
+        pTimer->enmType         = TMTIMERTYPE_DRV;
+        pTimer->u.Drv.pfnTimer  = pfnCallback;
+        pTimer->u.Drv.pDrvIns   = pDrvIns;
+        pTimer->pvUser          = pvUser;
+        *phTimer = pTimer->hSelf;
+        Log(("TM: Created device timer %p clock %d callback %p '%s'\n", *phTimer, enmClock, pfnCallback, pszDesc));
     }
 
@@ -1724,8 +1731,8 @@
  * @param   pszDesc         Pointer to description string which must stay around
  *                          until the timer is fully destroyed (i.e. a bit after TMTimerDestroy()).
- * @param   ppTimer         Where to store the timer on success.
+ * @param   phTimer         Where to store the timer handle on success.
  */
 VMMR3DECL(int) TMR3TimerCreate(PVM pVM, TMCLOCK enmClock, PFNTMTIMERINT pfnCallback, void *pvUser,
-                               uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer)
+                               uint32_t fFlags, const char *pszDesc, PTMTIMERHANDLE phTimer)
 {
     AssertReturn(fFlags & (TMTIMER_FLAGS_RING0 | TMTIMER_FLAGS_NO_RING0), VERR_INVALID_FLAGS);
@@ -1743,5 +1750,5 @@
         pTimer->u.Internal.pfnTimer = pfnCallback;
         pTimer->pvUser              = pvUser;
-        *ppTimer = pTimer;
+        *phTimer = pTimer->hSelf;
         Log(("TM: Created internal timer %p clock %d callback %p '%s'\n", pTimer, enmClock, pfnCallback, pszDesc));
     }
@@ -1757,15 +1764,8 @@
  * @param   pTimer          Timer handle as returned by one of the create functions.
  */
-VMMR3DECL(int) TMR3TimerDestroy(PTMTIMER pTimer)
-{
-    /*
-     * Be extra careful here.
-     */
-    if (!pTimer)
-        return VINF_SUCCESS;
-    AssertPtr(pTimer);
+static int tmR3TimerDestroy(PVMCC pVM, PTMTIMER pTimer)
+{
     Assert((unsigned)pTimer->enmClock < (unsigned)TMCLOCK_MAX);
 
-    PVM             pVM      = pTimer->CTX_SUFF(pVM);
     PTMTIMERQUEUE   pQueue   = &pVM->tm.s.CTX_SUFF(paTimerQueues)[pTimer->enmClock];
     bool            fActive  = false;
@@ -1925,4 +1925,22 @@
 
 /**
+ * Destroy a timer
+ *
+ * @returns VBox status code.
+ * @param   pVM         The cross context VM structure.
+ * @param   hTimer      Timer handle as returned by one of the create functions.
+ */
+VMMR3DECL(int) TMR3TimerDestroy(PVM pVM, TMTIMERHANDLE hTimer)
+{
+    /* We ignore NILs here. */
+    if (hTimer == NIL_TMTIMERHANDLE)
+        return VINF_SUCCESS;
+    PTMTIMER pTimer;
+    TMTIMER_HANDLE_TO_PTR_RETURN(pVM, hTimer, pTimer);
+    return tmR3TimerDestroy(pVM, pTimer);
+}
+
+
+/**
  * Destroy all timers owned by a device.
  *
@@ -1946,5 +1964,5 @@
             &&  pDestroy->u.Dev.pDevIns == pDevIns)
         {
-            int rc = TMR3TimerDestroy(pDestroy);
+            int rc = tmR3TimerDestroy(pVM, pDestroy);
             AssertRC(rc);
         }
@@ -1979,5 +1997,5 @@
             &&  pDestroy->u.Usb.pUsbIns == pUsbIns)
         {
-            int rc = TMR3TimerDestroy(pDestroy);
+            int rc = tmR3TimerDestroy(pVM, pDestroy);
             AssertRC(rc);
         }
@@ -2012,5 +2030,5 @@
             &&  pDestroy->u.Drv.pDrvIns == pDrvIns)
         {
-            int rc = TMR3TimerDestroy(pDestroy);
+            int rc = tmR3TimerDestroy(pVM, pDestroy);
             AssertRC(rc);
         }
@@ -2288,5 +2306,5 @@
                 case TMTIMERTYPE_USB:       pTimer->u.Usb.pfnTimer(pTimer->u.Usb.pUsbIns, pTimer, pTimer->pvUser); break;
                 case TMTIMERTYPE_DRV:       pTimer->u.Drv.pfnTimer(pTimer->u.Drv.pDrvIns, pTimer, pTimer->pvUser); break;
-                case TMTIMERTYPE_INTERNAL:  pTimer->u.Internal.pfnTimer(pVM, pTimer, pTimer->pvUser); break;
+                case TMTIMERTYPE_INTERNAL:  pTimer->u.Internal.pfnTimer(pVM, pTimer->hSelf, pTimer->pvUser); break;
                 default:
                     AssertMsgFailed(("Invalid timer type %d (%s)\n", pTimer->enmType, pTimer->pszDesc));
@@ -2472,5 +2490,5 @@
             case TMTIMERTYPE_USB:       pTimer->u.Usb.pfnTimer(pTimer->u.Usb.pUsbIns, pTimer, pTimer->pvUser); break;
             case TMTIMERTYPE_DRV:       pTimer->u.Drv.pfnTimer(pTimer->u.Drv.pDrvIns, pTimer, pTimer->pvUser); break;
-            case TMTIMERTYPE_INTERNAL:  pTimer->u.Internal.pfnTimer(pVM, pTimer, pTimer->pvUser); break;
+            case TMTIMERTYPE_INTERNAL:  pTimer->u.Internal.pfnTimer(pVM, pTimer->hSelf, pTimer->pvUser); break;
             default:
                 AssertMsgFailed(("Invalid timer type %d (%s)\n", pTimer->enmType, pTimer->pszDesc));
@@ -2696,10 +2714,15 @@
  *
  * @returns VBox status code.
- * @param   pTimer          Timer to save.
+ * @param   pVM             The cross context VM structure.
+ * @param   hTimer          Timer to save.
  * @param   pSSM            Save State Manager handle.
  */
-VMMR3DECL(int) TMR3TimerSave(PTMTIMERR3 pTimer, PSSMHANDLE pSSM)
-{
+VMMR3DECL(int) TMR3TimerSave(PVM pVM, TMTIMERHANDLE hTimer, PSSMHANDLE pSSM)
+{
+    VM_ASSERT_EMT(pVM);
+    PTMTIMER pTimer;
+    TMTIMER_HANDLE_TO_PTR_RETURN(pVM, hTimer, pTimer);
     LogFlow(("TMR3TimerSave: %p:{enmState=%s, .pszDesc={%s}} pSSM=%p\n", pTimer, tmTimerState(pTimer->enmState), pTimer->pszDesc, pSSM));
+
     switch (pTimer->enmState)
     {
@@ -2738,10 +2761,14 @@
  *
  * @returns VBox status code.
- * @param   pTimer          Timer to restore.
+ * @param   pVM             The cross context VM structure.
+ * @param   hTimer          Handle of Timer to restore.
  * @param   pSSM            Save State Manager handle.
  */
-VMMR3DECL(int) TMR3TimerLoad(PTMTIMERR3 pTimer, PSSMHANDLE pSSM)
-{
-    Assert(pTimer); Assert(pSSM); VM_ASSERT_EMT(pTimer->pVMR3);
+VMMR3DECL(int) TMR3TimerLoad(PVM pVM, TMTIMERHANDLE hTimer, PSSMHANDLE pSSM)
+{
+    VM_ASSERT_EMT(pVM);
+    PTMTIMER pTimer;
+    TMTIMER_HANDLE_TO_PTR_RETURN(pVM, hTimer, pTimer);
+    Assert(pSSM);
     LogFlow(("TMR3TimerLoad: %p:{enmState=%s, .pszDesc={%s}} pSSM=%p\n", pTimer, tmTimerState(pTimer->enmState), pTimer->pszDesc, pSSM));
 
@@ -2787,5 +2814,5 @@
          */
         Log(("u8State=%d u64Expire=%llu\n", u8State, u64Expire));
-        rc = TMTimerSet(pTimer, u64Expire);
+        rc = TMTimerSet(pVM, hTimer, u64Expire);
     }
     else
@@ -2795,5 +2822,5 @@
          */
         Log(("u8State=%d\n", u8State));
-        rc = TMTimerStop(pTimer);
+        rc = TMTimerStop(pVM, hTimer);
     }
 
@@ -2887,7 +2914,8 @@
  *          active.
  */
-VMMR3DECL(int) TMR3TimerSetCritSect(PTMTIMERR3 pTimer, PPDMCRITSECT pCritSect)
-{
-    AssertPtrReturn(pTimer, VERR_INVALID_HANDLE);
+VMMR3DECL(int) TMR3TimerSetCritSect(PVM pVM, TMTIMERHANDLE hTimer, PPDMCRITSECT pCritSect)
+{
+    PTMTIMER pTimer;
+    TMTIMER_HANDLE_TO_PTR_RETURN(pVM, hTimer, pTimer);
     AssertPtrReturn(pCritSect, VERR_INVALID_PARAMETER);
     const char *pszName = PDMR3CritSectName(pCritSect); /* exploited for validation */
@@ -3414,17 +3442,14 @@
 
 /**
- * Timer callback that calculates the CPU load since the last time it was
- * called.
- *
- * @param   pVM                 The cross context VM structure.
- * @param   pTimer              The timer.
- * @param   pvUser              NULL, unused.
- */
-static DECLCALLBACK(void) tmR3CpuLoadTimer(PVM pVM, PTMTIMER pTimer, void *pvUser)
+ * @callback_method_impl{FNTMTIMERINT,
+ *      Timer callback that calculates the CPU load since the last
+ *      time it was called.}
+ */
+static DECLCALLBACK(void) tmR3CpuLoadTimer(PVM pVM, TMTIMERHANDLE hTimer, void *pvUser)
 {
     /*
      * Re-arm the timer first.
      */
-    int rc = TMTimerSetMillies(pTimer, 1000);
+    int rc = TMTimerSetMillies(pVM, hTimer, 1000);
     AssertLogRelRC(rc);
     NOREF(pvUser);
@@ -3680,5 +3705,5 @@
                         pTimer->offScheduleNext,
                         tmR3Get5CharClockName(pTimer->enmClock),
-                        TMTimerGet(pTimer),
+                        TMTimerGet(pVM, pTimer->hSelf),
                         pTimer->u64Expire,
                         pTimer->uHzHint,
@@ -3726,5 +3751,5 @@
                             pTimer->offScheduleNext,
                             tmR3Get5CharClockName(pTimer->enmClock),
-                            TMTimerGet(pTimer),
+                            TMTimerGet(pVM, pTimer->hSelf),
                             pTimer->u64Expire,
                             pTimer->uHzHint,
Index: /trunk/src/VBox/VMM/VMMR3/VMM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/VMM.cpp	(revision 87765)
+++ /trunk/src/VBox/VMM/VMMR3/VMM.cpp	(revision 87766)
@@ -169,5 +169,5 @@
 static DECLCALLBACK(int)    vmmR3Save(PVM pVM, PSSMHANDLE pSSM);
 static DECLCALLBACK(int)    vmmR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass);
-static DECLCALLBACK(void)   vmmR3YieldEMT(PVM pVM, PTMTIMER pTimer, void *pvUser);
+static DECLCALLBACK(void)   vmmR3YieldEMT(PVM pVM, TMTIMERHANDLE hTimer, void *pvUser);
 static VBOXSTRICTRC         vmmR3EmtRendezvousCommon(PVM pVM, PVMCPU pVCpu, bool fIsCaller,
                                                      uint32_t fFlags, PFNVMMEMTRENDEZVOUS pfnRendezvous, void *pvUser);
@@ -661,8 +661,8 @@
              */
             rc = TMR3TimerCreate(pVM, TMCLOCK_REAL, vmmR3YieldEMT, NULL, TMTIMER_FLAGS_NO_RING0,
-                                 "EMT Yielder", &pVM->vmm.s.pYieldTimer);
+                                 "EMT Yielder", &pVM->vmm.s.hYieldTimer);
             AssertRCReturn(rc, rc);
 
-            rc = TMTimerSetMillies(pVM->vmm.s.pYieldTimer, pVM->vmm.s.cYieldEveryMillies);
+            rc = TMTimerSetMillies(pVM, pVM->vmm.s.hYieldTimer, pVM->vmm.s.cYieldEveryMillies);
             AssertRCReturn(rc, rc);
             break;
@@ -998,11 +998,11 @@
     if (!pVM->vmm.s.cYieldResumeMillies)
     {
-        uint64_t u64Now = TMTimerGet(pVM->vmm.s.pYieldTimer);
-        uint64_t u64Expire = TMTimerGetExpire(pVM->vmm.s.pYieldTimer);
+        uint64_t u64Now = TMTimerGet(pVM, pVM->vmm.s.hYieldTimer);
+        uint64_t u64Expire = TMTimerGetExpire(pVM, pVM->vmm.s.hYieldTimer);
         if (u64Now >= u64Expire || u64Expire == ~(uint64_t)0)
             pVM->vmm.s.cYieldResumeMillies = pVM->vmm.s.cYieldEveryMillies;
         else
-            pVM->vmm.s.cYieldResumeMillies = TMTimerToMilli(pVM->vmm.s.pYieldTimer, u64Expire - u64Now);
-        TMTimerStop(pVM->vmm.s.pYieldTimer);
+            pVM->vmm.s.cYieldResumeMillies = TMTimerToMilli(pVM, pVM->vmm.s.hYieldTimer, u64Expire - u64Now);
+        TMTimerStop(pVM, pVM->vmm.s.hYieldTimer);
     }
     pVM->vmm.s.u64LastYield = RTTimeNanoTS();
@@ -1018,5 +1018,5 @@
 {
     if (!pVM->vmm.s.cYieldResumeMillies)
-        TMTimerStop(pVM->vmm.s.pYieldTimer);
+        TMTimerStop(pVM, pVM->vmm.s.hYieldTimer);
     pVM->vmm.s.cYieldResumeMillies = pVM->vmm.s.cYieldEveryMillies;
     pVM->vmm.s.u64LastYield = RTTimeNanoTS();
@@ -1033,5 +1033,5 @@
     if (pVM->vmm.s.cYieldResumeMillies)
     {
-        TMTimerSetMillies(pVM->vmm.s.pYieldTimer, pVM->vmm.s.cYieldResumeMillies);
+        TMTimerSetMillies(pVM, pVM->vmm.s.hYieldTimer, pVM->vmm.s.cYieldResumeMillies);
         pVM->vmm.s.cYieldResumeMillies = 0;
     }
@@ -1040,11 +1040,9 @@
 
 /**
- * Internal timer callback function.
- *
- * @param   pVM             The cross context VM structure.
- * @param   pTimer          The timer handle.
- * @param   pvUser          User argument specified upon timer creation.
- */
-static DECLCALLBACK(void) vmmR3YieldEMT(PVM pVM, PTMTIMER pTimer, void *pvUser)
+ * @callback_method_impl{FNTMTIMERINT, EMT yielder}
+ *
+ * @todo This is a UNI core/thread thing, really...   Should be reconsidered.
+ */
+static DECLCALLBACK(void) vmmR3YieldEMT(PVM pVM, TMTIMERHANDLE hTimer, void *pvUser)
 {
     NOREF(pvUser);
@@ -1077,5 +1075,5 @@
 #endif
     }
-    TMTimerSetMillies(pTimer, pVM->vmm.s.cYieldEveryMillies);
+    TMTimerSetMillies(pVM, hTimer, pVM->vmm.s.cYieldEveryMillies);
 }
 
Index: /trunk/src/VBox/VMM/include/CPUMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/CPUMInternal.h	(revision 87765)
+++ /trunk/src/VBox/VMM/include/CPUMInternal.h	(revision 87766)
@@ -417,8 +417,6 @@
     CPUMCTXMSRS             GuestMsrs;
 
-    /** Nested VMX: VMX-preemption timer - R0 ptr. */
-    PTMTIMERR0              pNestedVmxPreemptTimerR0;
-    /** Nested VMX: VMX-preemption timer - R3 ptr. */
-    PTMTIMERR3              pNestedVmxPreemptTimerR3;
+    /** Nested VMX: VMX-preemption timer. */
+    TMTIMERHANDLE           hNestedVmxPreemptTimer;
 
     /** Use flags.
@@ -459,5 +457,5 @@
 
     /** Align the next member on a 64-byte boundary. */
-    uint8_t                 abPadding2[64 - (16 + 12 + 4 + 8 + 1 + 1)];
+    uint8_t                 abPadding2[64 - (8 + 12 + 4 + 8 + 1 + 1)];
 
     /** Saved host context.  Only valid while inside RC or HM contexts.
Index: /trunk/src/VBox/VMM/include/CPUMInternal.mac
===================================================================
--- /trunk/src/VBox/VMM/include/CPUMInternal.mac	(revision 87765)
+++ /trunk/src/VBox/VMM/include/CPUMInternal.mac	(revision 87766)
@@ -259,6 +259,5 @@
     ; Other stuff.
     ;
-    .pNestedVmxPreemptTimerR0   RTR0PTR_RES    1
-    .pNestedVmxPreemptTimerR3   RTR3PTR_RES    1
+    .hNestedVmxPreemptTimer   resq    1
 
     .fUseFlags            resd    1
@@ -275,6 +274,4 @@
 
     .fCpuIdApicFeatureVisible   resb    1
-
-    .abPadding2           resb    (64 - (RTR0PTR_CB + RTR3PTR_CB + 12 + 4 + RTR0PTR_CB + 1 + 1))
 
     ;
Index: /trunk/src/VBox/VMM/include/GIMHvInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/GIMHvInternal.h	(revision 87765)
+++ /trunk/src/VBox/VMM/include/GIMHvInternal.h	(revision 87766)
@@ -1263,8 +1263,6 @@
 typedef struct GIMHVSTIMER
 {
-    /** Synthetic timer object - R0 ptr. */
-    PTMTIMERR0                  pTimerR0;
-    /** Synthetic timer object - R3 ptr. */
-    PTMTIMERR3                  pTimerR3;
+    /** Synthetic timer handle. */
+    TMTIMERHANDLE               hTimer;
     /** Virtual CPU ID this timer belongs to (for reverse mapping). */
     VMCPUID                     idCpu;
Index: /trunk/src/VBox/VMM/include/PDMAsyncCompletionFileInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/PDMAsyncCompletionFileInternal.h	(revision 87765)
+++ /trunk/src/VBox/VMM/include/PDMAsyncCompletionFileInternal.h	(revision 87766)
@@ -277,5 +277,5 @@
 #ifdef PDM_ASYNC_COMPLETION_FILE_WITH_DELAY
     /** Timer for delayed request completion. */
-    PTMTIMERR3                          pTimer;
+    TMTIMERHANDLE                       hTimer;
     /** Milliseconds until the next delay expires. */
     volatile uint64_t                   cMilliesNext;
Index: /trunk/src/VBox/VMM/include/PDMBlkCacheInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/PDMBlkCacheInternal.h	(revision 87765)
+++ /trunk/src/VBox/VMM/include/PDMBlkCacheInternal.h	(revision 87766)
@@ -134,5 +134,5 @@
     volatile bool       fCommitInProgress;
     /** Commit interval timer */
-    PTMTIMERR3          pTimerCommit;
+    TMTIMERHANDLE       hTimerCommit;
     /** Number of endpoints using the cache. */
     uint32_t            cRefs;
Index: /trunk/src/VBox/VMM/include/PDMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/PDMInternal.h	(revision 87765)
+++ /trunk/src/VBox/VMM/include/PDMInternal.h	(revision 87766)
@@ -1044,5 +1044,5 @@
     uint32_t                        cMilliesInterval;
     /** Interval timer. Only used if cMilliesInterval is non-zero. */
-    PTMTIMERR3                      pTimer;
+    TMTIMERHANDLE                   hTimer;
     /** Pointer to the VM - R3. */
     PVMR3                           pVMR3;
Index: /trunk/src/VBox/VMM/include/TMInline.h
===================================================================
--- /trunk/src/VBox/VMM/include/TMInline.h	(revision 87765)
+++ /trunk/src/VBox/VMM/include/TMInline.h	(revision 87766)
@@ -56,4 +56,66 @@
 }
 
+
+/** @def TMTIMER_HANDLE_TO_PTR_RETURN_EX
+ * Converts a timer handle to a timer pointer, returning @a a_rcRet if the
+ * handle is invalid.
+ *
+ * @param   a_pVM       The cross context VM structure.
+ * @param   a_hTimer    The timer handle to translate.
+ * @param   a_rcRet     What to return on failure.
+ * @param   a_pTimerVar The timer variable to assign the resulting pointer to.
+ */
+#ifdef IN_RING3
+# define TMTIMER_HANDLE_TO_PTR_RETURN_EX(a_pVM, a_hTimer, a_rcRet, a_pTimerVar) do { \
+        RT_NOREF(a_pVM); \
+        (a_pTimerVar) = (PTMTIMER)hTimer; \
+        AssertPtrReturn((a_pTimerVar), a_rcRet); \
+        AssertReturn((a_pTimerVar)->hSelf == a_hTimer, a_rcRet); \
+    } while (0)
+#else
+# define TMTIMER_HANDLE_TO_PTR_RETURN_EX(a_pVM, a_hTimer, a_rcRet, a_pTimerVar) do { \
+        (a_pTimerVar) = (PTMTIMER)MMHyperR3ToCC(pVM, (RTR3PTR)hTimer); \
+        AssertPtrReturn((a_pTimerVar), a_rcRet); \
+        AssertReturn((a_pTimerVar)->hSelf == a_hTimer, a_rcRet); \
+        Assert((a_pTimerVar)->fFlags & TMTIMER_FLAGS_RING0); \
+    } while (0)
+#endif
+
+/** @def TMTIMER_HANDLE_TO_PTR_RETURN
+ * Converts a timer handle to a timer pointer, returning VERR_INVALID_HANDLE if
+ * invalid.
+ *
+ * @param   a_pVM       The cross context VM structure.
+ * @param   a_hTimer    The timer handle to translate.
+ * @param   a_pTimerVar The timer variable to assign the resulting pointer to.
+ */
+#define TMTIMER_HANDLE_TO_PTR_RETURN(a_pVM, a_hTimer, a_pTimerVar) \
+        TMTIMER_HANDLE_TO_PTR_RETURN_EX(a_pVM, a_hTimer, VERR_INVALID_HANDLE, a_pTimerVar)
+
+/** @def TMTIMER_HANDLE_TO_PTR_RETURN_VOID
+ * Converts a timer handle to a timer pointer, returning VERR_INVALID_HANDLE if
+ * invalid.
+ *
+ * @param   a_pVM       The cross context VM structure.
+ * @param   a_hTimer    The timer handle to translate.
+ * @param   a_pTimerVar The timer variable to assign the resulting pointer to.
+ */
+#ifdef IN_RING3
+# define TMTIMER_HANDLE_TO_PTR_RETURN_VOID(a_pVM, a_hTimer, a_pTimerVar) do { \
+        RT_NOREF(a_pVM); \
+        (a_pTimerVar) = (PTMTIMER)hTimer; \
+        AssertPtrReturnVoid((a_pTimerVar)); \
+        AssertReturnVoid((a_pTimerVar)->hSelf == a_hTimer); \
+    } while (0)
+#else
+# define TMTIMER_HANDLE_TO_PTR_RETURN_VOID(a_pVM, a_hTimer, a_pTimerVar) do { \
+        (a_pTimerVar) = (PTMTIMER)MMHyperR3ToCC(pVM, (RTR3PTR)hTimer); \
+        AssertPtrReturnVoid((a_pTimerVar)); \
+        AssertReturnVoid((a_pTimerVar)->hSelf == a_hTimer); \
+        Assert((a_pTimerVar)->fFlags & TMTIMER_FLAGS_RING0); \
+    } while (0)
+#endif
+
+
 #endif /* !VMM_INCLUDED_SRC_include_TMInline_h */
 
Index: /trunk/src/VBox/VMM/include/TMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/TMInternal.h	(revision 87765)
+++ /trunk/src/VBox/VMM/include/TMInternal.h	(revision 87766)
@@ -174,4 +174,6 @@
     int32_t                 offPrev;
 
+    /** It's own handle value. */
+    TMTIMERHANDLE           hSelf;
     /** Pointer to the VM the timer belongs to - R3 Ptr. */
     PVMR3                   pVMR3;
@@ -200,5 +202,5 @@
     /** TMTIMER_FLAGS_XXX.   */
     uint32_t                fFlags;
-    uint32_t                u32Pading;
+    uint32_t                u32Padding;
 
 #ifdef VBOX_WITH_STATISTICS
Index: /trunk/src/VBox/VMM/include/VMMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/VMMInternal.h	(revision 87765)
+++ /trunk/src/VBox/VMM/include/VMMInternal.h	(revision 87766)
@@ -193,5 +193,5 @@
 
     /** The EMT yield timer. */
-    PTMTIMERR3                  pYieldTimer;
+    TMTIMERHANDLE               hYieldTimer;
     /** The period to the next timeout when suspended or stopped.
      * This is 0 when running. */
