Index: /trunk/include/VBox/err.h
===================================================================
--- /trunk/include/VBox/err.h	(revision 46654)
+++ /trunk/include/VBox/err.h	(revision 46655)
@@ -1907,6 +1907,4 @@
 /** Undefined VM exit code. */
 #define VERR_VMX_UNDEFINED_EXIT_CODE                (-4019)
-/** Resume guest execution after injecting a double-fault. */
-#define VINF_VMX_DOUBLE_FAULT                       4020
 /** VMPTRLD failed; possibly because of invalid VMCS launch-state. */
 #define VERR_VMX_VMPTRLD_FAILED                     (-4021)
@@ -1979,4 +1977,6 @@
 /** Invalid HM64ON32OP value.  */
 #define VERR_HM_INVALID_HM64ON32OP                  (-4116)
+/** Resume guest execution after injecting a double-fault. */
+#define VINF_HM_DOUBLE_FAULT                        4117
 /** @} */
 
Index: /trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp	(revision 46654)
+++ /trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp	(revision 46655)
@@ -4750,5 +4750,5 @@
  * @returns VBox status code (informational error codes included).
  * @retval VINF_SUCCESS if we should continue handling the VM-exit.
- * @retval VINF_VMX_DOUBLE_FAULT if a #DF condition was detected and we ought to
+ * @retval VINF_HM_DOUBLE_FAULT if a #DF condition was detected and we ought to
  *         continue execution of the guest which will delivery the #DF.
  * @retval VINF_EM_RESET if we detected a triple-fault condition.
@@ -4785,37 +4785,49 @@
         /* See Intel spec. 30.7.1.1 "Reflecting Exceptions to Guest Software". */
         VMXREFLECTXCPT enmReflect = VMXREFLECTXCPT_NONE;
-        if (uIntType == VMX_IDT_VECTORING_INFO_TYPE_HW_XCPT)
-        {
-            enmReflect = VMXREFLECTXCPT_XCPT;
+        if (VMX_EXIT_INTERRUPTION_INFO_IS_VALID(pVmxTransient->uExitIntrInfo))
+        {
+            if (uIntType == VMX_IDT_VECTORING_INFO_TYPE_HW_XCPT)
+            {
+                enmReflect = VMXREFLECTXCPT_XCPT;
 #ifdef VBOX_STRICT
-            if (   hmR0VmxIsContributoryXcpt(uIdtVector)
-                && uExitVector == X86_XCPT_PF)
+                if (   hmR0VmxIsContributoryXcpt(uIdtVector)
+                    && uExitVector == X86_XCPT_PF)
+                {
+                    Log4(("IDT: Contributory #PF uCR2=%#RX64\n", pMixedCtx->cr2));
+                }
+#endif
+                if (   uExitVector == X86_XCPT_PF
+                    && uIdtVector == X86_XCPT_PF)
+                {
+                    pVmxTransient->fVectoringPF = true;
+                    Log4(("IDT: Vectoring #PF uCR2=%#RX64\n", pMixedCtx->cr2));
+                }
+                else if (   (pVCpu->hm.s.vmx.u32XcptBitmap & HMVMX_CONTRIBUTORY_XCPT_MASK)
+                         && hmR0VmxIsContributoryXcpt(uExitVector)
+                         && (   hmR0VmxIsContributoryXcpt(uIdtVector)
+                             || uIdtVector == X86_XCPT_PF))
+                {
+                    enmReflect = VMXREFLECTXCPT_DF;
+                }
+                else if (uIdtVector == X86_XCPT_DF)
+                    enmReflect = VMXREFLECTXCPT_TF;
+            }
+            else if (   uIntType != VMX_IDT_VECTORING_INFO_TYPE_SW_INT
+                     && uIntType != VMX_IDT_VECTORING_INFO_TYPE_SW_XCPT
+                     && uIntType != VMX_IDT_VECTORING_INFO_TYPE_PRIV_SW_XCPT)
             {
-                Log4(("IDT: Contributory #PF uCR2=%#RX64\n", pMixedCtx->cr2));
+                /*
+                 * Ignore software interrupts (INT n), software exceptions (#BP, #OF) and privileged software exception
+                 * (whatever they are) as they reoccur when restarting the instruction.
+                 */
+                enmReflect = VMXREFLECTXCPT_XCPT;
             }
-#endif
-            if (   uExitVector == X86_XCPT_PF
-                && uIdtVector == X86_XCPT_PF)
-            {
-                pVmxTransient->fVectoringPF = true;
-                Log4(("IDT: Vectoring #PF uCR2=%#RX64\n", pMixedCtx->cr2));
-            }
-            else if (   (pVCpu->hm.s.vmx.u32XcptBitmap & HMVMX_CONTRIBUTORY_XCPT_MASK)
-                     && hmR0VmxIsContributoryXcpt(uExitVector)
-                     && (   hmR0VmxIsContributoryXcpt(uIdtVector)
-                         || uIdtVector == X86_XCPT_PF))
-            {
-                enmReflect = VMXREFLECTXCPT_DF;
-            }
-            else if (uIdtVector == X86_XCPT_DF)
-                enmReflect = VMXREFLECTXCPT_TF;
-        }
-        else if (   uIntType != VMX_IDT_VECTORING_INFO_TYPE_SW_INT
-                 && uIntType != VMX_IDT_VECTORING_INFO_TYPE_SW_XCPT
-                 && uIntType != VMX_IDT_VECTORING_INFO_TYPE_PRIV_SW_XCPT)
+        }
+        else
         {
             /*
-             * Ignore software interrupts (INT n), software exceptions (#BP, #OF) and privileged software exception
-             * (whatever they are) as they reoccur when restarting the instruction.
+             * If event delivery caused an EPT violation/misconfig or APIC access VM-exit, then the VM-exit
+             * interruption-information will not be valid and we end up here. In such cases, it is sufficient to reflect the
+             * original exception to the guest after handling the VM-exit.
              */
             enmReflect = VMXREFLECTXCPT_XCPT;
@@ -4839,5 +4851,5 @@
                 rc = VINF_SUCCESS;
                 Log4(("IDT: Pending vectoring event %#RX64 Err=%#RX32\n", pVCpu->hm.s.Event.u64IntrInfo,
-                     pVCpu->hm.s.Event.u32ErrCode));
+                      pVCpu->hm.s.Event.u32ErrCode));
                 break;
             }
@@ -4846,7 +4858,7 @@
             {
                 hmR0VmxSetPendingXcptDF(pVCpu, pMixedCtx);
-                rc = VINF_VMX_DOUBLE_FAULT;
+                rc = VINF_HM_DOUBLE_FAULT;
                 Log4(("IDT: Pending vectoring #DF %#RX64 uIdtVector=%#x uExitVector=%#x\n", pVCpu->hm.s.Event.u64IntrInfo,
-                     uIdtVector, uExitVector));
+                      uIdtVector, uExitVector));
                 break;
             }
@@ -4854,6 +4866,6 @@
             case VMXREFLECTXCPT_TF:
             {
+                rc = VINF_EM_RESET;
                 Log4(("IDT: Pending vectoring triple-fault uIdt=%#x uExit=%#x\n", uIdtVector, uExitVector));
-                rc = VINF_EM_RESET;
                 break;
             }
@@ -4864,5 +4876,5 @@
         }
     }
-    Assert(rc == VINF_SUCCESS || rc == VINF_VMX_DOUBLE_FAULT || rc == VINF_EM_RESET);
+    Assert(rc == VINF_SUCCESS || rc == VINF_HM_DOUBLE_FAULT || rc == VINF_EM_RESET);
     return rc;
 }
@@ -7237,5 +7249,5 @@
     /* If this VM-exit occurred while delivering an event through the guest IDT, handle it accordingly. */
     rc = hmR0VmxCheckExitDueToEventDelivery(pVCpu, pMixedCtx, pVmxTransient);
-    if (RT_UNLIKELY(rc == VINF_VMX_DOUBLE_FAULT))
+    if (RT_UNLIKELY(rc == VINF_HM_DOUBLE_FAULT))
     {
         STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExitXcptNmi, y3);
@@ -8400,5 +8412,5 @@
     /* If this VM-exit occurred while delivering an event through the guest IDT, handle it accordingly. */
     int rc = hmR0VmxCheckExitDueToEventDelivery(pVCpu, pMixedCtx, pVmxTransient);
-    if (RT_UNLIKELY(rc == VINF_VMX_DOUBLE_FAULT))
+    if (RT_UNLIKELY(rc == VINF_HM_DOUBLE_FAULT))
         return VINF_SUCCESS;
     else if (RT_UNLIKELY(rc == VINF_EM_RESET))
@@ -8554,5 +8566,5 @@
     /* If this VM-exit occurred while delivering an event through the guest IDT, handle it accordingly. */
     int rc = hmR0VmxCheckExitDueToEventDelivery(pVCpu, pMixedCtx, pVmxTransient);
-    if (RT_UNLIKELY(rc == VINF_VMX_DOUBLE_FAULT))
+    if (RT_UNLIKELY(rc == VINF_HM_DOUBLE_FAULT))
         return VINF_SUCCESS;
     else if (RT_UNLIKELY(rc == VINF_EM_RESET))
@@ -8607,5 +8619,5 @@
     /* If this VM-exit occurred while delivering an event through the guest IDT, handle it accordingly. */
     int rc = hmR0VmxCheckExitDueToEventDelivery(pVCpu, pMixedCtx, pVmxTransient);
-    if (RT_UNLIKELY(rc == VINF_VMX_DOUBLE_FAULT))
+    if (RT_UNLIKELY(rc == VINF_HM_DOUBLE_FAULT))
         return VINF_SUCCESS;
     else if (RT_UNLIKELY(rc == VINF_EM_RESET))
@@ -9089,16 +9101,14 @@
     if (pVM->hm.s.fNestedPaging)
     {
+        pVCpu->hm.s.Event.fPending = false;                  /* In case it's a contributory or vectoring #PF. */
         if (RT_LIKELY(!pVmxTransient->fVectoringPF))
         {
-            pVCpu->hm.s.Event.fPending = false;                  /* In case it's a contributory #PF. */
             pMixedCtx->cr2 = pVmxTransient->uExitQualification;  /* Update here in case we go back to ring-3 before injection. */
             hmR0VmxSetPendingEvent(pVCpu, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo),
                                    0 /* cbInstr */, pVmxTransient->uExitIntrErrorCode, pVmxTransient->uExitQualification);
-            STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestPF);
         }
         else
         {
             /* A guest page-fault occurred during delivery of a page-fault. Inject #DF. */
-            pVCpu->hm.s.Event.fPending = false;     /* A vectoring #PF. */
             hmR0VmxSetPendingXcptDF(pVCpu, pMixedCtx);
             Log4(("Pending #DF due to vectoring #PF. NP\n"));
@@ -9149,5 +9159,5 @@
             /* A guest page-fault occurred during delivery of a page-fault. Inject #DF. */
             TRPMResetTrap(pVCpu);
-            pVCpu->hm.s.Event.fPending = false;     /* Clear pending #PF for replace it with #DF. */
+            pVCpu->hm.s.Event.fPending = false;     /* Clear pending #PF to replace it with #DF. */
             hmR0VmxSetPendingXcptDF(pVCpu, pMixedCtx);
             Log4(("#PF: Pending #DF due to vectoring #PF\n"));
