Index: /trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h	(revision 76039)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h	(revision 76040)
@@ -99,20 +99,20 @@
 
 /** Gets the guest-physical address of the shadows VMCS for the given VCPU. */
-#define IEM_VMX_GET_SHADOW_VMCS(a_pVCpu)            ((a_pVCpu)->cpum.GstCtx.hwvirt.vmx.GCPhysShadowVmcs)
+# define IEM_VMX_GET_SHADOW_VMCS(a_pVCpu)           ((a_pVCpu)->cpum.GstCtx.hwvirt.vmx.GCPhysShadowVmcs)
 
 /** Whether a shadow VMCS is present for the given VCPU. */
-#define IEM_VMX_HAS_SHADOW_VMCS(a_pVCpu)            RT_BOOL(IEM_VMX_GET_SHADOW_VMCS(a_pVCpu) != NIL_RTGCPHYS)
+# define IEM_VMX_HAS_SHADOW_VMCS(a_pVCpu)           RT_BOOL(IEM_VMX_GET_SHADOW_VMCS(a_pVCpu) != NIL_RTGCPHYS)
 
 /** Gets the VMXON region pointer. */
-#define IEM_VMX_GET_VMXON_PTR(a_pVCpu)              ((a_pVCpu)->cpum.GstCtx.hwvirt.vmx.GCPhysVmxon)
+# define IEM_VMX_GET_VMXON_PTR(a_pVCpu)             ((a_pVCpu)->cpum.GstCtx.hwvirt.vmx.GCPhysVmxon)
 
 /** Gets the guest-physical address of the current VMCS for the given VCPU. */
-#define IEM_VMX_GET_CURRENT_VMCS(a_pVCpu)           ((a_pVCpu)->cpum.GstCtx.hwvirt.vmx.GCPhysVmcs)
+# define IEM_VMX_GET_CURRENT_VMCS(a_pVCpu)          ((a_pVCpu)->cpum.GstCtx.hwvirt.vmx.GCPhysVmcs)
 
 /** Whether a current VMCS is present for the given VCPU. */
-#define IEM_VMX_HAS_CURRENT_VMCS(a_pVCpu)           RT_BOOL(IEM_VMX_GET_CURRENT_VMCS(a_pVCpu) != NIL_RTGCPHYS)
+# define IEM_VMX_HAS_CURRENT_VMCS(a_pVCpu)          RT_BOOL(IEM_VMX_GET_CURRENT_VMCS(a_pVCpu) != NIL_RTGCPHYS)
 
 /** Assigns the guest-physical address of the current VMCS for the given VCPU. */
-#define IEM_VMX_SET_CURRENT_VMCS(a_pVCpu, a_GCPhysVmcs) \
+# define IEM_VMX_SET_CURRENT_VMCS(a_pVCpu, a_GCPhysVmcs) \
     do \
     { \
@@ -122,5 +122,5 @@
 
 /** Clears any current VMCS for the given VCPU. */
-#define IEM_VMX_CLEAR_CURRENT_VMCS(a_pVCpu) \
+# define IEM_VMX_CLEAR_CURRENT_VMCS(a_pVCpu) \
     do \
     { \
@@ -130,5 +130,5 @@
 /** Check for VMX instructions requiring to be in VMX operation.
  * @note Any changes here, check if IEMOP_HLP_IN_VMX_OPERATION needs updating. */
-#define IEM_VMX_IN_VMX_OPERATION(a_pVCpu, a_szInstr, a_InsDiagPrefix) \
+# define IEM_VMX_IN_VMX_OPERATION(a_pVCpu, a_szInstr, a_InsDiagPrefix) \
     do \
     { \
@@ -144,5 +144,5 @@
 
 /** Marks a VM-entry failure with a diagnostic reason, logs and returns. */
-#define IEM_VMX_VMENTRY_FAILED_RET(a_pVCpu, a_pszInstr, a_pszFailure, a_VmxDiag) \
+# define IEM_VMX_VMENTRY_FAILED_RET(a_pVCpu, a_pszInstr, a_pszFailure, a_VmxDiag) \
     do \
     { \
@@ -154,5 +154,5 @@
 
 /** Marks a VM-exit failure with a diagnostic reason, logs and returns. */
-#define IEM_VMX_VMEXIT_FAILED_RET(a_pVCpu, a_uExitReason, a_pszFailure, a_VmxDiag) \
+# define IEM_VMX_VMEXIT_FAILED_RET(a_pVCpu, a_uExitReason, a_pszFailure, a_VmxDiag) \
     do \
     { \
@@ -162,4 +162,22 @@
         return VERR_VMX_VMEXIT_FAILED; \
     } while (0)
+
+/** Enables/disables IEM-only EM execution policy in and from ring-3.   */
+# if defined(VBOX_WITH_NESTED_HWVIRT_ONLY_IN_IEM) && defined(IN_RING3)
+#  define IEM_VMX_R3_EXECPOLICY_IEM_ALL_ENABLE_RET(a_pVCpu, a_pszLogPrefix) \
+    do { \
+        Log(("%s: Enabling IEM-only EM execution policy!\n", (a_pszLogPrefix))); \
+        return EMR3SetExecutionPolicy((a_pVCpu)->CTX_SUFF(pVM)->pUVM, EMEXECPOLICY_IEM_ALL, true); \
+    } while (0)
+
+#  define IEM_VMX_R3_EXECPOLICY_IEM_ALL_DISABLE(a_pVCpu, a_pszLogPrefix) \
+    do { \
+        Log(("%s: Disabling IEM-only EM execution policy!\n", (a_pszLogPrefix))); \
+        EMR3SetExecutionPolicy((a_pVCpu)->CTX_SUFF(pVM)->pUVM, EMEXECPOLICY_IEM_ALL, false); \
+    } while (0)
+# else
+#  define IEM_VMX_R3_EXECPOLICY_IEM_ALL_ENABLE_RET(a_pVCpu, a_pszLogPrefix)     do { return VINF_SUCCESS; } while (0)
+#  define IEM_VMX_R3_EXECPOLICY_IEM_ALL_DISABLE(a_pVCpu, a_pszLogPrefix)        do { } while (0)
+# endif
 
 
@@ -2809,4 +2827,8 @@
 IEM_STATIC VBOXSTRICTRC iemVmxVmexit(PVMCPU pVCpu, uint32_t uExitReason)
 {
+# if defined(VBOX_WITH_NESTED_HWVIRT_ONLY_IN_IEM) && !defined(IN_RING3)
+    RT_NOREF2(pVCpu, uExitReason);
+    return VINF_EM_RAW_EMULATE_INSTR;
+# else
     PVMXVVMCS pVmcs = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs);
     Assert(pVmcs);
@@ -2830,5 +2852,8 @@
         { /* likely */ }
         else
+        {
+            IEM_VMX_R3_EXECPOLICY_IEM_ALL_DISABLE(pVCpu, "VMX-Abort");
             return iemVmxAbort(pVCpu, VMXABORT_SAVE_GUEST_MSRS);
+        }
     }
     else
@@ -2853,5 +2878,7 @@
 
     Assert(rcStrict == VINF_SUCCESS);
+    IEM_VMX_R3_EXECPOLICY_IEM_ALL_DISABLE(pVCpu, "VM-exit");
     return VINF_VMX_VMEXIT;
+# endif
 }
 
@@ -7133,4 +7160,8 @@
 IEM_STATIC VBOXSTRICTRC iemVmxVmlaunchVmresume(PVMCPU pVCpu, uint8_t cbInstr, VMXINSTRID uInstrId, PCVMXVEXITINFO pExitInfo)
 {
+# if defined(VBOX_WITH_NESTED_HWVIRT_ONLY_IN_IEM) && !defined(IN_RING3)
+    RT_NOREF4(pVCpu, cbInstr, uInstrId, pExitInfo);
+    return VINF_EM_RAW_EMULATE_INSTR;
+# else
     Assert(   uInstrId == VMXINSTRID_VMLAUNCH
            || uInstrId == VMXINSTRID_VMRESUME);
@@ -7332,5 +7363,6 @@
     iemVmxVmFail(pVCpu, VMXINSTRERR_VMENTRY_INVALID_CTLS);
     iemRegAddToRipAndClearRF(pVCpu, cbInstr);
-    return VINF_SUCCESS;
+    IEM_VMX_R3_EXECPOLICY_IEM_ALL_ENABLE_RET(pVCpu, pszInstr);
+# endif
 }
 
@@ -7895,9 +7927,11 @@
         rcStrict = PGMPhysSimpleWriteGCPhys(pVCpu->CTX_SUFF(pVM), GCPtrVmcs + RT_UOFFSETOF(VMXVVMCS, fVmcsState),
                                             (const void *)&fVmcsStateClear, sizeof(fVmcsStateClear));
+        if (RT_FAILURE(rcStrict))
+            return rcStrict;
     }
 
     iemVmxVmSucceed(pVCpu);
     iemRegAddToRipAndClearRF(pVCpu, cbInstr);
-    return rcStrict;
+    return VINF_SUCCESS;
 }
 
@@ -8108,8 +8142,4 @@
                                     PCVMXVEXITINFO pExitInfo)
 {
-#if defined(VBOX_WITH_NESTED_HWVIRT_ONLY_IN_IEM) && !defined(IN_RING3)
-    RT_NOREF5(pVCpu, cbInstr, iEffSeg, GCPtrVmxon, pExitInfo);
-    return VINF_EM_RAW_EMULATE_INSTR;
-#else
     if (!IEM_VMX_IS_ROOT_MODE(pVCpu))
     {
@@ -8267,9 +8297,5 @@
         iemVmxVmSucceed(pVCpu);
         iemRegAddToRipAndClearRF(pVCpu, cbInstr);
-# if defined(VBOX_WITH_NESTED_HWVIRT_ONLY_IN_IEM) && defined(IN_RING3)
-        return EMR3SetExecutionPolicy(pVCpu->CTX_SUFF(pVM)->pUVM, EMEXECPOLICY_IEM_ALL, true);
-# else
         return VINF_SUCCESS;
-# endif
     }
     else if (IEM_VMX_IS_NON_ROOT_MODE(pVCpu))
@@ -8296,5 +8322,4 @@
     iemRegAddToRipAndClearRF(pVCpu, cbInstr);
     return VINF_SUCCESS;
-#endif
 }
 
@@ -8308,8 +8333,4 @@
 IEM_CIMPL_DEF_0(iemCImpl_vmxoff)
 {
-# if defined(VBOX_WITH_NESTED_HWVIRT_ONLY_IN_IEM) && !defined(IN_RING3)
-    RT_NOREF2(pVCpu, cbInstr);
-    return VINF_EM_RAW_EMULATE_INSTR;
-# else
     /* Nested-guest intercept. */
     if (IEM_VMX_IS_NON_ROOT_MODE(pVCpu))
@@ -8345,10 +8366,5 @@
     iemVmxVmSucceed(pVCpu);
     iemRegAddToRipAndClearRF(pVCpu, cbInstr);
-#  if defined(VBOX_WITH_NESTED_HWVIRT_ONLY_IN_IEM) && defined(IN_RING3)
-    return EMR3SetExecutionPolicy(pVCpu->CTX_SUFF(pVM)->pUVM, EMEXECPOLICY_IEM_ALL, false);
-#  else
     return VINF_SUCCESS;
-#  endif
-# endif
 }
 
