Index: /trunk/include/VBox/vmm/cpum.h
===================================================================
--- /trunk/include/VBox/vmm/cpum.h	(revision 74833)
+++ /trunk/include/VBox/vmm/cpum.h	(revision 74834)
@@ -1877,16 +1877,16 @@
 
 /**
- * Checks whether the given Pin-based VM-execution controls are set when executing a
- * nested-guest.
+ * Checks whether one of the given Pin-based VM-execution controls are set when
+ * executing a nested-guest.
  *
  * @returns @c true if set, @c false otherwise.
  * @param   pVCpu       The cross context virtual CPU structure of the calling EMT.
  * @param   pCtx        Pointer to the context.
- * @param   uPinCtl     The Pin-based VM-execution controls to check.
+ * @param   uPinCtls    The Pin-based VM-execution controls to check.
  *
  * @remarks This does not check if all given controls are set if more than one
  *          control is passed in @a uPinCtl.
  */
-DECLINLINE(bool) CPUMIsGuestVmxPinCtlsSet(PVMCPU pVCpu, PCCPUMCTX pCtx, uint32_t uPinCtl)
+DECLINLINE(bool) CPUMIsGuestVmxPinCtlsSet(PVMCPU pVCpu, PCCPUMCTX pCtx, uint32_t uPinCtls)
 {
     RT_NOREF(pVCpu);
@@ -1894,20 +1894,20 @@
     Assert(pCtx->hwvirt.vmx.fInVmxNonRootMode);
     Assert(pCtx->hwvirt.vmx.CTX_SUFF(pVmcs));
-    return RT_BOOL(pCtx->hwvirt.vmx.CTX_SUFF(pVmcs)->u32PinCtls & uPinCtl);
-}
-
-/**
- * Checks whether the given Processor-based VM-execution controls are set when
- * executing a nested-guest.
+    return RT_BOOL(pCtx->hwvirt.vmx.CTX_SUFF(pVmcs)->u32PinCtls & uPinCtls);
+}
+
+/**
+ * Checks whether one of the given Processor-based VM-execution controls are set
+ * when executing a nested-guest.
  *
  * @returns @c true if set, @c false otherwise.
  * @param   pVCpu       The cross context virtual CPU structure of the calling EMT.
  * @param   pCtx        Pointer to the context.
- * @param   uProcCtl    The Processor-based VM-execution controls to check.
+ * @param   uProcCtls   The Processor-based VM-execution controls to check.
  *
  * @remarks This does not check if all given controls are set if more than one
  *          control is passed in @a uProcCtls.
  */
-DECLINLINE(bool) CPUMIsGuestVmxProcCtlsSet(PVMCPU pVCpu, PCCPUMCTX pCtx, uint32_t uProcCtl)
+DECLINLINE(bool) CPUMIsGuestVmxProcCtlsSet(PVMCPU pVCpu, PCCPUMCTX pCtx, uint32_t uProcCtls)
 {
     RT_NOREF(pVCpu);
@@ -1915,22 +1915,21 @@
     Assert(pCtx->hwvirt.vmx.fInVmxNonRootMode);
     Assert(pCtx->hwvirt.vmx.CTX_SUFF(pVmcs));
-    return RT_BOOL(pCtx->hwvirt.vmx.CTX_SUFF(pVmcs)->u32ProcCtls & uProcCtl);
-}
-
-/**
- * Checks whether the given Secondary Processor-based VM-execution controls are set
- * when executing a nested-guest.
+    return RT_BOOL(pCtx->hwvirt.vmx.CTX_SUFF(pVmcs)->u32ProcCtls & uProcCtls);
+}
+
+/**
+ * Checks whether one of the given Secondary Processor-based VM-execution controls
+ * are set when executing a nested-guest.
  *
  * @returns @c true if set, @c false otherwise.
  * @param   pVCpu       The cross context virtual CPU structure of the calling EMT.
  * @param   pCtx        Pointer to the context.
- * @param   uProcCtl2   The Secondary Processor-based VM-execution controls to
+ * @param   uProcCtls2  The Secondary Processor-based VM-execution controls to
  *                      check.
  *
  * @remarks This does not check if all given controls are set if more than one
- *          control is passed in @a uProcCtl2.
- *
- */
-DECLINLINE(bool) CPUMIsGuestVmxProcCtls2Set(PVMCPU pVCpu, PCCPUMCTX pCtx, uint32_t uProcCtl2)
+ *          control is passed in @a uProcCtls2.
+ */
+DECLINLINE(bool) CPUMIsGuestVmxProcCtls2Set(PVMCPU pVCpu, PCCPUMCTX pCtx, uint32_t uProcCtls2)
 {
     RT_NOREF(pVCpu);
@@ -1938,5 +1937,27 @@
     Assert(pCtx->hwvirt.vmx.fInVmxNonRootMode);
     Assert(pCtx->hwvirt.vmx.CTX_SUFF(pVmcs));
-    return RT_BOOL(pCtx->hwvirt.vmx.CTX_SUFF(pVmcs)->u32ProcCtls2 & uProcCtl2);
+    return RT_BOOL(pCtx->hwvirt.vmx.CTX_SUFF(pVmcs)->u32ProcCtls2 & uProcCtls2);
+}
+
+
+/**
+ * Checks whether one of the given VM-exit controls are set when executing a
+ * nested-guest.
+ *
+ * @returns @c true if set, @c false otherwise.
+ * @param   pVCpu       The cross context virtual CPU structure of the calling EMT.
+ * @param   pCtx        Pointer to the context.
+ * @param   uExitCtls   The VM-exit controls to check.
+ *
+ * @remarks This does not check if all given controls are set if more than one
+ *          control is passed in @a uExitCtls.
+ */
+DECLINLINE(bool) CPUMIsGuestVmxExitCtlsSet(PVMCPU pVCpu, PCCPUMCTX pCtx, uint32_t uExitCtls)
+{
+    RT_NOREF(pVCpu);
+    Assert(pCtx->hwvirt.enmHwvirt == CPUMHWVIRT_VMX);
+    Assert(pCtx->hwvirt.vmx.fInVmxNonRootMode);
+    Assert(pCtx->hwvirt.vmx.CTX_SUFF(pVmcs));
+    return RT_BOOL(pCtx->hwvirt.vmx.CTX_SUFF(pVmcs)->u32ExitCtls & uExitCtls);
 }
 
Index: /trunk/include/VBox/vmm/iem.h
===================================================================
--- /trunk/include/VBox/vmm/iem.h	(revision 74833)
+++ /trunk/include/VBox/vmm/iem.h	(revision 74834)
@@ -323,4 +323,5 @@
 
 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX
+VMM_INT_DECL(VBOXSTRICTRC)  IEMExecVmxVmexitExtInt(PVMCPU pVCpu, uint8_t uVector, bool fIntPending);
 VMM_INT_DECL(VBOXSTRICTRC)  IEMExecDecodedVmread(PVMCPU pVCpu, PCVMXVEXITINFO pExitInfo);
 VMM_INT_DECL(VBOXSTRICTRC)  IEMExecDecodedVmwrite(PVMCPU pVCpu, PCVMXVEXITINFO pExitInfo);
Index: /trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAll.cpp	(revision 74833)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAll.cpp	(revision 74834)
@@ -978,4 +978,5 @@
                                               uint8_t cbInstr);
 IEM_STATIC VBOXSTRICTRC     iemVmxVmexitTripleFault(PVMCPU pVCpu);
+IEM_STATIC VBOXSTRICTRC     iemVmxVmexitExtInt(PVMCPU pVCpu, uint8_t uVector, bool fIntPending);
 #endif
 
@@ -13892,4 +13893,10 @@
             int32_t const rcPassUp = pVCpu->iem.s.rcPassUp;
 #ifdef VBOX_WITH_NESTED_HWVIRT_SVM
+            if (   rcStrict == VINF_VMX_VMEXIT
+                && rcPassUp == VINF_SUCCESS)
+                rcStrict = VINF_SUCCESS;
+            else
+#endif
+#ifdef VBOX_WITH_NESTED_HWVIRT_SVM
             if (   rcStrict == VINF_SVM_VMEXIT
                 && rcPassUp == VINF_SUCCESS)
@@ -15632,4 +15639,24 @@
 
 /**
+ * Interface for HM and EM to emulate VM-exit due to external interrupts.
+ *
+ * @returns Strict VBox status code.
+ * @param   pVCpu           The cross context virtual CPU structure of the calling EMT.
+ * @param   uVector         The external interrupt vector.
+ * @param   fIntPending     Whether the external interrupt is pending or
+ *                          acknowdledged in the interrupt controller.
+ * @thread  EMT(pVCpu)
+ */
+VMM_INT_DECL(VBOXSTRICTRC) IEMExecVmxVmexitExtInt(PVMCPU pVCpu, uint8_t uVector, bool fIntPending)
+{
+    /* IEM_CTX_ASSERT(pVCpu, IEM_CPUMCTX_EXTRN_SVM_VMEXIT_MASK); */ /** @todo NSTVMX: VMX_EXIT_MASK */
+    VBOXSTRICTRC rcStrict = iemVmxVmexitExtInt(pVCpu, uVector, fIntPending);
+    if (pVCpu->iem.s.cActiveMappings)
+        iemMemRollback(pVCpu);
+    return iemExecStatusCodeFiddling(pVCpu, rcStrict);
+}
+
+
+/**
  * Interface for HM and EM to emulate the VMREAD instruction.
  *
Index: /trunk/src/VBox/VMM/VMMR3/TRPM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/TRPM.cpp	(revision 74833)
+++ /trunk/src/VBox/VMM/VMMR3/TRPM.cpp	(revision 74834)
@@ -1519,4 +1519,17 @@
     if (RT_SUCCESS(rc))
     {
+#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
+        /* Handle the "acknowledge interrupt on exit" VM-exit intercept. */
+        if (CPUMIsGuestInVmxNonRootMode(pCtx))
+        {
+            if (   CPUMIsGuestVmxExitCtlsSet(pVCpu, pCtx, VMX_EXIT_CTLS_ACK_EXT_INT)
+                && CPUMIsGuestVmxPinCtlsSet(pVCpu, pCtx, VMX_PIN_CTLS_EXT_INT_EXIT))
+            {
+                VBOXSTRICTRC rcStrict = IEMExecVmxVmexitExtInt(pVCpu, u8Interrupt, false /* fIntPending */);
+                if (rcStrict != VINF_VMX_INTERCEPT_NOT_ACTIVE)
+                    return rcStrict;
+            }
+        }
+#endif
         if (EMIsSupervisorCodeRecompiled(pVM) || !VM_IS_RAW_MODE_ENABLED(pVM))
         {
