Index: /trunk/include/VBox/vmm/pdmdev.h
===================================================================
--- /trunk/include/VBox/vmm/pdmdev.h	(revision 87759)
+++ /trunk/include/VBox/vmm/pdmdev.h	(revision 87760)
@@ -2351,5 +2351,5 @@
 
 /** Current PDMDEVHLPR3 version number. */
-#define PDM_DEVHLPR3_VERSION                    PDM_VERSION_MAKE_PP(0xffe7, 45, 0)
+#define PDM_DEVHLPR3_VERSION                    PDM_VERSION_MAKE_PP(0xffe7, 46, 0)
 
 /**
@@ -2800,22 +2800,4 @@
 
     /**
-     * Creates a timer.
-     *
-     * @returns VBox status.
-     * @param   pDevIns             The device instance.
-     * @param   enmClock            The clock to use on this timer.
-     * @param   pfnCallback         Callback function.
-     * @param   pvUser              User argument for the callback.
-     * @param   fFlags              Flags, see TMTIMER_FLAGS_*.
-     * @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.
-     * @remarks Caller enters the device critical section prior to invoking the
-     *          callback.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnTMTimerCreate,(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback,
-                                                void *pvUser, uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer));
-
-    /**
      * Creates a timer w/ a cross context handle.
      *
@@ -2834,13 +2816,4 @@
     DECLR3CALLBACKMEMBER(int, pfnTimerCreate,(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback,
                                               void *pvUser, uint32_t fFlags, const char *pszDesc, PTMTIMERHANDLE phTimer));
-
-    /**
-     * Translates a timer handle to a pointer.
-     *
-     * @returns The time address.
-     * @param   pDevIns             The device instance.
-     * @param   hTimer              The timer handle.
-     */
-    DECLR3CALLBACKMEMBER(PTMTIMERR3, pfnTimerToPtr,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
 
     /** @name Timer handle method wrappers
@@ -5225,13 +5198,4 @@
     DECLR0CALLBACKMEMBER(VMCPUID, pfnGetCurrentCpuId,(PPDMDEVINS pDevIns));
 
-    /**
-     * Translates a timer handle to a pointer.
-     *
-     * @returns The time address.
-     * @param   pDevIns             The device instance.
-     * @param   hTimer              The timer handle.
-     */
-    DECLR0CALLBACKMEMBER(PTMTIMERR0, pfnTimerToPtr,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
-
     /** @name Timer handle method wrappers
      * @{ */
@@ -5489,5 +5453,5 @@
 
 /** Current PDMDEVHLP version number. */
-#define PDM_DEVHLPR0_VERSION                    PDM_VERSION_MAKE(0xffe5, 18, 0)
+#define PDM_DEVHLPR0_VERSION                    PDM_VERSION_MAKE(0xffe5, 19, 0)
 
 
@@ -6320,13 +6284,4 @@
 
 /**
- * @copydoc PDMDEVHLPR3::pfnTMTimerCreate
- */
-DECLINLINE(int) PDMDevHlpTMTimerCreate(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, void *pvUser,
-                                       uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer)
-{
-    return pDevIns->pHlpR3->pfnTMTimerCreate(pDevIns, enmClock, pfnCallback, pvUser, fFlags, pszDesc, ppTimer);
-}
-
-/**
  * @copydoc PDMDEVHLPR3::pfnTimerCreate
  */
@@ -6338,12 +6293,4 @@
 
 #endif /* IN_RING3 */
-
-/**
- * @copydoc PDMDEVHLPR3::pfnTimerToPtr
- */
-DECLINLINE(PTMTIMER) PDMDevHlpTimerToPtr(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
-{
-    return pDevIns->CTX_SUFF(pHlp)->pfnTimerToPtr(pDevIns, hTimer);
-}
 
 /**
Index: /trunk/include/VBox/vmm/pdmdrv.h
===================================================================
--- /trunk/include/VBox/vmm/pdmdrv.h	(revision 87759)
+++ /trunk/include/VBox/vmm/pdmdrv.h	(revision 87760)
@@ -1509,5 +1509,6 @@
  * @copydoc PDMDRVHLPR3::pfnTMTimerCreate
  */
-DECLINLINE(int) PDMDrvHlpTMTimerCreate(PPDMDRVINS pDrvIns, TMCLOCK enmClock, PFNTMTIMERDRV pfnCallback, void *pvUser, uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer)
+DECLINLINE(int) PDMDrvHlpTMTimerCreate(PPDMDRVINS pDrvIns, TMCLOCK enmClock, PFNTMTIMERDRV pfnCallback, void *pvUser,
+                                       uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer)
 {
     return pDrvIns->pHlpR3->pfnTMTimerCreate(pDrvIns, enmClock, pfnCallback, pvUser, fFlags, pszDesc, ppTimer);
Index: /trunk/include/VBox/vmm/tm.h
===================================================================
--- /trunk/include/VBox/vmm/tm.h	(revision 87759)
+++ /trunk/include/VBox/vmm/tm.h	(revision 87760)
@@ -82,4 +82,8 @@
  *  TMR3TimerSetCritSect(). */
 #define TMTIMER_FLAGS_NO_CRIT_SECT      RT_BIT_32(0)
+/** Used in ring-0.  Must set this or TMTIMER_FLAGS_NO_RING0. */
+#define TMTIMER_FLAGS_RING0             RT_BIT_32(1)
+/** Not used in ring-0 (for refactoring and doc purposes). */
+#define TMTIMER_FLAGS_NO_RING0          RT_BIT_32(31)
 /** @} */
 
Index: /trunk/src/VBox/Devices/Audio/DevHDA.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevHDA.cpp	(revision 87759)
+++ /trunk/src/VBox/Devices/Audio/DevHDA.cpp	(revision 87760)
@@ -4922,14 +4922,16 @@
      *        instead of the LPIB registers.
      */
+    /** @todo r=bird: The need to use virtual sync is perhaps because TM
+     *        doesn't schedule regular TMCLOCK_VIRTUAL timers as accurately as it
+     *        should (VT-x preemption timer, etc).  Hope to address that before
+     *        long. @bugref{9943}. */
     static const char * const s_apszNames[] =
-    {
-        "HDA SD0", "HDA SD1", "HDA SD2", "HDA SD3",
-        "HDA SD4", "HDA SD5", "HDA SD6", "HDA SD7",
-    };
+    { "HDA SD0", "HDA SD1", "HDA SD2", "HDA SD3", "HDA SD4", "HDA SD5", "HDA SD6", "HDA SD7", };
     AssertCompile(RT_ELEMENTS(s_apszNames) == HDA_MAX_STREAMS);
     for (size_t i = 0; i < HDA_MAX_STREAMS; i++)
     {
         rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, hdaR3Timer, (void *)(uintptr_t)i,
-                                  TMTIMER_FLAGS_NO_CRIT_SECT, s_apszNames[i], &pThis->aStreams[i].hTimer);
+                                  TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_NO_RING0,
+                                  s_apszNames[i], &pThis->aStreams[i].hTimer);
         AssertRCReturn(rc, rc);
 
Index: /trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevIchAc97.cpp	(revision 87759)
+++ /trunk/src/VBox/Devices/Audio/DevIchAc97.cpp	(revision 87760)
@@ -651,4 +651,8 @@
 /**
  * Acquires the TM lock and AC'97 lock, returns on failure.
+ *
+ * @todo r=bird: Isn't this overkill for ring-0, only ring-3 access the timer
+ *               from what I can tell (ichac97R3StreamTransferCalcNext,
+ *               ichac97R3TimerSet, timer callback and state load).
  */
 #define DEVAC97_LOCK_BOTH_RETURN(a_pDevIns, a_pThis, a_pStream, a_rcBusy) \
@@ -4330,4 +4334,8 @@
      *        instead of the LPIB registers.
      */
+    /** @todo r=bird: The need to use virtual sync is perhaps because TM
+     *        doesn't schedule regular TMCLOCK_VIRTUAL timers as accurately as it
+     *        should (VT-x preemption timer, etc).  Hope to address that before
+     *        long. @bugref{9943}. */
     static const char * const s_apszNames[] = { "AC97 PI", "AC97 PO", "AC97 MC" };
     AssertCompile(RT_ELEMENTS(s_apszNames) == AC97_MAX_STREAMS);
@@ -4335,5 +4343,5 @@
     {
         rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, ichac97R3Timer, &pThis->aStreams[i],
-                                  TMTIMER_FLAGS_NO_CRIT_SECT, s_apszNames[i], &pThis->aStreams[i].hTimer);
+                                  TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_RING0, s_apszNames[i], &pThis->aStreams[i].hTimer);
         AssertRCReturn(rc, rc);
 
Index: /trunk/src/VBox/Devices/Audio/DevSB16.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevSB16.cpp	(revision 87759)
+++ /trunk/src/VBox/Devices/Audio/DevSB16.cpp	(revision 87760)
@@ -2430,8 +2430,8 @@
      */
     rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, sb16TimerIRQ, pThis,
-                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "SB16 IRQ timer", &pThis->hTimerIRQ);
+                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT | TMTIMER_FLAGS_NO_RING0, "SB16 IRQ timer", &pThis->hTimerIRQ);
     AssertRCReturn(rc, rc);
     rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, sb16TimerIO, pThis,
-                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "SB16 IO timer", &pThis->hTimerIO);
+                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT | TMTIMER_FLAGS_NO_RING0, "SB16 IO timer", &pThis->hTimerIO);
     AssertRCReturn(rc, rc);
     pThis->cTicksTimerIOInterval = PDMDevHlpTimerGetFreq(pDevIns, pThis->hTimerIO) / uTimerHz;
Index: /trunk/src/VBox/Devices/Graphics/DevVGA.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA.cpp	(revision 87759)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA.cpp	(revision 87760)
@@ -5445,5 +5445,5 @@
  * @callback_method_impl{FNTMTIMERDEV, VGA Refresh Timer}
  */
-static DECLCALLBACK(void) vgaTimerRefresh(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
+static DECLCALLBACK(void) vgaR3TimerRefresh(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
 {
     PVGASTATE   pThis   = PDMDEVINS_2_DATA(pDevIns, PVGASTATE);
@@ -6783,6 +6783,6 @@
      * Create the refresh timer.
      */
-    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_REAL, vgaTimerRefresh, NULL, TMTIMER_FLAGS_NO_CRIT_SECT,
-                              "VGA Refresh Timer", &pThis->hRefreshTimer);
+    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_REAL, vgaR3TimerRefresh, NULL,
+                              TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_NO_RING0, "VGA Refresh Timer", &pThis->hRefreshTimer);
     AssertRCReturn(rc, rc);
 
Index: /trunk/src/VBox/Devices/Input/DevPS2K.cpp
===================================================================
--- /trunk/src/VBox/Devices/Input/DevPS2K.cpp	(revision 87759)
+++ /trunk/src/VBox/Devices/Input/DevPS2K.cpp	(revision 87760)
@@ -1401,5 +1401,6 @@
      */
     rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, ps2kR3ThrottleTimer, pThis,
-                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "PS2K Throttle Timer", &pThis->hThrottleTimer);
+                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT | TMTIMER_FLAGS_RING0,
+                              "PS2K Throttle Timer", &pThis->hThrottleTimer);
     AssertRCReturn(rc, rc);
 
@@ -1408,5 +1409,6 @@
      */
     rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, ps2kR3TypematicTimer, pThis,
-                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "PS2K Typematic Timer", &pThis->hKbdTypematicTimer);
+                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT | TMTIMER_FLAGS_RING0,
+                              "PS2K Typematic Timer", &pThis->hKbdTypematicTimer);
     AssertRCReturn(rc, rc);
 
@@ -1415,5 +1417,5 @@
      */
     rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, ps2kR3DelayTimer, pThis,
-                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "PS2K Delay Timer", &pThis->hKbdDelayTimer);
+                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT | TMTIMER_FLAGS_RING0, "PS2K Delay Timer", &pThis->hKbdDelayTimer);
     AssertRCReturn(rc, rc);
 
Index: /trunk/src/VBox/Devices/Input/DevPS2M.cpp
===================================================================
--- /trunk/src/VBox/Devices/Input/DevPS2M.cpp	(revision 87759)
+++ /trunk/src/VBox/Devices/Input/DevPS2M.cpp	(revision 87760)
@@ -1085,5 +1085,6 @@
      */
     int rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_REAL, ps2mR3ThrottleTimer, pThis,
-                                  TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "PS2M Throttle Timer", &pThis->hThrottleTimer);
+                                  TMTIMER_FLAGS_DEFAULT_CRIT_SECT | TMTIMER_FLAGS_NO_RING0,
+                                  "PS2M Throttle Timer", &pThis->hThrottleTimer);
     AssertRCReturn(rc, rc);
 
@@ -1092,5 +1093,5 @@
      */
     rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, ps2mR3DelayTimer, pThis,
-                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "PS2M Delay Timer", &pThis->hDelayTimer);
+                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT | TMTIMER_FLAGS_RING0, "PS2M Delay Timer", &pThis->hDelayTimer);
     AssertRCReturn(rc, rc);
 
Index: /trunk/src/VBox/Devices/Network/DevE1000.cpp
===================================================================
--- /trunk/src/VBox/Devices/Network/DevE1000.cpp	(revision 87759)
+++ /trunk/src/VBox/Devices/Network/DevE1000.cpp	(revision 87760)
@@ -8074,5 +8074,6 @@
 #ifdef E1K_TX_DELAY
     /* Create Transmit Delay Timer */
-    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kR3TxDelayTimer, pThis, TMTIMER_FLAGS_NO_CRIT_SECT,
+    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kR3TxDelayTimer, pThis,
+                              TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_RING0,
                               "E1000 Transmit Delay Timer", &pThis->hTXDTimer);
     AssertRCReturn(rc, rc);
@@ -8085,5 +8086,6 @@
     {
         /* Create Transmit Interrupt Delay Timer */
-        rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kR3TxIntDelayTimer, pThis, TMTIMER_FLAGS_NO_CRIT_SECT,
+        rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kR3TxIntDelayTimer, pThis,
+                                  TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_RING0,
                                   "E1000 Transmit Interrupt Delay Timer", &pThis->hTIDTimer);
         AssertRCReturn(rc, rc);
@@ -8091,5 +8093,6 @@
 # ifndef E1K_NO_TAD
         /* Create Transmit Absolute Delay Timer */
-        rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kR3TxAbsDelayTimer, pThis, TMTIMER_FLAGS_NO_CRIT_SECT,
+        rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kR3TxAbsDelayTimer, pThis,
+                                  TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_RING0,
                                   "E1000 Transmit Absolute Delay Timer", &pThis->hTADTimer);
         AssertRCReturn(rc, rc);
@@ -8100,10 +8103,12 @@
 #ifdef E1K_USE_RX_TIMERS
     /* Create Receive Interrupt Delay Timer */
-    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kR3RxIntDelayTimer, pThis, TMTIMER_FLAGS_NO_CRIT_SECT,
+    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kR3RxIntDelayTimer, pThis,
+                              TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_RING0,
                               "E1000 Receive Interrupt Delay Timer", &pThis->hRIDTimer);
     AssertRCReturn(rc, rc);
 
     /* Create Receive Absolute Delay Timer */
-    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kR3RxAbsDelayTimer, pThis, TMTIMER_FLAGS_NO_CRIT_SECT,
+    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kR3RxAbsDelayTimer, pThis,
+                              TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_RING0,
                               "E1000 Receive Absolute Delay Timer", &pThis->hRADTimer);
     AssertRCReturn(rc, rc);
@@ -8111,10 +8116,12 @@
 
     /* Create Late Interrupt Timer */
-    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kR3LateIntTimer, pThis, TMTIMER_FLAGS_NO_CRIT_SECT,
+    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kR3LateIntTimer, pThis,
+                              TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_RING0,
                               "E1000 Late Interrupt Timer", &pThis->hIntTimer);
     AssertRCReturn(rc, rc);
 
     /* Create Link Up Timer */
-    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kR3LinkUpTimer, pThis, TMTIMER_FLAGS_NO_CRIT_SECT,
+    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kR3LinkUpTimer, pThis,
+                              TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_RING0,
                               "E1000 Link Up Timer", &pThis->hLUTimer);
     AssertRCReturn(rc, rc);
Index: /trunk/src/VBox/Devices/Network/DevPCNet.cpp
===================================================================
--- /trunk/src/VBox/Devices/Network/DevPCNet.cpp	(revision 87759)
+++ /trunk/src/VBox/Devices/Network/DevPCNet.cpp	(revision 87760)
@@ -5328,5 +5328,5 @@
 
 #else
-    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, pcnetR3Timer, NULL, TMTIMER_FLAGS_NO_CRIT_SECT,
+    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, pcnetR3Timer, NULL, TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_RING0,
                               "PCnet Poll Timer", &pThis->hTimerPoll);
     AssertRCReturn(rc, rc);
@@ -5337,12 +5337,12 @@
     {
         /* Software Interrupt timer */
-        rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, pcnetR3TimerSoftInt, NULL, TMTIMER_FLAGS_NO_CRIT_SECT,
-                                  "PCnet SoftInt Timer", &pThis->hTimerSoftInt);
+        rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, pcnetR3TimerSoftInt, NULL,
+                                  TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_RING0, "PCnet SoftInt Timer", &pThis->hTimerSoftInt);
         AssertRCReturn(rc, rc);
         rc = PDMDevHlpTimerSetCritSect(pDevIns, pThis->hTimerSoftInt, &pThis->CritSect);
         AssertRCReturn(rc, rc);
     }
-    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, pcnetR3TimerRestore, pThis, TMTIMER_FLAGS_NO_CRIT_SECT,
-                              "PCnet Restore Timer", &pThis->hTimerRestore);
+    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, pcnetR3TimerRestore, pThis,
+                              TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_NO_RING0, "PCnet Restore Timer", &pThis->hTimerRestore);
     AssertRCReturn(rc, rc);
 
Index: /trunk/src/VBox/Devices/Network/DevVirtioNet.cpp
===================================================================
--- /trunk/src/VBox/Devices/Network/DevVirtioNet.cpp	(revision 87759)
+++ /trunk/src/VBox/Devices/Network/DevVirtioNet.cpp	(revision 87760)
@@ -2248,5 +2248,6 @@
 
     /* Create Link Up Timer */
-    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, vnetR3LinkUpTimer, NULL, TMTIMER_FLAGS_NO_CRIT_SECT,
+    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, vnetR3LinkUpTimer, NULL,
+                              TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_NO_RING0,
                               "VirtioNet Link Up Timer", &pThisCC->hLinkUpTimer);
     AssertRCReturn(rc, rc);
@@ -2254,5 +2255,6 @@
 # ifdef VNET_TX_DELAY
     /* Create Transmit Delay Timer */
-    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, vnetR3TxTimer, pThis, TMTIMER_FLAGS_NO_CRIT_SECT,
+    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, vnetR3TxTimer, pThis,
+                              TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_NO_RING0,
                               "VirtioNet TX Delay Timer", &pThis->hTxTimer);
     AssertRCReturn(rc, rc);
Index: /trunk/src/VBox/Devices/Network/DevVirtioNet_1_0.cpp
===================================================================
--- /trunk/src/VBox/Devices/Network/DevVirtioNet_1_0.cpp	(revision 87759)
+++ /trunk/src/VBox/Devices/Network/DevVirtioNet_1_0.cpp	(revision 87760)
@@ -3036,5 +3036,6 @@
 
     /* Create Link Up Timer */
-    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, virtioNetR3LinkUpTimer, NULL, TMTIMER_FLAGS_NO_CRIT_SECT,
+    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, virtioNetR3LinkUpTimer, NULL,
+                              TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_NO_RING0,
                               "VirtioNet Link Up Timer", &pThisCC->hLinkUpTimer);
 
Index: /trunk/src/VBox/Devices/PC/DevACPI.cpp
===================================================================
--- /trunk/src/VBox/Devices/PC/DevACPI.cpp	(revision 87759)
+++ /trunk/src/VBox/Devices/PC/DevACPI.cpp	(revision 87760)
@@ -4388,5 +4388,5 @@
      */
     rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, acpiR3PmTimer, NULL /*pvUser*/,
-                              TMTIMER_FLAGS_NO_CRIT_SECT, "ACPI PM Timer", &pThis->hPmTimer);
+                              TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_RING0, "ACPI PM Timer", &pThis->hPmTimer);
     AssertRCReturn(rc, rc);
 
Index: /trunk/src/VBox/Devices/PC/DevHPET.cpp
===================================================================
--- /trunk/src/VBox/Devices/PC/DevHPET.cpp	(revision 87759)
+++ /trunk/src/VBox/Devices/PC/DevHPET.cpp	(revision 87760)
@@ -1465,5 +1465,6 @@
 
         rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, hpetR3Timer, pHpetTimer,
-                                  TMTIMER_FLAGS_NO_CRIT_SECT, s_apszTimerNames[i], &pThis->aTimers[i].hTimer);
+                                  TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_RING0,
+                                  s_apszTimerNames[i], &pThis->aTimers[i].hTimer);
         AssertRCReturn(rc, rc);
         /** @todo r=bird: This is TOTALLY MESSED UP!  Why do we need
Index: /trunk/src/VBox/Devices/PC/DevPit-i8254.cpp
===================================================================
--- /trunk/src/VBox/Devices/PC/DevPit-i8254.cpp	(revision 87759)
+++ /trunk/src/VBox/Devices/PC/DevPit-i8254.cpp	(revision 87760)
@@ -1424,5 +1424,6 @@
      */
     rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, pitR3Timer, &pThis->channels[0],
-                              TMTIMER_FLAGS_NO_CRIT_SECT, "i8254 Programmable Interval Timer", &pThis->channels[0].hTimer);
+                              TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_RING0,
+                              "i8254 Programmable Interval Timer", &pThis->channels[0].hTimer);
     AssertRCReturn(rc, rc);
     rc = PDMDevHlpTimerSetCritSect(pDevIns, pThis->channels[0].hTimer, &pThis->CritSect);
Index: /trunk/src/VBox/Devices/PC/DevRTC.cpp
===================================================================
--- /trunk/src/VBox/Devices/PC/DevRTC.cpp	(revision 87759)
+++ /trunk/src/VBox/Devices/PC/DevRTC.cpp	(revision 87760)
@@ -588,5 +588,4 @@
     RT_NOREF2(pTimer, pvUser);
     PRTCSTATE pThis = PDMDEVINS_2_DATA(pDevIns, PRTCSTATE);
-    Assert(pTimer == PDMDevHlpTimerToPtr(pDevIns, pThis->hPeriodicTimer));
     Assert(PDMDevHlpTimerIsLockOwner(pDevIns, pThis->hPeriodicTimer));
     Assert(PDMDevHlpCritSectIsOwner(pDevIns, pDevIns->CTX_SUFF(pCritSectRo)));
@@ -667,5 +666,5 @@
  * @callback_method_impl{FNTMTIMERDEV, Second timer.}
  */
-static DECLCALLBACK(void) rtcTimerSecond(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
+static DECLCALLBACK(void) rtcR3TimerSecond(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
 {
     PRTCSTATE pThis = PDMDEVINS_2_DATA(pDevIns, PRTCSTATE);
@@ -673,5 +672,4 @@
     Assert(PDMDevHlpTimerIsLockOwner(pDevIns, pThis->hPeriodicTimer));
     Assert(PDMDevHlpCritSectIsOwner(pDevIns, pDevIns->CTX_SUFF(pCritSectRo)));
-    Assert(pTimer == PDMDevHlpTimerToPtr(pDevIns, pThis->hSecondTimer));
     RT_NOREF(pvUser, pTimer);
 
@@ -700,5 +698,5 @@
 
 
-/* Used by rtc_set_date and rtcTimerSecond2. */
+/* Used by rtc_set_date and rtcR3TimerSecond2. */
 static void rtc_copy_date(PRTCSTATE pThis)
 {
@@ -730,5 +728,5 @@
  * @callback_method_impl{FNTMTIMERDEV, Second2 timer.}
  */
-static DECLCALLBACK(void) rtcTimerSecond2(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
+static DECLCALLBACK(void) rtcR3TimerSecond2(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
 {
     PRTCSTATE pThis = PDMDEVINS_2_DATA(pDevIns, PRTCSTATE);
@@ -736,5 +734,4 @@
     Assert(PDMDevHlpTimerIsLockOwner(pDevIns, pThis->hPeriodicTimer));
     Assert(PDMDevHlpCritSectIsOwner(pDevIns, pDevIns->CTX_SUFF(pCritSectRo)));
-    Assert(pTimer == PDMDevHlpTimerToPtr(pDevIns, pThis->hSecondTimer2));
     RT_NOREF2(pTimer, pvUser);
 
@@ -1159,15 +1156,18 @@
     /* Periodic timer. */
     rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, rtcTimerPeriodic, pThis,
-                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "MC146818 RTC (CMOS) - Periodic", &pThis->hPeriodicTimer);
+                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT | TMTIMER_FLAGS_RING0,
+                              "MC146818 RTC (CMOS) - Periodic", &pThis->hPeriodicTimer);
     AssertRCReturn(rc, rc);
 
     /* Seconds timer. */
-    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, rtcTimerSecond, pThis,
-                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "MC146818 RTC (CMOS) - Second", &pThis->hSecondTimer);
+    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, rtcR3TimerSecond, pThis,
+                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT | TMTIMER_FLAGS_RING0,
+                              "MC146818 RTC (CMOS) - Second", &pThis->hSecondTimer);
     AssertRCReturn(rc, rc);
 
     /* The second2 timer, this is always active. */
-    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, rtcTimerSecond2, pThis,
-                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "MC146818 RTC (CMOS) - Second2", &pThis->hSecondTimer2);
+    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, rtcR3TimerSecond2, pThis,
+                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT | TMTIMER_FLAGS_NO_RING0,
+                              "MC146818 RTC (CMOS) - Second2", &pThis->hSecondTimer2);
     AssertRCReturn(rc, rc);
 
Index: /trunk/src/VBox/Devices/Serial/UartCore.cpp
===================================================================
--- /trunk/src/VBox/Devices/Serial/UartCore.cpp	(revision 87759)
+++ /trunk/src/VBox/Devices/Serial/UartCore.cpp	(revision 87760)
@@ -2070,5 +2070,5 @@
      */
     rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, uartR3RcvFifoTimeoutTimer, pThisCC,
-                              TMTIMER_FLAGS_NO_CRIT_SECT, "UART Rcv FIFO Timer",
+                              TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_RING0, "UART Rcv FIFO Timer",
                               &pThis->hTimerRcvFifoTimeout);
     AssertRCReturn(rc, rc);
@@ -2081,5 +2081,5 @@
      */
     rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, uartR3TxUnconnectedTimer, pThisCC,
-                              TMTIMER_FLAGS_NO_CRIT_SECT, "UART TX uncon. Timer",
+                              TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_NO_RING0, "UART TX uncon. Timer",
                               &pThis->hTimerTxUnconnected);
     AssertRCReturn(rc, rc);
Index: /trunk/src/VBox/Devices/Storage/DevAHCI.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/DevAHCI.cpp	(revision 87759)
+++ /trunk/src/VBox/Devices/Storage/DevAHCI.cpp	(revision 87760)
@@ -5937,5 +5937,5 @@
      */
     rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, ahciCccTimer, pThis,
-                              TMTIMER_FLAGS_NO_CRIT_SECT, "AHCI CCC Timer", &pThis->hHbaCccTimer);
+                              TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_RING0, "AHCI CCC Timer", &pThis->hHbaCccTimer);
     AssertRCReturn(rc, rc);
 
Index: /trunk/src/VBox/Devices/Storage/DevFdc.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/DevFdc.cpp	(revision 87759)
+++ /trunk/src/VBox/Devices/Storage/DevFdc.cpp	(revision 87760)
@@ -2924,5 +2924,6 @@
      */
     rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, fdcTimerCallback, pThis,
-                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "FDC Timer", &pThis->hResultTimer);
+                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT | TMTIMER_FLAGS_NO_RING0,
+                              "FDC Timer", &pThis->hResultTimer);
     AssertRCReturn(rc, rc);
 
@@ -2931,5 +2932,6 @@
      */
     rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, fdcTransferDelayTimer, pThis,
-                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "FDC Transfer Delay Timer", &pThis->hXferDelayTimer);
+                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT | TMTIMER_FLAGS_NO_RING0,
+                              "FDC Transfer Delay Timer", &pThis->hXferDelayTimer);
     AssertRCReturn(rc, rc);
 
@@ -2938,5 +2940,6 @@
      */
     rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, fdcIrqDelayTimer, pThis,
-                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "FDC IRQ Delay Timer", &pThis->hIrqDelayTimer);
+                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT | TMTIMER_FLAGS_NO_RING0,
+                              "FDC IRQ Delay Timer", &pThis->hIrqDelayTimer);
     AssertRCReturn(rc, rc);
 
Index: /trunk/src/VBox/Devices/USB/DevOHCI.cpp
===================================================================
--- /trunk/src/VBox/Devices/USB/DevOHCI.cpp	(revision 87759)
+++ /trunk/src/VBox/Devices/USB/DevOHCI.cpp	(revision 87760)
@@ -5822,5 +5822,6 @@
     {
         int rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, ohciR3LoadReattachDevices, NULL /*pvUser*/,
-                                      TMTIMER_FLAGS_NO_CRIT_SECT, "OHCI reattach devices on load", &pThisCC->pLoad->hTimer);
+                                      TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_NO_RING0, "OHCI reattach devices on load",
+                                      &pThisCC->pLoad->hTimer);
         if (RT_SUCCESS(rc))
             rc = PDMDevHlpTimerSetMillies(pDevIns, pThisCC->pLoad->hTimer, 250);
Index: /trunk/src/VBox/Devices/VMMDev/VMMDev.cpp
===================================================================
--- /trunk/src/VBox/Devices/VMMDev/VMMDev.cpp	(revision 87759)
+++ /trunk/src/VBox/Devices/VMMDev/VMMDev.cpp	(revision 87760)
@@ -4792,5 +4792,5 @@
      */
     rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, vmmDevHeartbeatFlatlinedTimer, pThis,
-                              TMTIMER_FLAGS_NO_CRIT_SECT, "Heartbeat flatlined", &pThis->hFlatlinedTimer);
+                              TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_RING0, "Heartbeat flatlined", &pThis->hFlatlinedTimer);
     AssertRCReturn(rc, rc);
 
Index: /trunk/src/VBox/ExtPacks/BusMouseSample/DevBusMouse.cpp
===================================================================
--- /trunk/src/VBox/ExtPacks/BusMouseSample/DevBusMouse.cpp	(revision 87759)
+++ /trunk/src/VBox/ExtPacks/BusMouseSample/DevBusMouse.cpp	(revision 87760)
@@ -716,5 +716,5 @@
      */
     rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, bmsR3TimerCallback, pThis,
-                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "Bus Mouse Timer", &pThis->hMouseTimer);
+                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT | TMTIMER_FLAGS_NO_RING0, "Bus Mouse Timer", &pThis->hMouseTimer);
     AssertRCReturn(rc, rc);
 
Index: /trunk/src/VBox/VMM/VMMAll/TMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/TMAll.cpp	(revision 87759)
+++ /trunk/src/VBox/VMM/VMMAll/TMAll.cpp	(revision 87760)
@@ -1109,4 +1109,7 @@
 VMMDECL(PTMTIMERR3) TMTimerR3Ptr(PTMTIMER pTimer)
 {
+#ifdef IN_RING0
+    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
+#endif
     return (PTMTIMERR3)MMHyperCCToR3(pTimer->CTX_SUFF(pVM), pTimer);
 }
@@ -1121,4 +1124,7 @@
 VMMDECL(PTMTIMERR0) TMTimerR0Ptr(PTMTIMER pTimer)
 {
+#ifdef IN_RING0
+    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
+#endif
     return (PTMTIMERR0)MMHyperCCToR0(pTimer->CTX_SUFF(pVM), pTimer);
 }
@@ -1133,4 +1139,7 @@
 VMMDECL(PTMTIMERRC) TMTimerRCPtr(PTMTIMER pTimer)
 {
+#ifdef IN_RING0
+    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
+#endif
     return (PTMTIMERRC)MMHyperCCToRC(pTimer->CTX_SUFF(pVM), pTimer);
 }
@@ -1152,4 +1161,7 @@
 VMMDECL(int) TMTimerLock(PTMTIMER pTimer, int rcBusy)
 {
+#ifdef IN_RING0
+    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
+#endif
     AssertPtr(pTimer);
     AssertReturn(pTimer->enmClock == TMCLOCK_VIRTUAL_SYNC, VERR_NOT_SUPPORTED);
@@ -1165,4 +1177,7 @@
 VMMDECL(void) TMTimerUnlock(PTMTIMER pTimer)
 {
+#ifdef IN_RING0
+    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
+#endif
     AssertPtr(pTimer);
     AssertReturnVoid(pTimer->enmClock == TMCLOCK_VIRTUAL_SYNC);
@@ -1179,4 +1194,7 @@
 VMMDECL(bool) TMTimerIsLockOwner(PTMTIMER pTimer)
 {
+#ifdef IN_RING0
+    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
+#endif
     AssertPtr(pTimer);
     AssertReturn(pTimer->enmClock == TMCLOCK_VIRTUAL_SYNC, false);
@@ -1306,4 +1324,7 @@
 VMMDECL(int) TMTimerSet(PTMTIMER pTimer, uint64_t u64Expire)
 {
+#ifdef IN_RING0
+    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
+#endif
     PVMCC pVM = pTimer->CTX_SUFF(pVM);
     STAM_COUNTER_INC(&pTimer->StatSetAbsolute);
@@ -1613,4 +1634,7 @@
 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);
     STAM_COUNTER_INC(&pTimer->StatSetRelative);
@@ -1841,4 +1865,7 @@
 VMMDECL(int) TMTimerSetFrequencyHint(PTMTIMER pTimer, uint32_t uHzHint)
 {
+#ifdef IN_RING0
+    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
+#endif
     TMTIMER_ASSERT_CRITSECT(pTimer);
 
@@ -1936,4 +1963,7 @@
 VMMDECL(int) TMTimerStop(PTMTIMER pTimer)
 {
+#ifdef IN_RING0
+    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
+#endif
     PVMCC pVM = pTimer->CTX_SUFF(pVM);
     STAM_COUNTER_INC(&pTimer->StatStop);
@@ -2044,4 +2074,7 @@
 VMMDECL(uint64_t) TMTimerGet(PTMTIMER pTimer)
 {
+#ifdef IN_RING0
+    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
+#endif
     PVMCC pVM = pTimer->CTX_SUFF(pVM);
     STAM_COUNTER_INC(&pTimer->StatGet);
@@ -2077,4 +2110,7 @@
 VMMDECL(uint64_t) TMTimerGetFreq(PTMTIMER pTimer)
 {
+#ifdef IN_RING0
+    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
+#endif
     switch (pTimer->enmClock)
     {
@@ -2102,4 +2138,7 @@
 VMMDECL(uint64_t) TMTimerGetExpire(PTMTIMER pTimer)
 {
+#ifdef IN_RING0
+    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
+#endif
     TMTIMER_ASSERT_CRITSECT(pTimer);
     int cRetries = 1000;
@@ -2164,4 +2203,7 @@
 VMMDECL(bool) TMTimerIsActive(PTMTIMER pTimer)
 {
+#ifdef IN_RING0
+    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
+#endif
     TMTIMERSTATE enmState = pTimer->enmState;
     switch (enmState)
@@ -2341,4 +2383,7 @@
 VMMDECL(uint64_t) TMTimerToNano(PTMTIMER pTimer, uint64_t u64Ticks)
 {
+#ifdef IN_RING0
+    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
+#endif
     switch (pTimer->enmClock)
     {
@@ -2370,4 +2415,7 @@
 VMMDECL(uint64_t) TMTimerToMicro(PTMTIMER pTimer, uint64_t u64Ticks)
 {
+#ifdef IN_RING0
+    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
+#endif
     switch (pTimer->enmClock)
     {
@@ -2399,4 +2447,7 @@
 VMMDECL(uint64_t) TMTimerToMilli(PTMTIMER pTimer, uint64_t u64Ticks)
 {
+#ifdef IN_RING0
+    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
+#endif
     switch (pTimer->enmClock)
     {
@@ -2427,4 +2478,7 @@
 VMMDECL(uint64_t) TMTimerFromNano(PTMTIMER pTimer, uint64_t cNanoSecs)
 {
+#ifdef IN_RING0
+    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
+#endif
     switch (pTimer->enmClock)
     {
@@ -2455,4 +2509,7 @@
 VMMDECL(uint64_t) TMTimerFromMicro(PTMTIMER pTimer, uint64_t cMicroSecs)
 {
+#ifdef IN_RING0
+    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
+#endif
     switch (pTimer->enmClock)
     {
@@ -2483,4 +2540,7 @@
 VMMDECL(uint64_t) TMTimerFromMilli(PTMTIMER pTimer, uint64_t cMilliSecs)
 {
+#ifdef IN_RING0
+    Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0);
+#endif
     switch (pTimer->enmClock)
     {
Index: /trunk/src/VBox/VMM/VMMR0/PDMR0DevHlp.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/PDMR0DevHlp.cpp	(revision 87759)
+++ /trunk/src/VBox/VMM/VMMR0/PDMR0DevHlp.cpp	(revision 87760)
@@ -415,9 +415,9 @@
 
 
-/** @interface_method_impl{PDMDEVHLPR0,pfnTimerToPtr} */
-static DECLCALLBACK(PTMTIMERR0) pdmR0DevHlp_TimerToPtr(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    RT_NOREF(pDevIns);
+/** 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);
 }
@@ -1249,5 +1249,4 @@
     pdmR0DevHlp_GetVMCPU,
     pdmR0DevHlp_GetCurrentCpuId,
-    pdmR0DevHlp_TimerToPtr,
     pdmR0DevHlp_TimerFromMicro,
     pdmR0DevHlp_TimerFromMilli,
@@ -1347,5 +1346,4 @@
     pdmR0DevHlp_GetVMCPU,
     pdmR0DevHlp_GetCurrentCpuId,
-    pdmR0DevHlp_TimerToPtr,
     pdmR0DevHlp_TimerFromMicro,
     pdmR0DevHlp_TimerFromMilli,
Index: /trunk/src/VBox/VMM/VMMR3/APIC.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/APIC.cpp	(revision 87759)
+++ /trunk/src/VBox/VMM/VMMR3/APIC.cpp	(revision 87760)
@@ -1502,6 +1502,6 @@
         PAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);
         RTStrPrintf(&pApicCpu->szTimerDesc[0], sizeof(pApicCpu->szTimerDesc), "APIC Timer %u", pVCpu->idCpu);
-        rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, apicR3TimerCallback, pVCpu, TMTIMER_FLAGS_NO_CRIT_SECT,
-                                  pApicCpu->szTimerDesc, &pApicCpu->hTimer);
+        rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, apicR3TimerCallback, pVCpu,
+                                  TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_RING0, pApicCpu->szTimerDesc, &pApicCpu->hTimer);
         AssertRCReturn(rc, rc);
     }
Index: /trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp	(revision 87759)
+++ /trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp	(revision 87760)
@@ -412,12 +412,13 @@
 
 
-/** @interface_method_impl{PDMDEVHLPR3,pfnTMTimerCreate} */
-static DECLCALLBACK(int) pdmR3DevHlp_TMTimerCreate(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, void *pvUser, uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer)
+/** @interface_method_impl{PDMDEVHLPR3,pfnTimerCreate} */
+static DECLCALLBACK(int) pdmR3DevHlp_TimerCreate(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback,
+                                                 void *pvUser, uint32_t fFlags, const char *pszDesc, PTMTIMERHANDLE phTimer)
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
     PVM pVM = pDevIns->Internal.s.pVMR3;
     VM_ASSERT_EMT(pVM);
-    LogFlow(("pdmR3DevHlp_TMTimerCreate: caller='%s'/%d: enmClock=%d pfnCallback=%p pvUser=%p fFlags=%#x pszDesc=%p:{%s} ppTimer=%p\n",
-             pDevIns->pReg->szName, pDevIns->iInstance, enmClock, pfnCallback, pvUser, fFlags, pszDesc, pszDesc, ppTimer));
+    LogFlow(("pdmR3DevHlp_TimerCreate: caller='%s'/%d: enmClock=%d pfnCallback=%p pvUser=%p fFlags=%#x pszDesc=%p:{%s} phTimer=%p\n",
+             pDevIns->pReg->szName, pDevIns->iInstance, enmClock, pfnCallback, pvUser, fFlags, pszDesc, pszDesc, phTimer));
 
     if (pDevIns->iInstance > 0) /** @todo use a string cache here later. */
@@ -428,28 +429,13 @@
     }
 
-    int rc = TMR3TimerCreateDevice(pVM, pDevIns, enmClock, pfnCallback, pvUser, fFlags, pszDesc, ppTimer);
-
-    LogFlow(("pdmR3DevHlp_TMTimerCreate: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
-    return rc;
-}
-
-
-
-/** @interface_method_impl{PDMDEVHLPR3,pfnTimerCreate} */
-static DECLCALLBACK(int) pdmR3DevHlp_TimerCreate(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback,
-                                                 void *pvUser, uint32_t fFlags, const char *pszDesc, PTMTIMERHANDLE phTimer)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    PVM pVM = pDevIns->Internal.s.pVMR3;
-    VM_ASSERT_EMT(pVM);
-    LogFlow(("pdmR3DevHlp_TimerCreate: caller='%s'/%d: enmClock=%d pfnCallback=%p pvUser=%p fFlags=%#x pszDesc=%p:{%s} phTimer=%p\n",
-             pDevIns->pReg->szName, pDevIns->iInstance, enmClock, pfnCallback, pvUser, fFlags, pszDesc, pszDesc, phTimer));
-
-    if (pDevIns->iInstance > 0) /** @todo use a string cache here later. */
-    {
-         char *pszDesc2 = MMR3HeapAPrintf(pVM, MM_TAG_PDM_DEVICE_DESC, "%s[%u]", pszDesc, pDevIns->iInstance);
-         if (pszDesc2)
-             pszDesc = pszDesc2;
-    }
+    /* Clear the ring-0 flag if the device isn't configured for ring-0. */
+    if (fFlags & TMTIMER_FLAGS_RING0)
+    {
+        Assert(pDevIns->Internal.s.pDevR3->pReg->fFlags & PDM_DEVREG_FLAGS_R0);
+        if (!(pDevIns->Internal.s.fIntFlags & PDMDEVINSINT_FLAGS_R0_ENABLED))
+            fFlags &= ~TMTIMER_FLAGS_RING0;
+    }
+    else
+        Assert(fFlags & TMTIMER_FLAGS_NO_RING0 /* just to make sure all devices has been considered */);
 
     PTMTIMER pTimer = NULL;
@@ -462,6 +448,6 @@
 
 
-/** @interface_method_impl{PDMDEVHLPR3,pfnTimerToPtr} */
-static DECLCALLBACK(PTMTIMERR3) pdmR3DevHlp_TimerToPtr(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
+/** Converts timer handle to pointer (used to exposed, will be replace soon.) */
+DECLINLINE(PTMTIMERR3) pdmR3DevHlp_TimerToPtr(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
@@ -4189,7 +4175,5 @@
     SSMR3HandleVersion,
     SSMR3HandleHostOSAndArch,
-    pdmR3DevHlp_TMTimerCreate,
     pdmR3DevHlp_TimerCreate,
-    pdmR3DevHlp_TimerToPtr,
     pdmR3DevHlp_TimerFromMicro,
     pdmR3DevHlp_TimerFromMilli,
@@ -4538,7 +4522,5 @@
     SSMR3HandleVersion,
     SSMR3HandleHostOSAndArch,
-    pdmR3DevHlp_TMTimerCreate,
     pdmR3DevHlp_TimerCreate,
-    pdmR3DevHlp_TimerToPtr,
     pdmR3DevHlp_TimerFromMicro,
     pdmR3DevHlp_TimerFromMilli,
@@ -4776,5 +4758,5 @@
     PDM_DEVHLPR3_VERSION /* the end */
 };
-#endif
+#endif /* VBOX_WITH_DBGF_TRACING */
 
 
@@ -5044,7 +5026,5 @@
     SSMR3HandleVersion,
     SSMR3HandleHostOSAndArch,
-    pdmR3DevHlp_TMTimerCreate,
     pdmR3DevHlp_TimerCreate,
-    pdmR3DevHlp_TimerToPtr,
     pdmR3DevHlp_TimerFromMicro,
     pdmR3DevHlp_TimerFromMilli,
Index: /trunk/src/VBox/VMM/VMMR3/PDMDriver.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMDriver.cpp	(revision 87759)
+++ /trunk/src/VBox/VMM/VMMR3/PDMDriver.cpp	(revision 87760)
@@ -1324,4 +1324,12 @@
     LogFlow(("pdmR3DrvHlp_TMTimerCreate: caller='%s'/%d: enmClock=%d pfnCallback=%p pvUser=%p fFlags=%#x pszDesc=%p:{%s} ppTimer=%p\n",
              pDrvIns->pReg->szName, pDrvIns->iInstance, enmClock, pfnCallback, pvUser, fFlags, pszDesc, pszDesc, ppTimer));
+
+    /* Clear the ring-0 flag if the driver isn't configured for ring-0. */
+    if (fFlags & TMTIMER_FLAGS_RING0)
+    {
+        Assert(pDrvIns->Internal.s.pDrv->pReg->fFlags & PDM_DRVREG_FLAGS_R0);
+        /** @todo if (!(pDrvIns->Internal.s.fIntFlags & PDMDRVINSINT_FLAGS_R0_ENABLED))   */
+            fFlags &= ~TMTIMER_FLAGS_RING0;
+    }
 
     int rc = TMR3TimerCreateDriver(pDrvIns->Internal.s.pVMR3, pDrvIns, enmClock, pfnCallback, pvUser, fFlags, pszDesc, ppTimer);
Index: /trunk/src/VBox/VMM/VMMR3/PDMUsb.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMUsb.cpp	(revision 87759)
+++ /trunk/src/VBox/VMM/VMMR3/PDMUsb.cpp	(revision 87760)
@@ -1829,4 +1829,6 @@
     if (pszDesc2)
         pszDesc = pszDesc2;
+
+    AssertStmt(!(fFlags & TMTIMER_FLAGS_RING0), fFlags &= ~TMTIMER_FLAGS_RING0);
 
     int rc = TMR3TimerCreateUsb(pVM, pUsbIns, enmClock, pfnCallback, pvUser, fFlags, pszDesc, ppTimer);
Index: /trunk/src/VBox/VMM/VMMR3/TM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/TM.cpp	(revision 87759)
+++ /trunk/src/VBox/VMM/VMMR3/TM.cpp	(revision 87760)
@@ -1508,8 +1508,9 @@
  * @param   pVM         The cross context VM structure.
  * @param   enmClock    The timer clock.
+ * @param   fFlags      TMTIMER_FLAGS_XXX.
  * @param   pszDesc     The timer description.
  * @param   ppTimer     Where to store the timer pointer on success.
  */
-static int tmr3TimerCreate(PVM pVM, TMCLOCK enmClock, const char *pszDesc, PPTMTIMERR3 ppTimer)
+static int tmr3TimerCreate(PVM pVM, TMCLOCK enmClock, uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer)
 {
     VM_ASSERT_EMT(pVM);
@@ -1549,4 +1550,5 @@
     pTimer->pCritSect       = NULL;
     pTimer->pszDesc         = pszDesc;
+    pTimer->fFlags          = fFlags;
 
     /* insert into the list of created timers. */
@@ -1604,10 +1606,11 @@
                                         uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer)
 {
-    AssertReturn(!(fFlags & ~(TMTIMER_FLAGS_NO_CRIT_SECT)), VERR_INVALID_PARAMETER);
+    AssertReturn(!(fFlags & ~(TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_RING0 | TMTIMER_FLAGS_NO_RING0)),
+                 VERR_INVALID_FLAGS);
 
     /*
      * Allocate and init stuff.
      */
-    int rc = tmr3TimerCreate(pVM, enmClock, pszDesc, ppTimer);
+    int rc = tmr3TimerCreate(pVM, enmClock, fFlags, pszDesc, ppTimer);
     if (RT_SUCCESS(rc))
     {
@@ -1645,10 +1648,10 @@
                                      uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer)
 {
-    AssertReturn(!(fFlags & ~(TMTIMER_FLAGS_NO_CRIT_SECT)), VERR_INVALID_PARAMETER);
+    AssertReturn(!(fFlags & ~(TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_NO_RING0)), VERR_INVALID_PARAMETER);
 
     /*
      * Allocate and init stuff.
      */
-    int rc = tmr3TimerCreate(pVM, enmClock, pszDesc, ppTimer);
+    int rc = tmr3TimerCreate(pVM, enmClock, fFlags, pszDesc, ppTimer);
     if (RT_SUCCESS(rc))
     {
@@ -1688,10 +1691,11 @@
                                         uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer)
 {
-    AssertReturn(!(fFlags & ~(TMTIMER_FLAGS_NO_CRIT_SECT)), VERR_INVALID_PARAMETER);
+    AssertReturn(!(fFlags & ~(TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_RING0 | TMTIMER_FLAGS_NO_RING0)),
+                 VERR_INVALID_FLAGS);
 
     /*
      * Allocate and init stuff.
      */
-    int rc = tmr3TimerCreate(pVM, enmClock, pszDesc, ppTimer);
+    int rc = tmr3TimerCreate(pVM, enmClock, fFlags, pszDesc, ppTimer);
     if (RT_SUCCESS(rc))
     {
@@ -1719,5 +1723,6 @@
  * @param   ppTimer         Where to store the timer on success.
  */
-VMMR3DECL(int) TMR3TimerCreateInternal(PVM pVM, TMCLOCK enmClock, PFNTMTIMERINT pfnCallback, void *pvUser, const char *pszDesc, PPTMTIMERR3 ppTimer)
+VMMR3DECL(int) TMR3TimerCreateInternal(PVM pVM, TMCLOCK enmClock,
+                                       PFNTMTIMERINT pfnCallback, void *pvUser, const char *pszDesc, PPTMTIMERR3 ppTimer)
 {
     /*
@@ -1725,5 +1730,5 @@
      */
     PTMTIMER pTimer;
-    int rc = tmr3TimerCreate(pVM, enmClock, pszDesc, &pTimer);
+    int rc = tmr3TimerCreate(pVM, enmClock, 0 /*fFlags*/, pszDesc, &pTimer);
     if (RT_SUCCESS(rc))
     {
@@ -1750,5 +1755,6 @@
  *                          until the timer is fully destroyed (i.e. a bit after TMTimerDestroy()).
  */
-VMMR3DECL(PTMTIMERR3) TMR3TimerCreateExternal(PVM pVM, TMCLOCK enmClock, PFNTMTIMEREXT pfnCallback, void *pvUser, const char *pszDesc)
+VMMR3DECL(PTMTIMERR3) TMR3TimerCreateExternal(PVM pVM, TMCLOCK enmClock,
+                                              PFNTMTIMEREXT pfnCallback, void *pvUser, const char *pszDesc)
 {
     /*
@@ -1756,5 +1762,5 @@
      */
     PTMTIMERR3 pTimer;
-    int rc = tmr3TimerCreate(pVM, enmClock, pszDesc, &pTimer);
+    int rc = tmr3TimerCreate(pVM, enmClock, 0 /*fFlags*/, pszDesc, &pTimer);
     if (RT_SUCCESS(rc))
     {
Index: /trunk/src/VBox/VMM/include/TMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/TMInternal.h	(revision 87759)
+++ /trunk/src/VBox/VMM/include/TMInternal.h	(revision 87760)
@@ -206,4 +206,9 @@
     uint32_t                padding0; /**< pad structure to multiple of 8 bytes. */
 #endif
+
+    /** TMTIMER_FLAGS_XXX.   */
+    uint32_t                fFlags;
+    uint32_t                u32Pading;
+
 #ifdef VBOX_WITH_STATISTICS
     STAMPROFILE             StatTimer;
