Index: /trunk/include/VBox/vmm/pdmcritsect.h
===================================================================
--- /trunk/include/VBox/vmm/pdmcritsect.h	(revision 38943)
+++ /trunk/include/VBox/vmm/pdmcritsect.h	(revision 38944)
@@ -58,5 +58,5 @@
 VMMDECL(int)        PDMCritSectTryEnterDebug(PPDMCRITSECT pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL);
 VMMR3DECL(int)      PDMR3CritSectEnterEx(PPDMCRITSECT pCritSect, bool fCallRing3);
-VMMDECL(void)       PDMCritSectLeave(PPDMCRITSECT pCritSect);
+VMMDECL(int)        PDMCritSectLeave(PPDMCRITSECT pCritSect);
 VMMDECL(bool)       PDMCritSectIsOwner(PCPDMCRITSECT pCritSect);
 VMMDECL(bool)       PDMCritSectIsOwnerEx(PCPDMCRITSECT pCritSect, PVMCPU pVCpu);
Index: /trunk/include/iprt/err.h
===================================================================
--- /trunk/include/iprt/err.h	(revision 38943)
+++ /trunk/include/iprt/err.h	(revision 38944)
@@ -1106,4 +1106,7 @@
 /** Nested ownership requests are not permitted for this semaphore type. */
 #define VERR_SEM_NESTED                     (-364)
+/** The release call only release a semaphore nesting, i.e. the caller is still
+ * holding the semaphore. */
+#define VINF_SEM_NESTED                     (364)
 /** Deadlock detected. */
 #define VERR_DEADLOCK                       (-365)
Index: /trunk/src/VBox/VMM/VMMAll/PDMAllCritSect.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/PDMAllCritSect.cpp	(revision 38943)
+++ /trunk/src/VBox/VMM/VMMAll/PDMAllCritSect.cpp	(revision 38944)
@@ -491,7 +491,12 @@
  * Leaves a critical section entered with PDMCritSectEnter().
  *
+ * @returns Indication whether we really exited the critical section.
+ * @retval  VINF_SUCCESS if we really exited.
+ * @retval  VINF_SEM_NESTED if we only reduced the nesting count.
+ * @retval  VERR_NOT_OWNER if you somehow ignore release assertions.
+ *
  * @param   pCritSect           The PDM critical section to leave.
  */
-VMMDECL(void) PDMCritSectLeave(PPDMCRITSECT pCritSect)
+VMMDECL(int) PDMCritSectLeave(PPDMCRITSECT pCritSect)
 {
     AssertMsg(pCritSect->s.Core.u32Magic == RTCRITSECT_MAGIC, ("%p %RX32\n", pCritSect, pCritSect->s.Core.u32Magic));
@@ -500,5 +505,5 @@
     /* Check for NOP sections before asserting ownership. */
     if (pCritSect->s.Core.fFlags & RTCRITSECT_FLAGS_NOP)
-        return;
+        return VINF_SUCCESS;
 
     /*
@@ -506,8 +511,9 @@
      */
     RTNATIVETHREAD const hNativeSelf = pdmCritSectGetNativeSelf(pCritSect);
-    AssertReleaseMsgReturnVoid(pCritSect->s.Core.NativeThreadOwner == hNativeSelf,
-                               ("%p %s: %p != %p; cLockers=%d cNestings=%d\n", pCritSect, R3STRING(pCritSect->s.pszName),
-                                pCritSect->s.Core.NativeThreadOwner, hNativeSelf,
-                                pCritSect->s.Core.cLockers, pCritSect->s.Core.cNestings));
+    AssertReleaseMsgReturn(pCritSect->s.Core.NativeThreadOwner == hNativeSelf,
+                           ("%p %s: %p != %p; cLockers=%d cNestings=%d\n", pCritSect, R3STRING(pCritSect->s.pszName),
+                            pCritSect->s.Core.NativeThreadOwner, hNativeSelf,
+                            pCritSect->s.Core.cLockers, pCritSect->s.Core.cNestings),
+                           VERR_NOT_OWNER);
     Assert(pCritSect->s.Core.cNestings >= 1);
 
@@ -521,5 +527,5 @@
         ASMAtomicDecS32(&pCritSect->s.Core.cLockers);
         Assert(pCritSect->s.Core.cLockers >= 0);
-        return;
+        return VINF_SEM_NESTED;
     }
 
@@ -595,5 +601,5 @@
             ASMAtomicWriteHandle(&pCritSect->s.Core.NativeThreadOwner, NIL_RTNATIVETHREAD);
             if (ASMAtomicCmpXchgS32(&pCritSect->s.Core.cLockers, -1, 0))
-                return;
+                return VINF_SUCCESS;
 
             /* darn, someone raced in on us. */
@@ -620,4 +626,6 @@
     }
 #endif /* IN_RING0 || IN_RC */
+
+    return VINF_SUCCESS;
 }
 
