Index: /trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAll.cpp	(revision 37012)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAll.cpp	(revision 37013)
@@ -4528,9 +4528,44 @@
     if (   pOrgCtx->eflags.Bits.u1IF
         && TRPMHasTrap(pVCpu)
-        //&& TRPMIsSoftwareInterrupt(pVCpu)
         && EMGetInhibitInterruptsPC(pVCpu) != pOrgCtx->rip)
     {
-        Log(("Injecting trap %#x\n", TRPMGetTrapNo(pVCpu)));
-        iemCImpl_int(pIemCpu, 0, TRPMGetTrapNo(pVCpu), false);
+        uint8_t     u8TrapNo;
+        TRPMEVENT   enmType;
+        RTGCUINT    uErrCode;
+        RTGCPTR     uCr2;
+        int rc2 = TRPMQueryTrapAll(pVCpu, &u8TrapNo, &enmType, &uErrCode, &uCr2); AssertRC(rc2);
+        Log(("Injecting trap %#x\n", u8TrapNo));
+
+        uint32_t    fFlags;
+        switch (enmType)
+        {
+            case TRPM_HARDWARE_INT:
+                fFlags = IEM_XCPT_FLAGS_T_EXT_INT;
+                uErrCode = uCr2 = 0;
+                break;
+            case TRPM_SOFTWARE_INT:
+                fFlags = IEM_XCPT_FLAGS_T_SOFT_INT;
+                uErrCode = uCr2 = 0;
+                break;
+            case TRPM_TRAP:
+                fFlags = IEM_XCPT_FLAGS_T_CPU_XCPT;
+                if (u8TrapNo == X86_XCPT_PF)
+                    fFlags |= IEM_XCPT_FLAGS_CR2;
+                switch (u8TrapNo)
+                {
+                    case X86_XCPT_DF:
+                    case X86_XCPT_TS:
+                    case X86_XCPT_NP:
+                    case X86_XCPT_SS:
+                    case X86_XCPT_PF:
+                    case X86_XCPT_AC:
+                        fFlags |= IEM_XCPT_FLAGS_ERR;
+                        break;
+                }
+                TRPMHasTrap(pVCpu)
+                break;
+            IEM_NOT_REACHED_DEFAULT_CASE_RET();
+        }
+        iemCImpl_RaiseXcptOrInt(pIemCpu, 0, u8TrapNo, fFlags, (uint16_t)uErrCode, uCr2);
         if (!IEM_VERIFICATION_ENABLED(pIemCpu))
             TRPMResetTrap(pVCpu);
Index: /trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h	(revision 37012)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h	(revision 37013)
@@ -1115,11 +1115,54 @@
 
 
-/**
- * Implements int3 and int XX.
- *
- * @param   u8Int       The interrupt vector number.
- * @param   fIsBpInstr  Is it the breakpoint instruction.
- */
-IEM_CIMPL_DEF_2(iemCImpl_int, uint8_t, u8Int, bool, fIsBpInstr)
+/** @name IEM_XCPT_FLAGS_XXX - flags for iemCImpl_RaiseXcptOrInt.
+ * @{ */
+/** CPU exception. */
+#define IEM_XCPT_FLAGS_T_CPU_XCPT       RT_BIT_32(0)
+/** External interrupt (from PIC, APIC, whatever). */
+#define IEM_XCPT_FLAGS_T_EXT_INT        RT_BIT_32(1)
+/** Software interrupt (int, into or bound). */
+#define IEM_XCPT_FLAGS_T_SOFT_INT       RT_BIT_32(2)
+/** Takes an error code. */
+#define IEM_XCPT_FLAGS_ERR              RT_BIT_32(3)
+/** Takes a CR2. */
+#define IEM_XCPT_FLAGS_CR2              RT_BIT_32(4)
+/** Generated by the breakpoint instruction. */
+#define IEM_XCPT_FLAGS_BP_INSTR         RT_BIT_32(5)
+/** Mask out the nesting level. */
+#define IEM_XCPT_FLAGS_NESTING_MASK     UINT32_C(0xff000000)
+/** Shift count for the nesting level. */
+#define IEM_XCPT_FLAGS_NESTING_SHIFT    24
+/** Mask out the nesting level after shifting. */
+#define IEM_XCPT_FLAGS_NESTING_SMASK    UINT32_C(0x000000ff)
+/** @}  */
+
+
+static VBOXSTRICTRC
+iemCImpl_RaiseXcptOrIntAgain(PIEMCPU     pIemCpu,
+                             uint8_t     u8Vector,
+                             uint32_t    fFlags,
+                             uint16_t    uErr,
+                             uint64_t    uCr2,
+                             uint8_t     u8PrevVector);
+
+/**
+ * Implements exceptions and interrupts.
+ *
+ * @returns VBox strict status code.
+ * @param   pIemCpu         The IEM per CPU instance data.
+ * @param   cbInstr         The number of bytes to offset rIP by in the return
+ *                          address.
+ * @param   u8Vector        The interrupt / exception vector number.
+ * @param   fFlags          The flags.
+ * @param   uErr            The error value if IEM_XCPT_FLAGS_ERR is set.
+ * @param   uCr2            The CR2 value if IEM_XCPT_FLAGS_CR2 is set.
+ */
+static VBOXSTRICTRC
+iemCImpl_RaiseXcptOrInt(PIEMCPU     pIemCpu,
+                        uint8_t     cbInstr,
+                        uint8_t     u8Vector,
+                        uint32_t    fFlags,
+                        uint16_t    uErr,
+                        uint64_t    uCr2)
 {
     /** @todo we should call TRPM to do this job.  */
@@ -1134,8 +1177,14 @@
     {
         /* read the IDT entry. */
-        if (pCtx->idtr.cbIdt < UINT32_C(4) * u8Int + 3)
-            return iemRaiseGeneralProtectionFault(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Int << X86_TRAP_ERR_SEL_SHIFT));
+        if (pCtx->idtr.cbIdt < UINT32_C(4) * u8Vector + 3)
+            return iemCImpl_RaiseXcptOrIntAgain(pIemCpu,
+                                                X86_XCPT_GP,
+                                                IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR
+                                                | (fFlags & IEM_XCPT_FLAGS_NESTING_MASK),
+                                                X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT),
+                                                0,
+                                                u8Vector);
         RTFAR16 Idte;
-        rcStrict = iemMemFetchDataU32(pIemCpu, (uint32_t *)&Idte, UINT8_MAX, pCtx->idtr.pIdt + UINT32_C(4) * u8Int);
+        rcStrict = iemMemFetchDataU32(pIemCpu, (uint32_t *)&Idte, UINT8_MAX, pCtx->idtr.pIdt + UINT32_C(4) * u8Vector);
         if (RT_UNLIKELY(rcStrict != VINF_SUCCESS))
             return rcStrict;
@@ -1164,6 +1213,50 @@
     }
 
+    /*
+     * continue here...
+     */
     AssertFailed();
     return VERR_NOT_IMPLEMENTED;
+}
+
+
+/**
+ * Deals with exceptions occuring while dispatching an exception or interrupt.
+ *
+ * @returns VBox strict status code.
+ * @param   pIemCpu         The IEM per CPU instance data.
+ * @param   u8Vector        The exception vector number.
+ * @param   fFlags          The flags.
+ * @param   uErr            The error value if IEM_XCPT_FLAGS_ERR is set.
+ * @param   uCr2            The CR2 value if IEM_XCPT_FLAGS_CR2 is set.
+ * @param   u8PrevVector    The exception we tried raising.
+ */
+static VBOXSTRICTRC
+iemCImpl_RaiseXcptOrIntAgain(PIEMCPU     pIemCpu,
+                             uint8_t     u8Vector,
+                             uint32_t    fFlags,
+                             uint16_t    uErr,
+                             uint64_t    uCr2,
+                             uint8_t     u8PrevVector)
+{
+    return iemCImpl_RaiseXcptOrInt(pIemCpu, 0, u8Vector, fFlags, uErr, uCr2);
+}
+
+
+
+/**
+ * Implements int3 and int XX.
+ *
+ * @param   u8Int       The interrupt vector number.
+ * @param   fIsBpInstr  Is it the breakpoint instruction.
+ */
+IEM_CIMPL_DEF_2(iemCImpl_int, uint8_t, u8Int, bool, fIsBpInstr)
+{
+    return iemCImpl_RaiseXcptOrInt(pIemCpu,
+                                   cbInstr,
+                                   u8Int,
+                                   (fIsBpInstr ? IEM_XCPT_FLAGS_BP_INSTR : 0) | IEM_XCPT_FLAGS_T_SOFT_INT,
+                                   0,
+                                   0);
 }
 
