Index: trunk/src/VBox/VMM/VMMR0/HMR0.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR0/HMR0.cpp	(revision 48229)
+++ trunk/src/VBox/VMM/VMMR0/HMR0.cpp	(revision 48230)
@@ -1074,5 +1074,5 @@
         {
             rc = g_HvmR0.pfnDisableCpu(pCpu, pvCpuPage, HCPhysCpuPage);
-            AssertRC(rc);
+            AssertRCReturn(rc, rc);
         }
         else
Index: trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp	(revision 48229)
+++ trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp	(revision 48230)
@@ -1961,5 +1961,5 @@
  * @param   pCtx        Pointer to the guest-CPU context.
  */
-static void hmR0SvmLeaveSession(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
+static int hmR0SvmLeaveSession(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
 {
     HM_DISABLE_PREEMPT_IF_NEEDED();
@@ -1981,7 +1981,7 @@
     /* Leave HM context. This takes care of local init (term). */
     int rc = HMR0LeaveCpu(pVCpu);
-    AssertRC(rc); NOREF(rc);
 
     HM_RESTORE_PREEMPT_IF_NEEDED();
+    return rc;
 }
 
@@ -1990,4 +1990,5 @@
  * Does the necessary state syncing before doing a longjmp to ring-3.
  *
+ * @returns VBox status code.
  * @param   pVM         Pointer to the VM.
  * @param   pVCpu       Pointer to the VMCPU.
@@ -1996,7 +1997,7 @@
  * @remarks No-long-jmp zone!!!
  */
-static void hmR0SvmLongJmpToRing3(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
-{
-    hmR0SvmLeaveSession(pVM, pVCpu, pCtx);
+static int hmR0SvmLongJmpToRing3(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
+{
+    return hmR0SvmLeaveSession(pVM, pVCpu, pCtx);
 }
 
@@ -2013,7 +2014,9 @@
  *
  * @remarks Must never be called with @a enmOperation ==
- *          VMMCALLRING3_VM_R0_ASSERTION.
- */
-DECLCALLBACK(void) hmR0SvmCallRing3Callback(PVMCPU pVCpu, VMMCALLRING3 enmOperation, void *pvUser)
+ *          VMMCALLRING3_VM_R0_ASSERTION. We can't assert it here because if it
+ *          it -does- get called with VMMCALLRING3_VM_R0_ASSERTION, we'll end up
+ *          with an infinite recursion.
+ */
+DECLCALLBACK(int) hmR0SvmCallRing3Callback(PVMCPU pVCpu, VMMCALLRING3 enmOperation, void *pvUser)
 {
     /* VMMRZCallRing3() already makes sure we never get called as a result of an longjmp due to an assertion, */
@@ -2027,7 +2030,9 @@
 
     Log4(("hmR0SvmCallRing3Callback->hmR0SvmLongJmpToRing3\n"));
-    hmR0SvmLongJmpToRing3(pVCpu->CTX_SUFF(pVM), pVCpu, (PCPUMCTX)pvUser);
+    int rc = hmR0SvmLongJmpToRing3(pVCpu->CTX_SUFF(pVM), pVCpu, (PCPUMCTX)pvUser);
+    AssertRCReturn(rc, rc);
 
     VMMRZCallRing3Enable(pVCpu);
+    return VINF_SUCCESS;
 }
 
Index: trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp	(revision 48229)
+++ trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp	(revision 48230)
@@ -6085,4 +6085,5 @@
  * (longjmp, preemption, voluntary exits to ring-3) from VT-x.
  *
+ * @returns VBox status code.
  * @param   pVM         Pointer to the VM.
  * @param   pVCpu       Pointer to the VMCPU.
@@ -6093,5 +6094,5 @@
  * @remarks No-long-jmp zone!!!
  */
-static void hmR0VmxLeave(PVM pVM, PVMCPU pVCpu, PCPUMCTX pMixedCtx)
+static int hmR0VmxLeave(PVM pVM, PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 {
     Assert(!RTThreadPreemptIsEnabled(NIL_RTTHREAD));
@@ -6105,5 +6106,5 @@
     {
         int rc = hmR0VmxSaveGuestState(pVCpu, pMixedCtx);
-        AssertRC(rc);
+        AssertRCReturn(rc, rc);
         Assert(pVCpu->hm.s.vmx.fUpdatedGuestState == HMVMX_UPDATED_GUEST_ALL);
     }
@@ -6155,5 +6156,6 @@
     {
         int rc = VMXClearVmcs(pVCpu->hm.s.vmx.HCPhysVmcs);
-        AssertRC(rc);
+        AssertRCReturn(rc, rc);
+
         pVCpu->hm.s.vmx.uVmcsState = HMVMX_VMCS_STATE_CLEAR;
         Log4Func(("Cleared Vmcs. HostCpuId=%u\n", idCpu));
@@ -6161,4 +6163,6 @@
     Assert(!(pVCpu->hm.s.vmx.uVmcsState & HMVMX_VMCS_STATE_LAUNCHED));
     NOREF(idCpu);
+
+    return VINF_SUCCESS;
 }
 
@@ -6167,4 +6171,5 @@
  * Leaves the VT-x session.
  *
+ * @returns VBox status code.
  * @param   pVM         Pointer to the VM.
  * @param   pVCpu       Pointer to the VMCPU.
@@ -6175,5 +6180,5 @@
  * @remarks No-long-jmp zone!!!
  */
-DECLINLINE(void) hmR0VmxLeaveSession(PVM pVM, PVMCPU pVCpu, PCPUMCTX pMixedCtx)
+DECLINLINE(int) hmR0VmxLeaveSession(PVM pVM, PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 {
     HM_DISABLE_PREEMPT_IF_NEEDED();
@@ -6186,5 +6191,6 @@
     if (!pVCpu->hm.s.fLeaveDone)
     {
-        hmR0VmxLeave(pVM, pVCpu, pMixedCtx);
+        int rc2 = hmR0VmxLeave(pVM, pVCpu, pMixedCtx);
+        AssertRCReturn(rc2, rc2);
         pVCpu->hm.s.fLeaveDone = true;
     }
@@ -6198,7 +6204,8 @@
     /* Leave HM context. This takes care of local init (term). */
     int rc = HMR0LeaveCpu(pVCpu);
-    AssertRC(rc); NOREF(rc);
 
     HM_RESTORE_PREEMPT_IF_NEEDED();
+
+    return rc;
 }
 
@@ -6207,4 +6214,5 @@
  * Does the necessary state syncing before doing a longjmp to ring-3.
  *
+ * @returns VBox status code.
  * @param   pVM         Pointer to the VM.
  * @param   pVCpu       Pointer to the VMCPU.
@@ -6215,7 +6223,7 @@
  * @remarks No-long-jmp zone!!!
  */
-DECLINLINE(void) hmR0VmxLongJmpToRing3(PVM pVM, PVMCPU pVCpu, PCPUMCTX pMixedCtx)
-{
-    hmR0VmxLeaveSession(pVM, pVCpu, pMixedCtx);
+DECLINLINE(int) hmR0VmxLongJmpToRing3(PVM pVM, PVMCPU pVCpu, PCPUMCTX pMixedCtx)
+{
+    return hmR0VmxLeaveSession(pVM, pVCpu, pMixedCtx);
 }
 
@@ -6229,4 +6237,5 @@
  * executing outside HM (recompiler/IEM).
  *
+ * @returns VBox status code.
  * @param   pVM         Pointer to the VM.
  * @param   pVCpu       Pointer to the VMCPU.
@@ -6237,5 +6246,5 @@
  *                      VINF_VMM_UNKNOWN_RING3_CALL.
  */
-static void hmR0VmxExitToRing3(PVM pVM, PVMCPU pVCpu, PCPUMCTX pMixedCtx, int rcExit)
+static int hmR0VmxExitToRing3(PVM pVM, PVMCPU pVCpu, PCPUMCTX pMixedCtx, int rcExit)
 {
     Assert(pVM);
@@ -6247,5 +6256,5 @@
     {
         /* We've done what is required in hmR0VmxExitErrInvalidGuestState(). We're not going to continue guest execution... */
-        return;
+        return VINF_SUCCESS;
     }
     else if (RT_UNLIKELY(rcExit == VERR_VMX_INVALID_VMCS_PTR))
@@ -6255,5 +6264,5 @@
         pVCpu->hm.s.vmx.LastError.idEnteredCpu    = pVCpu->hm.s.idEnteredCpu;
         /* LastError.idCurrentCpu was updated in hmR0VmxPreRunGuestCommitted(). */
-        return;
+        return VINF_SUCCESS;
     }
 
@@ -6270,5 +6279,5 @@
 
     /* Save guest state and restore host state bits. */
-    hmR0VmxLeaveSession(pVM, pVCpu, pMixedCtx);
+    int rc = hmR0VmxLeaveSession(pVM, pVCpu, pMixedCtx);
     STAM_COUNTER_DEC(&pVCpu->hm.s.StatSwitchLongJmpToR3);
 
@@ -6282,6 +6291,6 @@
                               | CPUM_CHANGED_HIDDEN_SEL_REGS);
     Assert(pVCpu->hm.s.vmx.fUpdatedGuestState & HMVMX_UPDATED_GUEST_CR0);
-    if (    pVM->hm.s.fNestedPaging
-        &&  CPUMIsGuestPagingEnabledEx(pMixedCtx))
+    if (   pVM->hm.s.fNestedPaging
+        && CPUMIsGuestPagingEnabledEx(pMixedCtx))
     {
         CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_GLOBAL_TLB_FLUSH);
@@ -6310,4 +6319,6 @@
     VMMRZCallRing3RemoveNotification(pVCpu);
     VMMRZCallRing3Enable(pVCpu);
+
+    return rc;
 }
 
@@ -6317,13 +6328,17 @@
  * longjump to ring-3 and possibly get preempted.
  *
+ * @returns VBox status code.
  * @param   pVCpu           Pointer to the VMCPU.
  * @param   enmOperation    The operation causing the ring-3 longjump.
- * @param   pvUser          The user argument (pointer to the possibly
- *                          out-of-date guest-CPU context).
+ * @param   pvUser          Opaque pointer to the guest-CPU context. The data
+ *                          may be out-of-sync. Make sure to update the required
+ *                          fields before using them.
  *
  * @remarks Must never be called with @a enmOperation ==
- *          VMMCALLRING3_VM_R0_ASSERTION.
- */
-DECLCALLBACK(void) hmR0VmxCallRing3Callback(PVMCPU pVCpu, VMMCALLRING3 enmOperation, void *pvUser)
+ *          VMMCALLRING3_VM_R0_ASSERTION. We can't assert it here because if it
+ *          it -does- get called with VMMCALLRING3_VM_R0_ASSERTION, we'll end up
+ *          with an infinite recursion.
+ */
+DECLCALLBACK(int) hmR0VmxCallRing3Callback(PVMCPU pVCpu, VMMCALLRING3 enmOperation, void *pvUser)
 {
     /* VMMRZCallRing3() already makes sure we never get called as a result of an longjmp due to an assertion. */
@@ -6337,7 +6352,9 @@
 
     Log4(("hmR0VmxCallRing3Callback->hmR0VmxLongJmpToRing3 pVCpu=%p idCpu=%RU32\n", pVCpu, pVCpu->idCpu));
-    hmR0VmxLongJmpToRing3(pVCpu->CTX_SUFF(pVM), pVCpu, (PCPUMCTX)pvUser);
+    int rc = hmR0VmxLongJmpToRing3(pVCpu->CTX_SUFF(pVM), pVCpu, (PCPUMCTX)pvUser);
+    AssertRCReturn(rc, rc);
 
     VMMRZCallRing3Enable(pVCpu);
+    return VINF_SUCCESS;
 }
 
@@ -7748,5 +7765,10 @@
         rc = VINF_EM_TRIPLE_FAULT;
 
-    hmR0VmxExitToRing3(pVM, pVCpu, pCtx, rc);
+    int rc2 = hmR0VmxExitToRing3(pVM, pVCpu, pCtx, rc);
+    if (RT_FAILURE(rc2))
+    {
+        pVCpu->hm.s.u32HMError = rc;
+        rc = rc2;
+    }
     Assert(!VMMRZCallRing3IsNotificationSet(pVCpu));
     return rc;
Index: trunk/src/VBox/VMM/VMMRZ/VMMRZ.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMRZ/VMMRZ.cpp	(revision 48229)
+++ trunk/src/VBox/VMM/VMMRZ/VMMRZ.cpp	(revision 48230)
@@ -86,10 +86,13 @@
     pVM->vmm.s.pfnRCToHost(VINF_VMM_CALL_HOST);
 #else
+    int rc;
     if (   pVCpu->vmm.s.pfnCallRing3CallbackR0
         && enmOperation != VMMCALLRING3_VM_R0_ASSERTION)
     {
-        pVCpu->vmm.s.pfnCallRing3CallbackR0(pVCpu, enmOperation, pVCpu->vmm.s.pvCallRing3CallbackUserR0);
-    }
-    int rc = vmmR0CallRing3LongJmp(&pVCpu->vmm.s.CallRing3JmpBufR0, VINF_VMM_CALL_HOST);
+        rc = pVCpu->vmm.s.pfnCallRing3CallbackR0(pVCpu, enmOperation, pVCpu->vmm.s.pvCallRing3CallbackUserR0);
+        if (RT_FAILURE(rc))
+            return rc;
+    }
+    rc = vmmR0CallRing3LongJmp(&pVCpu->vmm.s.CallRing3JmpBufR0, VINF_VMM_CALL_HOST);
     if (RT_FAILURE(rc))
         return rc;
