Index: /trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp	(revision 45531)
+++ /trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp	(revision 45532)
@@ -4985,5 +4985,5 @@
                || uIntrState == VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_MOVSS);
         rc  = hmR0VmxSaveGuestRip(pVCpu, pMixedCtx);
-        rc |= hmR0VmxSaveGuestRflags(pVCpu, pMixedCtx);    /* for hmR0VmxLoadGuestIntrState(). */
+        rc |= hmR0VmxSaveGuestRflags(pVCpu, pMixedCtx);    /* for hmR0VmxGetGuestIntrState(). */
         AssertRC(rc);
         EMSetInhibitInterruptsPC(pVCpu, pMixedCtx->rip);
@@ -5558,9 +5558,11 @@
 
 /**
- * Converts any TRPM trap into a pending VMX event.
+ * Converts any TRPM trap into a pending VMX event. This is typically used when
+ * entering from ring-3 (not longjmp returns).
  *
  * @param   pVCpu           Pointer to the VMCPU.
- */
-static void hmR0VmxUpdatePendingEvent(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
+ * @param   pCtx            Pointer to the guest-CPU context.
+ */
+static void hmR0VmxUpdatePendingEvent(PVMCPU pVCpu, PCPUMCTX pCtx)
 {
     if (!TRPMHasTrap(pVCpu))
@@ -5606,5 +5608,5 @@
                 u32IntrInfo |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_HW_XCPT << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT);
                 if (uVector == X86_XCPT_PF)
-                    pMixedCtx->cr2 = TRPMGetFaultAddress(pVCpu);
+                    pCtx->cr2 = TRPMGetFaultAddress(pVCpu);
                 break;
             }
@@ -5624,4 +5626,5 @@
 
     rc = TRPMResetTrap(pVCpu);
+    AssertRC(rc);
     Log(("Converted TRPM trap: u32IntrInfo=%#RX32 enmTrpmEvent=%d cbInstr=%u u32ErrCode=%#RX32 GCPtrFaultAddress=%#RGv\n",
          u32IntrInfo, enmTrpmEvent, u32ErrCode, GCPtrFaultAddress));
@@ -5636,5 +5639,5 @@
  * @param   pvCpu           Pointer to the VMCPU.
  */
-static void hmR0VmxUpdateTRPMTrap(PVMCPU pVCpu)
+static void hmR0VmxUpdateTRPM(PVMCPU pVCpu)
 {
     if (pVCpu->hm.s.Event.fPending)
@@ -5670,10 +5673,9 @@
 
         Log(("Converting pending HM event to TRPM trap uVector=%#x enmTrapType=%d\n", uVector, enmTrapType));
-
         int rc = TRPMAssertTrap(pVCpu, uVector, enmTrapType);
         AssertRC(rc);
+
         if (fErrorCodeValid)
             TRPMSetErrorCode(pVCpu, uErrorCode);
-
         /* A page-fault exception during a page-fault would become a double-fault. */
         if (   uVectorType == VMX_IDT_VECTORING_INFO_TYPE_HW_XCPT
@@ -5780,5 +5782,5 @@
 
     /* We need to do this only while truly exiting the "inner loop" back to ring-3 and -not- for any longjmp to ring3. */
-    hmR0VmxUpdateTRPMTrap(pVCpu);
+    hmR0VmxUpdateTRPM(pVCpu);
 
     /* Sync. the guest state. */
@@ -5856,6 +5858,6 @@
 
 /**
- * Checks if there are any pending guest interrupts to be delivered and injects
- * them into the VM by updating the VMCS.
+ * Injects any pending events into the guest if the guest is in a state to
+ * receive them.
  *
  * @returns VBox status code (informational status codes included).
@@ -5958,5 +5960,7 @@
      * VT-x clears the valid bit on every VM-exit. See Intel spec. 24.8.3 "VM-Entry Controls for Event Injection".
      */
-    hmR0VmxLoadGuestIntrState(pVCpu, uIntrState);
+    int rc2 = hmR0VmxLoadGuestIntrState(pVCpu, uIntrState);
+    AssertRC(rc2);
+    Assert(rc == VINF_SUCCESS || rc == VINF_EM_RESET);
     return rc;
 }
@@ -5973,5 +5977,4 @@
 DECLINLINE(void) hmR0VmxSetPendingXcptUD(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 {
-    /* Refer Intel spec. 24.8.3 "VM-entry Controls for Event Injection" for the format of u32IntrInfo. */
     uint32_t u32IntrInfo = X86_XCPT_UD | (1 << VMX_EXIT_INTERRUPTION_INFO_VALID_SHIFT);
     STAM_COUNTER_INC(&pVCpu->hm.s.StatIntInject);
@@ -6144,4 +6147,7 @@
  *                          exceptions).
  * @param   u32ErrCode      The VM-entry exception error code.
+ * @param   puIntrState     Pointer to the current guest interruptibility-state.
+ *                          This interruptibility-state will be updated if
+ *                          necessary. This cannot not be NULL.
  *
  * @remarks No-long-jump zone!!!
@@ -6162,6 +6168,4 @@
     Assert(   uIntrType != VMX_EXIT_INTERRUPTION_INFO_TYPE_NMI
            || !((*puIntrState) & VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_MOVSS));
-
-    STAM_COUNTER_INC(&pVCpu->hm.s.paStatInjectedIrqsR0[uVector & MASK_INJECT_IRQ_STAT]);
 
     /* We require CR0 to check if the guest is in real-mode. */
@@ -6268,9 +6272,10 @@
     }
 
-    /* Add the valid bit, maybe the caller was lazy. */
-    u32IntrInfo |= (1 << VMX_EXIT_INTERRUPTION_INFO_VALID_SHIFT);
-
+    /* Validate. */
+    Assert(VMX_EXIT_INTERRUPTION_INFO_VALID(u32IntrInfo));              /* Bit 31 (Valid bit) must be set by caller. */
     Assert(!VMX_EXIT_INTERRUPTION_INFO_NMI_UNBLOCK(u32IntrInfo));       /* Bit 12 MBZ. */
     Assert(!(u32IntrInfo & 0x7ffff000));                                /* Bits 30:12 MBZ. */
+
+    /* Inject. */
     Log(("Injecting u32IntrInfo=%#x u32ErrCode=%#x instrlen=%#x\n", u32IntrInfo, u32ErrCode, cbInstr));
     rc  = VMXWriteVmcs32(VMX_VMCS32_CTRL_ENTRY_INTERRUPTION_INFO, u32IntrInfo);
@@ -6279,6 +6284,4 @@
     rc |= VMXWriteVmcs32(VMX_VMCS32_CTRL_ENTRY_INSTR_LENGTH, cbInstr);
     AssertRCReturn(rc, rc);
-
-    Assert(uIntrType != VMX_EXIT_INTERRUPTION_INFO_TYPE_SW_INT);
     return rc;
 }
