Index: /trunk/include/VBox/vmm/vmm.h
===================================================================
--- /trunk/include/VBox/vmm/vmm.h	(revision 48226)
+++ /trunk/include/VBox/vmm/vmm.h	(revision 48227)
@@ -543,4 +543,5 @@
 VMMRZDECL(int)      VMMRZCallRing3SetNotification(PVMCPU pVCpu, R0PTRTYPE(PFNVMMR0CALLRING3NOTIFICATION) pfnCallback, RTR0PTR pvUser);
 VMMRZDECL(void)     VMMRZCallRing3RemoveNotification(PVMCPU pVCpu);
+VMMRZDECL(bool)     VMMRZCallRing3IsNotificationSet(PVMCPU pVCpu);
 /** @} */
 #endif
Index: /trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp	(revision 48226)
+++ /trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp	(revision 48227)
@@ -301,4 +301,5 @@
  * @param   pvCpuPage       Pointer to the global CPU page.
  * @param   HCPhysCpuPage   Physical address of the global CPU page.
+ * @param   fEnabledByHost  Whether the host OS has already initialized AMD-V.
  * @param   pvArg           Unused on AMD-V.
  */
@@ -311,4 +312,5 @@
     AssertReturn(pvCpuPage, VERR_INVALID_PARAMETER);
     NOREF(pvArg);
+    NOREF(fEnabledByHost);
 
     /*
@@ -1587,4 +1589,5 @@
 
     LogFlowFunc(("pVM=%p pVCpu=%p\n", pVM, pVCpu));
+    Assert(pVCpu->hm.s.fContextUseFlags & (HM_CHANGED_HOST_CONTEXT | HM_CHANGED_HOST_GUEST_SHARED_STATE));
 
     pVCpu->hm.s.fLeaveDone = false;
@@ -2091,12 +2094,12 @@
     }
 
-    /* On our way back from ring-3 the following needs to be done. */
-    /** @todo This can change with preemption hooks. */
-    if (rcExit == VINF_EM_RAW_INTERRUPT)
-        pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_HOST_CONTEXT;
-    else
-        pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_HOST_CONTEXT | HM_CHANGED_ALL_GUEST;
+    /* On our way back from ring-3 reload the guest state if there is a possibility of it being changed. */
+    if (rcExit != VINF_EM_RAW_INTERRUPT)
+        pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_ALL_GUEST;
 
     STAM_COUNTER_INC(&pVCpu->hm.s.StatSwitchExitToR3);
+
+    /* We do -not- want any longjmp notifications after this! We must return to ring-3 ASAP. */
+    VMMRZCallRing3RemoveNotification(pVCpu);
     VMMRZCallRing3Enable(pVCpu);
 }
@@ -3066,5 +3069,5 @@
 
     hmR0SvmExitToRing3(pVM, pVCpu, pCtx, rc);
-    VMMRZCallRing3RemoveNotification(pVCpu);
+    Assert(!VMMRZCallRing3IsNotificationSet(pVCpu));
     return rc;
 }
Index: /trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp	(revision 48226)
+++ /trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp	(revision 48227)
@@ -1018,4 +1018,5 @@
     Assert(!RTThreadPreemptIsEnabled(NIL_RTTHREAD));
 
+    /* Enable VT-x if it's not already enabled by the host. */
     if (!fEnabledByHost)
     {
@@ -6177,4 +6178,5 @@
 {
     HM_DISABLE_PREEMPT_IF_NEEDED();
+    HMVMX_ASSERT_CPU_SAFE();
     Assert(!VMMRZCallRing3IsEnabled(pVCpu));
     Assert(!RTThreadPreemptIsEnabled(NIL_RTTHREAD));
@@ -6299,11 +6301,12 @@
      *        accessing APIC page in prot mode. */
 
-    /* On our way back from ring-3 the following needs to be done. */
-    if (rcExit == VINF_EM_RAW_INTERRUPT)
-        pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_HOST_CONTEXT;
-    else
-        pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_HOST_CONTEXT | HM_CHANGED_ALL_GUEST;
+    /* On our way back from ring-3 reload the guest state if there is a possibility of it being changed. */
+    if (rcExit != VINF_EM_RAW_INTERRUPT)
+        pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_ALL_GUEST;
 
     STAM_COUNTER_INC(&pVCpu->hm.s.StatSwitchExitToR3);
+
+    /* We do -not- want any longjmp notifications after this! We must return to ring-3 ASAP. */
+    VMMRZCallRing3RemoveNotification(pVCpu);
     VMMRZCallRing3Enable(pVCpu);
 }
@@ -6902,4 +6905,5 @@
 
     LogFlowFunc(("pVM=%p pVCpu=%p\n", pVM, pVCpu));
+    Assert(pVCpu->hm.s.fContextUseFlags & (HM_CHANGED_HOST_CONTEXT | HM_CHANGED_HOST_GUEST_SHARED_STATE));
 
 #ifdef VBOX_STRICT
@@ -7745,5 +7749,5 @@
 
     hmR0VmxExitToRing3(pVM, pVCpu, pCtx, rc);
-    VMMRZCallRing3RemoveNotification(pVCpu);
+    Assert(!VMMRZCallRing3IsNotificationSet(pVCpu));
     return rc;
 }
@@ -8588,4 +8592,6 @@
                         Assert(pVCpu->CTX_SUFF(pVM)->hm.s.vmx.pRealModeTSS);
                         Assert(PDMVmmDevHeapIsEnabled(pVCpu->CTX_SUFF(pVM)));
+                        Assert(CPUMIsGuestInRealModeEx(pMixedCtx));
+
                         rc  = hmR0VmxReadExitInstrLenVmcs(pVCpu, pVmxTransient);
                         rc |= hmR0VmxReadExitIntrErrorCodeVmcs(pVCpu, pVmxTransient);
Index: /trunk/src/VBox/VMM/VMMRZ/VMMRZ.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMRZ/VMMRZ.cpp	(revision 48226)
+++ /trunk/src/VBox/VMM/VMMRZ/VMMRZ.cpp	(revision 48227)
@@ -214,2 +214,14 @@
 }
 
+
+/**
+ * Checks whether there is a ring-0 callback notification active.
+ *
+ * @param   pVCpu   Pointer to the VMCPU.
+ * @returns true if there the notification is active, false otherwise.
+ */
+VMMRZDECL(bool) VMMRZCallRing3IsNotificationSet(PVMCPU pVCpu)
+{
+    return !(pVCpu->vmm.s.pfnCallRing3CallbackR0 == NULL);
+}
+
