Index: trunk/src/VBox/VMM/VMMAll/PDMAllCritSect.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/PDMAllCritSect.cpp	(revision 90328)
+++ trunk/src/VBox/VMM/VMMAll/PDMAllCritSect.cpp	(revision 90329)
@@ -290,4 +290,16 @@
 #else
 # ifdef IN_RING0
+    /*
+     * In ring-0 context we have to take the special VT-x/AMD-V HM context into
+     * account when waiting on contended locks.
+     *
+     * While we usually (it can be VINF_SUCCESS) have to option via the rcBusy
+     * parameter of going to back to ring-3 and to re-start the work there, it's
+     * almost always more efficient to try wait for the lock here.  The rcBusy
+     * will be used if we encounter an VERR_INTERRUPTED situation though.
+     *
+     * We must never block if VMMRZCallRing3Disable is active.
+     */
+
     /** @todo If preemption is disabled it means we're in VT-x/AMD-V context
      *        and would be better off switching out of that while waiting for
@@ -333,5 +345,5 @@
         return pdmR3R0CritSectEnterContended(pCritSect, hNativeSelf, pSrcPos);
 #  endif
-#endif /* IN_RING0 */
+# endif /* IN_RING0 */
 
     STAM_REL_COUNTER_INC(&pCritSect->s.StatContentionRZLock);
Index: trunk/src/VBox/VMM/VMMR0/PDMR0Driver.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR0/PDMR0Driver.cpp	(revision 90328)
+++ trunk/src/VBox/VMM/VMMR0/PDMR0Driver.cpp	(revision 90329)
@@ -113,4 +113,100 @@
 
 
+/** @interface_method_impl{PDMDRVHLPR0,pfnCritSectEnter} */
+static DECLCALLBACK(int)      pdmR0DrvHlp_CritSectEnter(PPDMDRVINS pDrvIns, PPDMCRITSECT pCritSect, int rcBusy)
+{
+    PDMDRV_ASSERT_DRVINS(pDrvIns);
+    NOREF(pDrvIns);
+    return PDMCritSectEnter(pCritSect, rcBusy);
+}
+
+
+/** @interface_method_impl{PDMDRVHLPR0,pfnCritSectEnterDebug} */
+static DECLCALLBACK(int)      pdmR0DrvHlp_CritSectEnterDebug(PPDMDRVINS pDrvIns, PPDMCRITSECT pCritSect, int rcBusy,
+                                                             RTHCUINTPTR uId, RT_SRC_POS_DECL)
+{
+    PDMDRV_ASSERT_DRVINS(pDrvIns);
+    NOREF(pDrvIns);
+    return PDMCritSectEnterDebug(pCritSect, rcBusy, uId, RT_SRC_POS_ARGS);
+}
+
+
+/** @interface_method_impl{PDMDRVHLPR0,pfnCritSectTryEnter} */
+static DECLCALLBACK(int)      pdmR0DrvHlp_CritSectTryEnter(PPDMDRVINS pDrvIns, PPDMCRITSECT pCritSect)
+{
+    PDMDRV_ASSERT_DRVINS(pDrvIns);
+    NOREF(pDrvIns);
+    return PDMCritSectTryEnter(pCritSect);
+}
+
+
+/** @interface_method_impl{PDMDRVHLPR0,pfnCritSectTryEnterDebug} */
+static DECLCALLBACK(int)      pdmR0DrvHlp_CritSectTryEnterDebug(PPDMDRVINS pDrvIns, PPDMCRITSECT pCritSect,
+                                                                RTHCUINTPTR uId, RT_SRC_POS_DECL)
+{
+    PDMDRV_ASSERT_DRVINS(pDrvIns);
+    NOREF(pDrvIns);
+    return PDMCritSectTryEnterDebug(pCritSect, uId, RT_SRC_POS_ARGS);
+}
+
+
+/** @interface_method_impl{PDMDRVHLPR0,pfnCritSectLeave} */
+static DECLCALLBACK(int)      pdmR0DrvHlp_CritSectLeave(PPDMDRVINS pDrvIns, PPDMCRITSECT pCritSect)
+{
+    PDMDRV_ASSERT_DRVINS(pDrvIns);
+    NOREF(pDrvIns);
+    return PDMCritSectLeave(pCritSect);
+}
+
+
+/** @interface_method_impl{PDMDRVHLPR0,pfnCritSectIsOwner} */
+static DECLCALLBACK(bool)     pdmR0DrvHlp_CritSectIsOwner(PPDMDRVINS pDrvIns, PCPDMCRITSECT pCritSect)
+{
+    PDMDRV_ASSERT_DRVINS(pDrvIns);
+    NOREF(pDrvIns);
+    return PDMCritSectIsOwner(pCritSect);
+}
+
+
+/** @interface_method_impl{PDMDRVHLPR0,pfnCritSectIsInitialized} */
+static DECLCALLBACK(bool)     pdmR0DrvHlp_CritSectIsInitialized(PPDMDRVINS pDrvIns, PCPDMCRITSECT pCritSect)
+{
+    PDMDRV_ASSERT_DRVINS(pDrvIns);
+    NOREF(pDrvIns);
+    return PDMCritSectIsInitialized(pCritSect);
+}
+
+
+/** @interface_method_impl{PDMDRVHLPR0,pfnCritSectHasWaiters} */
+static DECLCALLBACK(bool)     pdmR0DrvHlp_CritSectHasWaiters(PPDMDRVINS pDrvIns, PCPDMCRITSECT pCritSect)
+{
+    PDMDRV_ASSERT_DRVINS(pDrvIns);
+    NOREF(pDrvIns);
+    return PDMCritSectHasWaiters(pCritSect);
+}
+
+
+/** @interface_method_impl{PDMDRVHLPR0,pfnCritSectGetRecursion} */
+static DECLCALLBACK(uint32_t) pdmR0DrvHlp_CritSectGetRecursion(PPDMDRVINS pDrvIns, PCPDMCRITSECT pCritSect)
+{
+    PDMDRV_ASSERT_DRVINS(pDrvIns);
+    NOREF(pDrvIns);
+    return PDMCritSectGetRecursion(pCritSect);
+}
+
+
+/** @interface_method_impl{PDMDRVHLPR0,pfn} */
+static DECLCALLBACK(int)      pdmR0DrvHlp_CritSectScheduleExitEvent(PPDMDRVINS pDrvIns, PPDMCRITSECT pCritSect,
+                                                                    SUPSEMEVENT hEventToSignal)
+{
+    PDMDRV_ASSERT_DRVINS(pDrvIns);
+    NOREF(pDrvIns);
+    return PDMHCCritSectScheduleExitEvent(pCritSect, hEventToSignal);
+}
+
+
+/** @interface_method_impl{PDMDRVHLPR0,pfn} */
+
+
 /**
  * The Ring-0 Context Driver Helper Callbacks.
@@ -125,4 +221,14 @@
     pdmR0DrvHlp_AssertEMT,
     pdmR0DrvHlp_AssertOther,
+    pdmR0DrvHlp_CritSectEnter,
+    pdmR0DrvHlp_CritSectEnterDebug,
+    pdmR0DrvHlp_CritSectTryEnter,
+    pdmR0DrvHlp_CritSectTryEnterDebug,
+    pdmR0DrvHlp_CritSectLeave,
+    pdmR0DrvHlp_CritSectIsOwner,
+    pdmR0DrvHlp_CritSectIsInitialized,
+    pdmR0DrvHlp_CritSectHasWaiters,
+    pdmR0DrvHlp_CritSectGetRecursion,
+    pdmR0DrvHlp_CritSectScheduleExitEvent,
     PDM_DRVHLPRC_VERSION
 };
Index: trunk/src/VBox/VMM/VMMR3/PDMDriver.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/PDMDriver.cpp	(revision 90328)
+++ trunk/src/VBox/VMM/VMMR3/PDMDriver.cpp	(revision 90329)
@@ -1783,4 +1783,114 @@
 }
 
+/** @interface_method_impl{PDMDRVHLPR3,pfnCritSectYield} */
+static DECLCALLBACK(bool)     pdmR3DrvHlp_CritSectYield(PPDMDRVINS pDrvIns, PPDMCRITSECT pCritSect)
+{
+    PDMDRV_ASSERT_DRVINS(pDrvIns);
+    RT_NOREF(pDrvIns);
+    return PDMR3CritSectYield(pDrvIns->Internal.s.pVMR3, pCritSect);
+}
+
+
+/** @interface_method_impl{PDMDRVHLPR3,pfnCritSectEnter} */
+static DECLCALLBACK(int)      pdmR3DrvHlp_CritSectEnter(PPDMDRVINS pDrvIns, PPDMCRITSECT pCritSect, int rcBusy)
+{
+    PDMDRV_ASSERT_DRVINS(pDrvIns);
+    RT_NOREF(pDrvIns);
+    return PDMCritSectEnter(pCritSect, rcBusy);
+}
+
+
+/** @interface_method_impl{PDMDRVHLPR3,pfnCritSectEnterDebug} */
+static DECLCALLBACK(int)      pdmR3DrvHlp_CritSectEnterDebug(PPDMDRVINS pDrvIns, PPDMCRITSECT pCritSect, int rcBusy,
+                                                             RTHCUINTPTR uId, RT_SRC_POS_DECL)
+{
+    PDMDRV_ASSERT_DRVINS(pDrvIns);
+    RT_NOREF(pDrvIns);
+    return PDMCritSectEnterDebug(pCritSect, rcBusy, uId, RT_SRC_POS_ARGS);
+}
+
+
+/** @interface_method_impl{PDMDRVHLPR3,pfnCritSectTryEnter} */
+static DECLCALLBACK(int)      pdmR3DrvHlp_CritSectTryEnter(PPDMDRVINS pDrvIns, PPDMCRITSECT pCritSect)
+{
+    PDMDRV_ASSERT_DRVINS(pDrvIns);
+    RT_NOREF(pDrvIns);
+    return PDMCritSectTryEnter(pCritSect);
+}
+
+
+/** @interface_method_impl{PDMDRVHLPR3,pfnCritSectTryEnterDebug} */
+static DECLCALLBACK(int)      pdmR3DrvHlp_CritSectTryEnterDebug(PPDMDRVINS pDrvIns, PPDMCRITSECT pCritSect,
+                                                                RTHCUINTPTR uId, RT_SRC_POS_DECL)
+{
+    PDMDRV_ASSERT_DRVINS(pDrvIns);
+    RT_NOREF(pDrvIns);
+    return PDMCritSectTryEnterDebug(pCritSect, uId, RT_SRC_POS_ARGS);
+}
+
+
+/** @interface_method_impl{PDMDRVHLPR3,pfnCritSectLeave} */
+static DECLCALLBACK(int)      pdmR3DrvHlp_CritSectLeave(PPDMDRVINS pDrvIns, PPDMCRITSECT pCritSect)
+{
+    PDMDRV_ASSERT_DRVINS(pDrvIns);
+    RT_NOREF(pDrvIns);
+    return PDMCritSectLeave(pCritSect);
+}
+
+
+/** @interface_method_impl{PDMDRVHLPR3,pfnCritSectIsOwner} */
+static DECLCALLBACK(bool)     pdmR3DrvHlp_CritSectIsOwner(PPDMDRVINS pDrvIns, PCPDMCRITSECT pCritSect)
+{
+    PDMDRV_ASSERT_DRVINS(pDrvIns);
+    RT_NOREF(pDrvIns);
+    return PDMCritSectIsOwner(pCritSect);
+}
+
+
+/** @interface_method_impl{PDMDRVHLPR3,pfnCritSectIsInitialized} */
+static DECLCALLBACK(bool)     pdmR3DrvHlp_CritSectIsInitialized(PPDMDRVINS pDrvIns, PCPDMCRITSECT pCritSect)
+{
+    PDMDRV_ASSERT_DRVINS(pDrvIns);
+    RT_NOREF(pDrvIns);
+    return PDMCritSectIsInitialized(pCritSect);
+}
+
+
+/** @interface_method_impl{PDMDRVHLPR3,pfnCritSectHasWaiters} */
+static DECLCALLBACK(bool)     pdmR3DrvHlp_CritSectHasWaiters(PPDMDRVINS pDrvIns, PCPDMCRITSECT pCritSect)
+{
+    PDMDRV_ASSERT_DRVINS(pDrvIns);
+    RT_NOREF(pDrvIns);
+    return PDMCritSectHasWaiters(pCritSect);
+}
+
+
+/** @interface_method_impl{PDMDRVHLPR3,pfnCritSectGetRecursion} */
+static DECLCALLBACK(uint32_t) pdmR3DrvHlp_CritSectGetRecursion(PPDMDRVINS pDrvIns, PCPDMCRITSECT pCritSect)
+{
+    PDMDRV_ASSERT_DRVINS(pDrvIns);
+    RT_NOREF(pDrvIns);
+    return PDMCritSectGetRecursion(pCritSect);
+}
+
+
+/** @interface_method_impl{PDMDRVHLPR3,pfnCritSectScheduleExitEvent} */
+static DECLCALLBACK(int)      pdmR3DrvHlp_CritSectScheduleExitEvent(PPDMDRVINS pDrvIns, PPDMCRITSECT pCritSect,
+                                                                    SUPSEMEVENT hEventToSignal)
+{
+    PDMDRV_ASSERT_DRVINS(pDrvIns);
+    RT_NOREF(pDrvIns);
+    return PDMHCCritSectScheduleExitEvent(pCritSect, hEventToSignal);
+}
+
+
+/** @interface_method_impl{PDMDRVHLPR3,pfnCritSectDelete} */
+static DECLCALLBACK(int)      pdmR3DrvHlp_CritSectDelete(PPDMDRVINS pDrvIns, PPDMCRITSECT pCritSect)
+{
+    PDMDRV_ASSERT_DRVINS(pDrvIns);
+    RT_NOREF(pDrvIns);
+    return PDMR3CritSectDelete(pCritSect);
+}
+
 
 /** @interface_method_impl{PDMDRVHLPR3,pfnCallR0} */
@@ -1941,4 +2051,16 @@
     pdmR3DrvHlp_LdrGetR0InterfaceSymbols,
     pdmR3DrvHlp_CritSectInit,
+    pdmR3DrvHlp_CritSectYield,
+    pdmR3DrvHlp_CritSectEnter,
+    pdmR3DrvHlp_CritSectEnterDebug,
+    pdmR3DrvHlp_CritSectTryEnter,
+    pdmR3DrvHlp_CritSectTryEnterDebug,
+    pdmR3DrvHlp_CritSectLeave,
+    pdmR3DrvHlp_CritSectIsOwner,
+    pdmR3DrvHlp_CritSectIsInitialized,
+    pdmR3DrvHlp_CritSectHasWaiters,
+    pdmR3DrvHlp_CritSectGetRecursion,
+    pdmR3DrvHlp_CritSectScheduleExitEvent,
+    pdmR3DrvHlp_CritSectDelete,
     pdmR3DrvHlp_CallR0,
     pdmR3DrvHlp_BlkCacheRetain,
