Index: trunk/src/VBox/VMM/VMMR3/APIC.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/APIC.cpp	(revision 87748)
+++ 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 87748)
+++ 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 87748)
+++ 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 87748)
+++ 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 87748)
+++ 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))
     {
