Index: /trunk/src/VBox/VMM/EM.cpp
===================================================================
--- /trunk/src/VBox/VMM/EM.cpp	(revision 346)
+++ /trunk/src/VBox/VMM/EM.cpp	(revision 347)
@@ -2058,4 +2058,21 @@
                 break;
             }
+            uint8_t u8Interrupt;
+
+            Assert(TRPMHasTrap(pVM));
+            Assert(!PATMIsPatchGCAddr(pVM, (RTGCPTR)pCtx->eip));
+
+            if (TRPMHasTrap(pVM))
+            {
+                u8Interrupt = TRPMGetTrapNo(pVM);
+
+                /* If the guest gate is marked unpatched, then we will check again if we can patch it. */
+                if (TRPMR3GetGuestTrapHandler(pVM, u8Interrupt) == TRPM_INVALID_HANDLER)
+                {
+                    CSAMR3CheckGates(pVM, u8Interrupt, 1);
+                    Log(("emR3RawHandleRC: recheck gate %x -> valid=%d\n", u8Interrupt, TRPMR3GetGuestTrapHandler(pVM, u8Interrupt) != TRPM_INVALID_HANDLER));
+                    /** @note If it was successful, then we could go back to raw mode, but let's keep things simple for now. */
+                }
+            }
             rc = emR3RawGuestTrap(pVM);
             break;
@@ -2135,4 +2152,5 @@
          */
         case VINF_EM_RAW_INTERRUPT_PENDING:
+        case VINF_EM_RAW_RING_SWITCH_INT:
         {
             uint8_t u8Interrupt;
@@ -2145,8 +2163,7 @@
                 u8Interrupt = TRPMGetTrapNo(pVM);
 
-                /* If the guest gate is marked dirty, then we will check again if we can patch it. */
-                if (TRPMR3IsGuestTrapHandlerDirty(pVM, u8Interrupt))
+                /* If the guest gate is marked unpatched, then we will check again if we can patch it. */
+                if (TRPMR3GetGuestTrapHandler(pVM, u8Interrupt) == TRPM_INVALID_HANDLER)
                 {
-                    Assert(TRPMR3GetGuestTrapHandler(pVM, u8Interrupt) == TRPM_INVALID_HANDLER);
                     CSAMR3CheckGates(pVM, u8Interrupt, 1);
                     Log(("emR3RawHandleRC: recheck gate %x -> valid=%d\n", u8Interrupt, TRPMR3GetGuestTrapHandler(pVM, u8Interrupt) != TRPM_INVALID_HANDLER));
@@ -2157,8 +2174,4 @@
             break;
         }
-
-        case VINF_EM_RAW_RING_SWITCH_INT:
-            rc = VINF_EM_RESCHEDULE_REM;
-            break;
 
         /*
Index: /trunk/src/VBox/VMM/PATM/CSAM.cpp
===================================================================
--- /trunk/src/VBox/VMM/PATM/CSAM.cpp	(revision 346)
+++ /trunk/src/VBox/VMM/PATM/CSAM.cpp	(revision 347)
@@ -216,6 +216,4 @@
     pVM->csam.s.fScanningStarted = false;
 
-    memset(&pVM->csam.s.aIDT[0], 0, sizeof(pVM->csam.s.aIDT));
-
     VM_FF_CLEAR(pVM, VM_FF_CSAM_FLUSH_DIRTY_PAGE);
     pVM->csam.s.cDirtyPages = 0;
@@ -454,7 +452,4 @@
     memcpy(pVM->csam.s.pvDirtyBasePage,  csamInfo.pvDirtyBasePage, sizeof(pVM->csam.s.pvDirtyBasePage));
     memcpy(pVM->csam.s.pvDirtyFaultPage, csamInfo.pvDirtyFaultPage, sizeof(pVM->csam.s.pvDirtyFaultPage));
-
-    /* Restore IDT gate info. */
-    memcpy(&pVM->csam.s.aIDT[0], &csamInfo.aIDT[0], sizeof(pVM->csam.s.aIDT));
 
     /* Restore pgdir bitmap (we'll change the pointers next). */
@@ -2161,4 +2156,17 @@
     }
 
+    /* We only check all gates once during a session */
+    if (    !pVM->csam.s.fGatesChecked
+        &&   cGates != 256)
+        return VINF_SUCCESS;    /* too early */
+
+    /* We only check all gates once during a session */
+    if (    pVM->csam.s.fGatesChecked
+        &&  cGates != 1)
+        return VINF_SUCCESS;    /* ignored */
+
+    if (cGates != 1)
+        pVM->csam.s.fGatesChecked = true;
+
     Assert(GCPtrIDT && cGates <= 256);
     if (!GCPtrIDT || cGates > 256)
@@ -2208,27 +2216,9 @@
     for (/*iGate*/; iGate<iGateEnd; iGate++, pGuestIdte++)
     {
-        if (    pVM->csam.s.fGatesChecked
-            &&  cGates != 1                 /* applies only when we check the entire IDT */
-            &&  pGuestIdte->au64 != pVM->csam.s.aIDT[iGate].au64)
-        {
-            /* We can't check the contents here, as it might only have been partially modified at this point.
-             * TRPMR3InjectEvent will recheck if necessary.
-             */
-#ifdef DEBUG
-            RTGCPTR pHandler = (pGuestIdte->Gen.u16OffsetHigh << 16) | pGuestIdte->Gen.u16OffsetLow;
-
-            Log2(("IDT entry %x with handler %VGv refused (1)\n", iGate, pHandler));
-#endif
-            TRPMR3SetGuestTrapHandler(pVM, iGate, TRPM_INVALID_HANDLER);
-            TRPMR3SetGuestTrapHandlerDirty(pVM, iGate, true);
-            continue;
-        }
-
-        TRPMR3SetGuestTrapHandlerDirty(pVM, iGate, false);
+        Assert(TRPMR3GetGuestTrapHandler(pVM, iGate) == TRPM_INVALID_HANDLER);
 
         if (    pGuestIdte->Gen.u1Present
             &&  (pGuestIdte->Gen.u5Type2 == VBOX_IDTE_TYPE2_TRAP_32 || pGuestIdte->Gen.u5Type2 == VBOX_IDTE_TYPE2_INT_32)
             &&  (pGuestIdte->Gen.u2DPL == 3 || pGuestIdte->Gen.u2DPL == 0)
-            &&  pGuestIdte->au64 != pVM->csam.s.aIDT[iGate].au64
            )
         {
@@ -2236,12 +2226,4 @@
             CSAMP2GLOOKUPREC cacheRec = {0};            /* Cache record for PATMGCVirtToHCVirt. */
             PCSAMPAGE pPage = NULL;
-
-            /* Save a copy */
-            pVM->csam.s.aIDT[iGate].au64 = pGuestIdte->au64;
-
-            /*
-             * Assume it's not safe.
-             */
-            TRPMR3SetGuestTrapHandler(pVM, iGate, TRPM_INVALID_HANDLER);
 
             pHandler = (pGuestIdte->Gen.u16OffsetHigh << 16) | pGuestIdte->Gen.u16OffsetLow;
@@ -2263,92 +2245,58 @@
             {
                 Log(("CSAMCheckGates: csamAnalyseCodeStream failed with %d\n", rc));
+                continue;
             }
+            if (iGate >= 0x20)
+            {
+                /* OpenBSD guest specific patch test (3.7 & 3.8) */
+                rc = PATMR3InstallPatch(pVM, pHandler - 3, PATMFL_CODE32 | PATMFL_GUEST_SPECIFIC);
+                if (VBOX_FAILURE(rc))
+                    /* OpenBSD guest specific patch test (3.9 & 4.0) */
+                    rc = PATMR3InstallPatch(pVM, pHandler - 0x2B, PATMFL_CODE32 | PATMFL_GUEST_SPECIFIC);
+                if (VBOX_SUCCESS(rc))
+                    Log(("Installed OpenBSD interrupt handler prefix instruction (push cs) patch\n"));
+            }
+
+            /* Trap gates and certain interrupt gates. */
+            uint32_t fPatchFlags = PATMFL_CODE32 | PATMFL_IDTHANDLER;
+
+            if (pGuestIdte->Gen.u5Type2 == VBOX_IDTE_TYPE2_TRAP_32)
+                fPatchFlags |= PATMFL_TRAPHANDLER;
             else
+                fPatchFlags |= PATMFL_INTHANDLER;
+
+            switch (iGate) {
+            case 8:
+            case 10:
+            case 11:
+            case 12:
+            case 13:
+            case 14:
+            case 17:
+                fPatchFlags |= PATMFL_TRAPHANDLER_WITH_ERRORCODE;
+                break;
+            default:
+                /* No error code. */
+                break;
+            }
+
+            Log(("Installing %s gate handler for 0x%X at %VGv\n", (pGuestIdte->Gen.u5Type2 == VBOX_IDTE_TYPE2_TRAP_32) ? "trap" : "intr", iGate, pHandler));
+
+            rc = PATMR3InstallPatch(pVM, pHandler, fPatchFlags);
+            if (VBOX_SUCCESS(rc) || rc == VERR_PATM_ALREADY_PATCHED)
             {
-                if (iGate >= 0x20)
+                Log(("Gate handler 0x%X is SAFE!\n", iGate));
+
+                RTGCPTR pNewHandlerGC = PATMR3QueryPatchGCPtr(pVM, pHandler);
+                if (pNewHandlerGC)
                 {
-                    /* OpenBSD guest specific patch test (3.7 & 3.8) */
-                    rc = PATMR3InstallPatch(pVM, pHandler - 3, PATMFL_CODE32 | PATMFL_GUEST_SPECIFIC);
+                    rc = TRPMR3SetGuestTrapHandler(pVM, iGate, pNewHandlerGC);
                     if (VBOX_FAILURE(rc))
-                        /* OpenBSD guest specific patch test (3.9 & 4.0) */
-                        rc = PATMR3InstallPatch(pVM, pHandler - 0x2B, PATMFL_CODE32 | PATMFL_GUEST_SPECIFIC);
-                    if (VBOX_SUCCESS(rc))
-                        Log(("Installed OpenBSD interrupt handler prefix instruction (push cs) patch\n"));
-                }
-
-                /* Trap gates and certain interrupt gates. */
-                uint32_t fPatchFlags = PATMFL_CODE32 | PATMFL_IDTHANDLER;
-
-                if (pGuestIdte->Gen.u5Type2 == VBOX_IDTE_TYPE2_TRAP_32)
-                    fPatchFlags |= PATMFL_TRAPHANDLER;
-                else
-                    fPatchFlags |= PATMFL_INTHANDLER;
-
-                switch (iGate) {
-                case 8:
-                case 10:
-                case 11:
-                case 12:
-                case 13:
-                case 14:
-                case 17:
-                    fPatchFlags |= PATMFL_TRAPHANDLER_WITH_ERRORCODE;
-                    break;
-                default:
-                    /* No error code. */
-                    break;
-                }
-
-                Log(("Installing %s gate handler for 0x%X at %VGv\n", (pGuestIdte->Gen.u5Type2 == VBOX_IDTE_TYPE2_TRAP_32) ? "trap" : "intr", iGate, pHandler));
-
-                rc = PATMR3InstallPatch(pVM, pHandler, fPatchFlags);
-                if (VBOX_SUCCESS(rc) || rc == VERR_PATM_ALREADY_PATCHED)
-                {
-                    RTGCPTR pNewHandlerGC;
-
-                    Log(("Gate handler 0x%X is SAFE!\n", iGate));
-
-                    pNewHandlerGC = PATMR3QueryPatchGCPtr(pVM, pHandler);
-                    if (pNewHandlerGC)
-                    {
-                        rc = TRPMR3SetGuestTrapHandler(pVM, iGate, pNewHandlerGC);
-                        if (VBOX_FAILURE(rc))
-                            Log(("TRPMR3SetGuestTrapHandler %d failed with %Vrc\n", iGate, rc));
-                    }
-                    else
-                        Assert(0);
+                        Log(("TRPMR3SetGuestTrapHandler %d failed with %Vrc\n", iGate, rc));
                 }
             }
         }
-        else
-        if (pGuestIdte->au64 != pVM->csam.s.aIDT[iGate].au64)
-        {
-            /* Save a copy */
-            pVM->csam.s.aIDT[iGate].au64 = pGuestIdte->au64;
-
-#ifdef DEBUG
-            RTGCPTR pHandler = (pGuestIdte->Gen.u16OffsetHigh << 16) | pGuestIdte->Gen.u16OffsetLow;
-
-            Log2(("IDT entry %x with handler %VGv refused (2)\n", iGate, pHandler));
-#endif
-
-            /*
-             * Everything is dangerous unless checked
-             */
-            TRPMR3SetGuestTrapHandler(pVM, iGate, TRPM_INVALID_HANDLER);
-        }
-#ifdef DEBUG
-        else
-        if (TRPMR3GetGuestTrapHandler(pVM, iGate) == TRPM_INVALID_HANDLER)
-        {
-            RTGCPTR pHandler = (pGuestIdte->Gen.u16OffsetHigh << 16) | pGuestIdte->Gen.u16OffsetLow;
-
-            Log2(("IDT entry %x with handler %VGv refused (3)\n", iGate, pHandler));
-        }
-#endif
-    }
+    } /* for */
     STAM_PROFILE_STOP(&pVM->csam.s.StatCheckGates, a);
-
-    pVM->csam.s.fGatesChecked = true;
     return VINF_SUCCESS;
 }
Index: /trunk/src/VBox/VMM/PATM/CSAMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/PATM/CSAMInternal.h	(revision 346)
+++ /trunk/src/VBox/VMM/PATM/CSAMInternal.h	(revision 347)
@@ -45,5 +45,5 @@
 /** @} */
 
-#define CSAM_SSM_VERSION                       12
+#define CSAM_SSM_VERSION                       13
 
 #define CSAM_PGDIRBMP_CHUNKS                   1024
@@ -158,7 +158,4 @@
     HCPTRTYPE(uint8_t **) pPDBitmapHC;
     HCPTRTYPE(RTGCPTR  *) pPDGCBitmapHC;
-
-    /* Saved IDT entries. */
-    VBOXIDTE            aIDT[256];
 
     /* Temporary storage during load/save state */
Index: /trunk/src/VBox/VMM/PATM/PATM.cpp
===================================================================
--- /trunk/src/VBox/VMM/PATM/PATM.cpp	(revision 346)
+++ /trunk/src/VBox/VMM/PATM/PATM.cpp	(revision 347)
@@ -1594,11 +1594,5 @@
         if (pCpu->pCurInstr->opcode == OP_CALL)
         {
-            if (PATMIsPatchGCAddr(pVM, pTargetGC))
-            {
-                pTargetGC = PATMR3QueryPatchGCPtr(pVM, pTargetGC);
-                if (pTargetGC == 0)
-                    return VERR_PATCHING_REFUSED;
-            }
-
+            Assert(!PATMIsPatchGCAddr(pVM, pTargetGC));
             rc = patmPatchGenCall(pVM, pPatch, pCpu, pCurInstrGC, pTargetGC, false);
             if (VBOX_FAILURE(rc))
@@ -4863,8 +4857,5 @@
             iGate = TRPMR3QueryGateByHandler(pVM, PATCHCODE_PTR_GC(pPatch));
             if (iGate != (uint32_t)~0)
-            {
                 TRPMR3SetGuestTrapHandler(pVM, iGate, TRPM_INVALID_HANDLER);
-                TRPMR3SetGuestTrapHandlerDirty(pVM, iGate, false);
-            }
         }
 
@@ -5542,25 +5533,9 @@
     // Find the patch record
     pPatchRec = (PPATMPATCHREC)RTAvloGCPtrGet(&pVM->patm.s.PatchLookupTreeHC->PatchTree, pAddrGC);
-    if (pPatchRec)
-    {
+    /** @todo we should only use patches that are enabled! always did this, but it's incorrect! */
+    if (pPatchRec && (pPatchRec->patch.uState == PATCH_ENABLED || pPatchRec->patch.uState == PATCH_DIRTY))
         return PATCHCODE_PTR_GC(&pPatchRec->patch);
-    }
+
     return 0;
-}
-
-/**
- * Handle traps in patch code.
- *
- * The current guest trap has an EIP inside patch code space.
- *
- * @returns On success VINF_SUCCESS or between VINF_EM_FIRST and VINF_EM_LAST.
- * @returns On failure appropriate status code.
- * @param   pVM         VM Handle.
- * @param   rc          The GC return code.
- */
-PATMR3DECL(int) PATMR3Trap(PVM pVM, int rc)
-{
-    /** @todo Implement PATMR3Trap! */
-    return VERR_NOT_IMPLEMENTED;
 }
 
Index: /trunk/src/VBox/VMM/SELM.cpp
===================================================================
--- /trunk/src/VBox/VMM/SELM.cpp	(revision 346)
+++ /trunk/src/VBox/VMM/SELM.cpp	(revision 347)
@@ -1478,6 +1478,6 @@
 
                 /** @todo handle these dependencies better! */
-                TRPMR3ClearHandler(pVM, 0x2E);
-                TRPMR3ClearHandler(pVM, 0x80);
+                TRPMR3SetGuestTrapHandler(pVM, 0x2E, TRPM_INVALID_HANDLER);
+                TRPMR3SetGuestTrapHandler(pVM, 0x80, TRPM_INVALID_HANDLER);
                 pVM->selm.s.fSyncTSSRing0Stack = true;
  	        }
Index: /trunk/src/VBox/VMM/TRPM.cpp
===================================================================
--- /trunk/src/VBox/VMM/TRPM.cpp	(revision 346)
+++ /trunk/src/VBox/VMM/TRPM.cpp	(revision 347)
@@ -441,5 +441,4 @@
     AssertRelease(sizeof(pVM->trpm.s) <= sizeof(pVM->trpm.padding));
     AssertRelease(ELEMENTS(pVM->trpm.s.aGuestTrapHandler) == sizeof(pVM->trpm.s.au32IdtPatched)*8);
-    AssertRelease(ELEMENTS(pVM->trpm.s.aGuestTrapHandler) == sizeof(pVM->trpm.s.au32IdtDirty)*8);
 
     /*
@@ -723,5 +722,4 @@
     SSMR3PutUInt(pSSM,      VM_FF_ISSET(pVM, VM_FF_TRPM_SYNC_IDT));
     SSMR3PutMem(pSSM,       &pTrpm->au32IdtPatched[0], sizeof(pTrpm->au32IdtPatched));
-    SSMR3PutMem(pSSM,       &pTrpm->au32IdtDirty[0], sizeof(pTrpm->au32IdtDirty));
     SSMR3PutU32(pSSM, ~0);              /* separator. */
 
@@ -798,5 +796,4 @@
 
     SSMR3GetMem(pSSM, &pTrpm->au32IdtPatched[0], sizeof(pTrpm->au32IdtPatched));
-    SSMR3GetMem(pSSM, &pTrpm->au32IdtDirty[0], sizeof(pTrpm->au32IdtDirty));
 
     /* check the separator */
@@ -866,6 +863,11 @@
     if (fRawRing0 && CSAMIsEnabled(pVM))
     {
-        rc = CSAMR3CheckGates(pVM, 0, 256); /* check all gates */
-        AssertRCReturn(rc, rc);
+        /* Clear all handlers */
+        /** @todo inefficient, but simple */
+        for (unsigned iGate=0;iGate<256;iGate++)
+            TRPMR3SetGuestTrapHandler(pVM, iGate, TRPM_INVALID_HANDLER);
+
+        /* Scan them all (only the first time) */
+        CSAMR3CheckGates(pVM, 0, 256);
     }
 
@@ -994,61 +996,60 @@
 
 
-#if 0 /* obsolete */
-/**
- * Activate guest trap gate handler
- * Used for setting up trap gates used for kernel calls.
+/**
+ * Clear passthrough interrupt gate handler (reset to default handler)
  *
  * @returns VBox status code.
  * @param   pVM         The VM to operate on.
- * @param   iTrap       Interrupt/trap number.
- */
-TRPMR3DECL(int) TRPMR3EnableGuestTrapHandler(PVM pVM, unsigned iTrap)
-{
-    /*
-     * Validate.
-     */
-    if (!EMIsRawRing0Enabled(pVM))
-    {
-        AssertMsgFailed(("Enabling interrupt gates only works when raw ring 0 is enabled\n"));
-        return VINF_SUCCESS;
-    }
-    if (iTrap < TRPM_HANDLER_INT_BASE || iTrap >= ELEMENTS(pVM->trpm.s.aIdt))
-    {
-        AssertMsg(iTrap < TRPM_HANDLER_INT_BASE, ("Illegal gate number %d!\n", iTrap));
+ * @param   iTrap       Trap/interrupt gate number.
+ */
+TRPMR3DECL(int) trpmR3ClearPassThroughHandler(PVM pVM, unsigned iTrap)
+{
+    /** @todo cleanup trpmR3ClearPassThroughHandler()! */
+    RTGCPTR aGCPtrs[TRPM_HANDLER_MAX];
+    int rc;
+
+    memset(aGCPtrs, 0, sizeof(aGCPtrs));
+
+    rc = PDMR3GetSymbolGC(pVM, VMMGC_MAIN_MODULE_NAME, "TRPMGCHandlerInterupt", &aGCPtrs[TRPM_HANDLER_INT]);
+    AssertReleaseMsgRC(rc, ("Couldn't find TRPMGCHandlerInterupt in VMMGC.gc!\n"));
+
+    if (    iTrap < TRPM_HANDLER_INT_BASE
+        ||  iTrap >= ELEMENTS(pVM->trpm.s.aIdt))
+    {
+        AssertMsg(iTrap < TRPM_HANDLER_INT_BASE, ("Illegal gate number %#x!\n", iTrap));
         return VERR_INVALID_PARAMETER;
     }
-
-    uint16_t    cbIDT;
-    RTGCPTR     GCPtrIDT = CPUMGetGuestIDTR(pVM, &cbIDT);
-    if (iTrap * sizeof(VBOXIDTE) >= cbIDT)
-        return VERR_INVALID_PARAMETER;  /* Silently ignore out of range requests. */
-
-    /*
-     * Read the guest IDT entry.
-     */
-    VBOXIDTE GuestIdte;
-    int rc = PGMPhysReadGCPtr(pVM, &GuestIdte, GCPtrIDT + iTrap * sizeof(GuestIdte),  sizeof(GuestIdte));
-    if (VBOX_FAILURE(rc))
-    {
-        AssertMsgRC(rc, ("Failed to read IDTE! rc=%Vrc\n", rc));
-        return rc;
-    }
-
-    if (    GuestIdte.Gen.u1Present
-        &&  GuestIdte.Gen.u5Type2 == VBOX_IDTE_TYPE2_TRAP_32
-        &&  GuestIdte.Gen.u2DPL == 3)
-    {
-        LogFlow(("TRPMR3SetHandler: %X %04X:%04X%04X gate=%d dpl=%d present=%d\n", iTrap,
-                 GuestIdte.Gen.u16SegSel, GuestIdte.Gen.u16OffsetHigh, GuestIdte.Gen.u16OffsetLow,
-                 GuestIdte.Gen.u5Type2, GuestIdte.Gen.u2DPL, GuestIdte.Gen.u1Present));
-
-        PVBOXIDTE pIdte = &pVM->trpm.s.aIdt[iTrap];
-        GuestIdte.Gen.u16SegSel |= 1;  // ring 1
-        *pIdte = GuestIdte;
+    memcpy(&pVM->trpm.s.aIdt[iTrap], &g_aIdt[iTrap], sizeof(pVM->trpm.s.aIdt[0]));
+
+    /* Unmark it for relocation purposes. */
+    ASMBitClear(&pVM->trpm.s.au32IdtPatched[0], iTrap);
+
+    RTSEL               SelCS         = CPUMGetHyperCS(pVM);
+    PVBOXIDTE           pIdte         = &pVM->trpm.s.aIdt[iTrap];
+    PVBOXIDTE_GENERIC   pIdteTemplate = &g_aIdt[iTrap];
+    if (pIdte->Gen.u1Present)
+    {
+        Assert(pIdteTemplate->u16OffsetLow == TRPM_HANDLER_INT);
+        Assert(sizeof(RTGCPTR) <= sizeof(aGCPtrs[0]));
+        RTGCPTR Offset = (RTGCPTR)aGCPtrs[pIdteTemplate->u16OffsetLow];
+
+        /*
+         * Generic handlers have different entrypoints for each possible
+         * vector number. These entrypoints make a sort of an array with
+         * 8 byte entries where the vector number is the index.
+         * See TRPMGCHandlersA.asm for details.
+         */
+        Offset += iTrap * 8;
+
+        if (pIdte->Gen.u5Type2 != VBOX_IDTE_TYPE2_TASK)
+        {
+            pIdte->Gen.u16OffsetLow  = Offset & 0xffff;
+            pIdte->Gen.u16OffsetHigh = Offset >> 16;
+            pIdte->Gen.u16SegSel     = SelCS;
+        }
     }
 
     return VINF_SUCCESS;
 }
-#endif
 
 
@@ -1083,38 +1084,4 @@
 
 /**
- * Marks IDT entry as dirty
- *
- * @returns Guest trap handler address or TRPM_INVALID_HANDLER if none installed
- * @param   pVM         The VM to operate on.
- * @param   iTrap       Interrupt/trap number.
- * @param   fSetDirty   Set or clear
- */
-TRPMR3DECL(int) TRPMR3SetGuestTrapHandlerDirty(PVM pVM, unsigned iGate, bool fSetDirty)
-{
-    AssertReturn(iGate < ELEMENTS(pVM->trpm.s.aIdt), VERR_INVALID_PARAMETER);
-
-    if (fSetDirty)
-        ASMBitSet(&pVM->trpm.s.au32IdtDirty[0], iGate);
-    else
-        ASMBitClear(&pVM->trpm.s.au32IdtDirty[0], iGate);
-
-    return VINF_SUCCESS;
-}
-
-
-/**
- * Checks if IDT entry is dirty
- *
- * @returns dirty status
- * @param   pVM         The VM to operate on.
- * @param   iTrap       Interrupt/trap number.
- */
-TRPMR3DECL(bool) TRPMR3IsGuestTrapHandlerDirty(PVM pVM, unsigned iGate)
-{
-    return ASMBitTest(&pVM->trpm.s.au32IdtDirty[0], iGate);
-}
-
-
-/**
  * Get guest trap/interrupt gate handler
  *
@@ -1162,4 +1129,8 @@
         /* clear trap handler */
         Log(("TRPMR3SetGuestTrapHandler: clear handler %x\n", iTrap));
+
+        if (ASMBitTest(&pVM->trpm.s.au32IdtPatched[0], iTrap))
+            trpmR3ClearPassThroughHandler(pVM, iTrap);
+
         pVM->trpm.s.aGuestTrapHandler[iTrap] = TRPM_INVALID_HANDLER;
         return VINF_SUCCESS;
@@ -1229,62 +1200,4 @@
     }
     return VERR_INVALID_PARAMETER;
-}
-
-
-/**
- * Clear interrupt gate handler (reset to default handler)
- *
- * @returns VBox status code.
- * @param   pVM         The VM to operate on.
- * @param   iTrap       Trap/interrupt gate number.
- */
-TRPMR3DECL(int) TRPMR3ClearHandler(PVM pVM, unsigned iTrap)
-{
-    /** @todo cleanup TRPMR3ClearHandler()! */
-    RTGCPTR aGCPtrs[TRPM_HANDLER_MAX];
-    int rc;
-
-    memset(aGCPtrs, 0, sizeof(aGCPtrs));
-
-    rc = PDMR3GetSymbolGC(pVM, VMMGC_MAIN_MODULE_NAME, "TRPMGCHandlerInterupt", &aGCPtrs[TRPM_HANDLER_INT]);
-    AssertReleaseMsgRC(rc, ("Couldn't find TRPMGCHandlerInterupt in VMMGC.gc!\n"));
-
-    if (    iTrap < TRPM_HANDLER_INT_BASE
-        ||  iTrap >= ELEMENTS(pVM->trpm.s.aIdt))
-    {
-        AssertMsg(iTrap < TRPM_HANDLER_INT_BASE, ("Illegal gate number %#x!\n", iTrap));
-        return VERR_INVALID_PARAMETER;
-    }
-    memcpy(&pVM->trpm.s.aIdt[iTrap], &g_aIdt[iTrap], sizeof(pVM->trpm.s.aIdt[0]));
-
-    /* Unmark it for relocation purposes. */
-    ASMBitClear(&pVM->trpm.s.au32IdtPatched[0], iTrap);
-
-    RTSEL               SelCS         = CPUMGetHyperCS(pVM);
-    PVBOXIDTE           pIdte         = &pVM->trpm.s.aIdt[iTrap];
-    PVBOXIDTE_GENERIC   pIdteTemplate = &g_aIdt[iTrap];
-    if (pIdte->Gen.u1Present)
-    {
-        Assert(pIdteTemplate->u16OffsetLow == TRPM_HANDLER_INT);
-        Assert(sizeof(RTGCPTR) <= sizeof(aGCPtrs[0]));
-        RTGCPTR Offset = (RTGCPTR)aGCPtrs[pIdteTemplate->u16OffsetLow];
-
-        /*
-         * Generic handlers have different entrypoints for each possible
-         * vector number. These entrypoints make a sort of an array with
-         * 8 byte entries where the vector number is the index.
-         * See TRPMGCHandlersA.asm for details.
-         */
-        Offset += iTrap * 8;
-
-        if (pIdte->Gen.u5Type2 != VBOX_IDTE_TYPE2_TASK)
-        {
-            pIdte->Gen.u16OffsetLow  = Offset & 0xffff;
-            pIdte->Gen.u16OffsetHigh = Offset >> 16;
-            pIdte->Gen.u16SegSel     = SelCS;
-        }
-    }
-
-    return VINF_SUCCESS;
 }
 
@@ -1401,8 +1314,7 @@
                 return VINF_EM_RESCHEDULE_HWACC;
             }
-            /* If the guest gate is marked dirty, then we will check again if we can patch it. */
-            if (TRPMR3IsGuestTrapHandlerDirty(pVM, u8Interrupt))
+            /* If the guest gate is not patched, then we will check (again) if we can patch it. */
+            if (pVM->trpm.s.aGuestTrapHandler[u8Interrupt] == TRPM_INVALID_HANDLER)
             {
-                Assert(TRPMR3GetGuestTrapHandler(pVM, u8Interrupt) == TRPM_INVALID_HANDLER);
                 CSAMR3CheckGates(pVM, u8Interrupt, 1);
                 Log(("TRPMR3InjectEvent: recheck gate %x -> valid=%d\n", u8Interrupt, TRPMR3GetGuestTrapHandler(pVM, u8Interrupt) != TRPM_INVALID_HANDLER));
Index: /trunk/src/VBox/VMM/TRPMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/TRPMInternal.h	(revision 346)
+++ /trunk/src/VBox/VMM/TRPMInternal.h	(revision 347)
@@ -130,7 +130,4 @@
     uint32_t        au32IdtPatched[8];
 
-    /** Bitmap for IDTEs that were changed. */
-    uint32_t        au32IdtDirty[8];
-
     /** Temporary Hypervisor trap handlers.
      * NULL means default action. */
Index: /trunk/src/VBox/VMM/TRPMInternal.mac
===================================================================
--- /trunk/src/VBox/VMM/TRPMInternal.mac	(revision 346)
+++ /trunk/src/VBox/VMM/TRPMInternal.mac	(revision 347)
@@ -47,5 +47,4 @@
     .aIdt               resd 512
     .au32IdtPatched     resd 8
-    .au32IdtDirty       resd 8
     .aTmpTrapHandlers   resd 256
 
