Index: trunk/src/VBox/VMM/VMMAll/IEMAllInstOneByte.cpp.h
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllInstOneByte.cpp.h	(revision 100760)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllInstOneByte.cpp.h	(revision 100761)
@@ -2312,7 +2312,7 @@
         IEMOP_HLP_NO_64BIT();
         if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
-            IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_RFLAGS, iemCImpl_popa_16);
+            IEM_MC_DEFER_TO_CIMPL_0_RET(0, iemCImpl_popa_16);
         Assert(pVCpu->iem.s.enmEffOpSize == IEMMODE_32BIT);
-        IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_RFLAGS, iemCImpl_popa_32);
+        IEM_MC_DEFER_TO_CIMPL_0_RET(0, iemCImpl_popa_32);
     }
     IEMOP_MNEMONIC(mvex, "mvex");
@@ -5723,5 +5723,6 @@
     IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
-    IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_RFLAGS, iemCImpl_popf, pVCpu->iem.s.enmEffOpSize);
+    IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_RFLAGS | IEM_CIMPL_F_CHECK_IRQ,
+                                iemCImpl_popf, pVCpu->iem.s.enmEffOpSize);
 }
 
@@ -7584,5 +7585,5 @@
     IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     IEM_MC_DEFER_TO_CIMPL_1_RET(IEM_CIMPL_F_BRANCH_INDIRECT | IEM_CIMPL_F_BRANCH_FAR
-                                | IEM_CIMPL_F_MODE | IEM_CIMPL_F_RFLAGS | IEM_CIMPL_F_VMEXIT,
+                                | IEM_CIMPL_F_MODE | IEM_CIMPL_F_RFLAGS | IEM_CIMPL_F_CHECK_IRQ | IEM_CIMPL_F_VMEXIT,
                                 iemCImpl_iret, pVCpu->iem.s.enmEffOpSize);
 }
@@ -12543,5 +12544,5 @@
     IEMOP_MNEMONIC(sti, "sti");
     IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
-    IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_RFLAGS | IEM_CIMPL_F_VMEXIT, iemCImpl_sti);
+    IEM_MC_DEFER_TO_CIMPL_0_RET(IEM_CIMPL_F_RFLAGS | IEM_CIMPL_F_CHECK_IRQ_DELAYED | IEM_CIMPL_F_VMEXIT, iemCImpl_sti);
 }
 
Index: trunk/src/VBox/VMM/VMMAll/IEMAllThrdFuncsBltIn.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllThrdFuncsBltIn.cpp	(revision 100760)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllThrdFuncsBltIn.cpp	(revision 100761)
@@ -88,4 +88,37 @@
     return pfnCImpl(pVCpu, cbInstr);
 }
+
+
+/**
+ * Built-in function that checks for pending interrupts that can be delivered.
+ *
+ * This triggers after the completion of an instruction, so EIP is already at
+ * the next instruction.  If an IRQ or important FF is pending, this will return
+ * a non-zero status that stops TB execution.
+ */
+IEM_DECL_IEMTHREADEDFUNC_DEF(iemThreadedFunc_BltIn_CheckIrq)
+{
+    RT_NOREF(uParam0, uParam1, uParam2);
+
+    /*
+     * Check for IRQs and other FFs that needs servicing.
+     */
+    uint64_t fCpu = pVCpu->fLocalForcedActions;
+    fCpu &= VMCPU_FF_ALL_MASK & ~(  VMCPU_FF_PGM_SYNC_CR3
+                                  | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL
+                                  | VMCPU_FF_TLB_FLUSH
+                                  | VMCPU_FF_UNHALT );
+    if (RT_LIKELY(   (   !fCpu
+                      || (   !(fCpu & ~(VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC))
+                          && !pVCpu->cpum.GstCtx.rflags.Bits.u1IF) )
+                  && !VM_FF_IS_ANY_SET(pVCpu->CTX_SUFF(pVM), VM_FF_ALL_MASK) ))
+        return VINF_SUCCESS;
+
+    Log(("%04x:%08RX32: Pending IRQ and/or FF: fCpu=%#RX64 fVm=%#RX32 IF=%d\n",
+         pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.eip, fCpu,
+         pVCpu->CTX_SUFF(pVM)->fGlobalForcedActions & VM_FF_ALL_MASK, pVCpu->cpum.GstCtx.rflags.Bits.u1IF));
+    return VINF_IEM_REEXEC_MODE_CHANGED;
+}
+
 
 
Index: trunk/src/VBox/VMM/VMMAll/IEMAllThrdPython.py
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllThrdPython.py	(revision 100760)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllThrdPython.py	(revision 100761)
@@ -209,4 +209,6 @@
         'IEM_CIMPL_F_BRANCH_CONDITIONAL':   False,
         'IEM_CIMPL_F_RFLAGS':               False,
+        'IEM_CIMPL_F_CHECK_IRQ':            False,
+        'IEM_CIMPL_F_CHECK_IRQ_DELAYED':    False,
         'IEM_CIMPL_F_STATUS_FLAGS':         False,
         'IEM_CIMPL_F_VMEXIT':               True,
@@ -909,5 +911,5 @@
         # mask and maybe emit additional checks.
         if 'IEM_CIMPL_F_MODE' in self.dsCImplFlags or 'IEM_CIMPL_F_XCPT' in self.dsCImplFlags:
-            aoStmts.append(iai.McCppCall('IEM_MC2_EMIT_CALL_1', ( 'kIemThreadedFunc_CheckMode', 'pVCpu->iem.s.fExec', ),
+            aoStmts.append(iai.McCppCall('IEM_MC2_EMIT_CALL_1', ( 'kIemThreadedFunc_BltIn_CheckMode', 'pVCpu->iem.s.fExec', ),
                                          cchIndent = cchIndent));
 
@@ -931,4 +933,9 @@
             aoStmts.append(iai.McCppGeneric('pVCpu->iem.s.fEndTb = true; /* %s */' % (','.join(asEndTbFlags),),
                                             cchIndent = cchIndent));
+
+        if 'IEM_CIMPL_F_CHECK_IRQ' in self.dsCImplFlags:
+            aoStmts.append(iai.McCppGeneric('pVCpu->iem.s.cInstrTillIrqCheck = 0;', cchIndent = cchIndent));
+        elif 'IEM_CIMPL_F_CHECK_IRQ_DELAYED' in self.dsCImplFlags:
+            aoStmts.append(iai.McCppGeneric('pVCpu->iem.s.cInstrTillIrqCheck = 1;', cchIndent = cchIndent));
 
         return aoStmts;
@@ -1366,4 +1373,23 @@
         ];
 
+    ## List of built-in threaded functions.
+    kasBltIns = (
+        'DeferToCImpl0',
+        'CheckIrq',
+        'CheckMode',
+        'CheckCsLim',
+        'CheckCsLimAndOpcodes',
+        'CheckOpcodes',
+        'CheckCsLimAndPcAndOpcodes',
+        'CheckPcAndOpcodes',
+        'CheckCsLimAndOpcodesAcrossPageLoadingTlb',
+        'CheckOpcodesAcrossPageLoadingTlb',
+        'CheckCsLimAndOpcodesLoadingTlb',
+        'CheckOpcodesLoadingTlb',
+        'CheckCsLimAndOpcodesOnNextPageLoadingTlb',
+        'CheckOpcodesOnNextPageLoadingTlb',
+        'CheckCsLimAndOpcodesOnNewPageLoadingTlb',
+        'CheckOpcodesOnNewPageLoadingTlb',
+    );
 
     def generateThreadedFunctionsHeader(self, oOut):
@@ -1384,20 +1410,7 @@
             '     * Predefined',
             '     */',
-            '    kIemThreadedFunc_DeferToCImpl0,',
-            '    kIemThreadedFunc_CheckMode,',
-            '    kIemThreadedFunc_CheckCsLim,',
-            '    kIemThreadedFunc_CheckCsLimAndOpcodes,',
-            '    kIemThreadedFunc_CheckOpcodes,',
-            '    kIemThreadedFunc_CheckCsLimAndPcAndOpcodes,',
-            '    kIemThreadedFunc_CheckPcAndOpcodes,',
-            '    kIemThreadedFunc_CheckCsLimAndOpcodesAcrossPageLoadingTlb,',
-            '    kIemThreadedFunc_CheckOpcodesAcrossPageLoadingTlb,',
-            '    kIemThreadedFunc_CheckCsLimAndOpcodesLoadingTlb,',
-            '    kIemThreadedFunc_CheckOpcodesLoadingTlb,',
-            '    kIemThreadedFunc_CheckCsLimAndOpcodesOnNextPageLoadingTlb,',
-            '    kIemThreadedFunc_CheckOpcodesOnNextPageLoadingTlb,',
-            '    kIemThreadedFunc_CheckCsLimAndOpcodesOnNewPageLoadingTlb,',
-            '    kIemThreadedFunc_CheckOpcodesOnNewPageLoadingTlb,',
         ];
+        asLines += ['    kIemThreadedFunc_BltIn_%s,' % (sFuncNm,) for sFuncNm in self.kasBltIns];
+
         iThreadedFunction = 1;
         for sVariation in ThreadedFunctionVariation.kasVariationsEmitOrder:
@@ -1540,21 +1553,8 @@
                    + '    /*\n'
                    + '     * Predefined.\n'
-                   + '     */'
-                   + '    iemThreadedFunc_BltIn_DeferToCImpl0,\n'
-                   + '    iemThreadedFunc_BltIn_CheckMode,\n'
-                   + '    iemThreadedFunc_BltIn_CheckCsLim,\n'
-                   + '    iemThreadedFunc_BltIn_CheckCsLimAndOpcodes,\n'
-                   + '    iemThreadedFunc_BltIn_CheckOpcodes,\n'
-                   + '    iemThreadedFunc_BltIn_CheckCsLimAndPcAndOpcodes,\n'
-                   + '    iemThreadedFunc_BltIn_CheckPcAndOpcodes,\n'
-                   + '    iemThreadedFunc_BltIn_CheckCsLimAndOpcodesAcrossPageLoadingTlb,\n'
-                   + '    iemThreadedFunc_BltIn_CheckOpcodesAcrossPageLoadingTlb,\n'
-                   + '    iemThreadedFunc_BltIn_CheckCsLimAndOpcodesLoadingTlb,\n'
-                   + '    iemThreadedFunc_BltIn_CheckOpcodesLoadingTlb,\n'
-                   + '    iemThreadedFunc_BltIn_CheckCsLimAndOpcodesOnNextPageLoadingTlb,\n'
-                   + '    iemThreadedFunc_BltIn_CheckOpcodesOnNextPageLoadingTlb,\n'
-                   + '    iemThreadedFunc_BltIn_CheckCsLimAndOpcodesOnNewPageLoadingTlb,\n'
-                   + '    iemThreadedFunc_BltIn_CheckOpcodesOnNewPageLoadingTlb,\n'
-                   );
+                   + '     */\n');
+        for sFuncNm in self.kasBltIns:
+            oOut.write('    iemThreadedFunc_BltIn_%s,\n' % (sFuncNm,));
+
         iThreadedFunction = 1;
         for sVariation in ThreadedFunctionVariation.kasVariationsEmitOrder:
@@ -1586,21 +1586,8 @@
                    + '    /*\n'
                    + '     * Predefined.\n'
-                   + '     */'
-                   + '    "BltIn_DeferToCImpl0",\n'
-                   + '    "BltIn_CheckMode",\n'
-                   + '    "BltIn_CheckCsLim",\n'
-                   + '    "BltIn_CheckCsLimAndOpcodes",\n'
-                   + '    "BltIn_CheckOpcodes",\n'
-                   + '    "BltIn_CheckCsLimAndPcAndOpcodes",\n'
-                   + '    "BltIn_CheckPcAndOpcodes",\n'
-                   + '    "BltIn_CheckCsLimAndOpcodesAcrossPageLoadingTlb",\n'
-                   + '    "BltIn_CheckOpcodesAcrossPageLoadingTlb",\n'
-                   + '    "BltIn_CheckCsLimAndOpcodesLoadingTlb",\n'
-                   + '    "BltIn_CheckOpcodesLoadingTlb",\n'
-                   + '    "BltIn_CheckCsLimAndOpcodesOnNextPageLoadingTlb",\n'
-                   + '    "BltIn_CheckOpcodesOnNextPageLoadingTlb",\n'
-                   + '    "BltIn_CheckCsLimAndOpcodesOnNewPageLoadingTlb",\n'
-                   + '    "BltIn_CheckOpcodesOnNewPageLoadingTlb",\n'
-                   );
+                   + '     */\n');
+        for sFuncNm in self.kasBltIns:
+            oOut.write('    "BltIn_%s",\n' % (sFuncNm,));
+
         iThreadedFunction = 1;
         for sVariation in ThreadedFunctionVariation.kasVariationsEmitOrder:
Index: trunk/src/VBox/VMM/VMMAll/IEMAllThrdRecompiler.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllThrdRecompiler.cpp	(revision 100760)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllThrdRecompiler.cpp	(revision 100761)
@@ -446,8 +446,8 @@
     uint32_t cHash;
     uint32_t uHashMask;
-    PIEMTB   apHash[_64K];
+    PIEMTB   apHash[_1M];
 } IEMTBCACHE;
 
-static IEMTBCACHE g_TbCache = { _64K, 0xffff, }; /**< Quick and dirty. */
+static IEMTBCACHE g_TbCache = { _1M, _1M - 1, }; /**< Quick and dirty. */
 
 #define IEMTBCACHE_HASH(a_paCache, a_fTbFlags, a_GCPhysPc) \
@@ -735,4 +735,5 @@
         pVCpu->iem.s.fTbBranched            = IEMBRANCHED_F_NO;
         pVCpu->iem.s.fTbCrossedPage         = false;
+        pVCpu->iem.s.cInstrTillIrqCheck     = 32;
     }
     else
@@ -868,6 +869,8 @@
 {
     Assert((pVCpu->iem.s.GCPhysInstrBuf & GUEST_PAGE_OFFSET_MASK) == 0);
+#if 0
     if (pVCpu->cpum.GstCtx.rip >= 0xc0000000 && !LogIsEnabled())
         RTLogChangeFlags(NULL, 0, RTLOGFLAGS_DISABLED);
+#endif
 
     /*
@@ -992,16 +995,16 @@
                 || pVCpu->iem.s.fTbCrossedPage)
                 pCall->enmFunction = pTb->fFlags & IEMTB_F_CS_LIM_CHECKS
-                                   ? kIemThreadedFunc_CheckCsLimAndOpcodesLoadingTlb
-                                   : kIemThreadedFunc_CheckOpcodesLoadingTlb;
+                                   ? kIemThreadedFunc_BltIn_CheckCsLimAndOpcodesLoadingTlb
+                                   : kIemThreadedFunc_BltIn_CheckOpcodesLoadingTlb;
             else if (pVCpu->iem.s.fTbBranched & (IEMBRANCHED_F_CONDITIONAL | /* paranoia: */ IEMBRANCHED_F_DIRECT))
                 pCall->enmFunction = pTb->fFlags & IEMTB_F_CS_LIM_CHECKS
-                                   ? kIemThreadedFunc_CheckCsLimAndPcAndOpcodes
-                                   : kIemThreadedFunc_CheckPcAndOpcodes;
+                                   ? kIemThreadedFunc_BltIn_CheckCsLimAndPcAndOpcodes
+                                   : kIemThreadedFunc_BltIn_CheckPcAndOpcodes;
             else
             {
                 Assert(pVCpu->iem.s.fTbBranched & IEMBRANCHED_F_RELATIVE);
                 pCall->enmFunction = pTb->fFlags & IEMTB_F_CS_LIM_CHECKS
-                                   ? kIemThreadedFunc_CheckCsLimAndOpcodes
-                                   : kIemThreadedFunc_CheckOpcodes;
+                                   ? kIemThreadedFunc_BltIn_CheckCsLimAndOpcodes
+                                   : kIemThreadedFunc_BltIn_CheckOpcodes;
             }
         }
@@ -1104,6 +1107,6 @@
             /* Determin which function we need to load & check. */
             pCall->enmFunction = pTb->fFlags & IEMTB_F_CS_LIM_CHECKS
-                               ? kIemThreadedFunc_CheckCsLimAndOpcodesOnNewPageLoadingTlb
-                               : kIemThreadedFunc_CheckOpcodesOnNewPageLoadingTlb;
+                               ? kIemThreadedFunc_BltIn_CheckCsLimAndOpcodesOnNewPageLoadingTlb
+                               : kIemThreadedFunc_BltIn_CheckOpcodesOnNewPageLoadingTlb;
         }
         else
@@ -1126,10 +1129,10 @@
             if (pVCpu->iem.s.fTbCheckOpcodes)
                 pCall->enmFunction = pTb->fFlags & IEMTB_F_CS_LIM_CHECKS
-                                   ? kIemThreadedFunc_CheckCsLimAndOpcodesAcrossPageLoadingTlb
-                                   : kIemThreadedFunc_CheckOpcodesAcrossPageLoadingTlb;
+                                   ? kIemThreadedFunc_BltIn_CheckCsLimAndOpcodesAcrossPageLoadingTlb
+                                   : kIemThreadedFunc_BltIn_CheckOpcodesAcrossPageLoadingTlb;
             else
                 pCall->enmFunction = pTb->fFlags & IEMTB_F_CS_LIM_CHECKS
-                                   ? kIemThreadedFunc_CheckCsLimAndOpcodesOnNextPageLoadingTlb
-                                   : kIemThreadedFunc_CheckOpcodesOnNextPageLoadingTlb;
+                                   ? kIemThreadedFunc_BltIn_CheckCsLimAndOpcodesOnNextPageLoadingTlb
+                                   : kIemThreadedFunc_BltIn_CheckOpcodesOnNextPageLoadingTlb;
         }
     }
@@ -1143,8 +1146,8 @@
         if (pVCpu->iem.s.fTbCheckOpcodes)
             pCall->enmFunction = pTb->fFlags & IEMTB_F_CS_LIM_CHECKS
-                               ? kIemThreadedFunc_CheckCsLimAndOpcodes
-                               : kIemThreadedFunc_CheckOpcodes;
+                               ? kIemThreadedFunc_BltIn_CheckCsLimAndOpcodes
+                               : kIemThreadedFunc_BltIn_CheckOpcodes;
         else
-            pCall->enmFunction = kIemThreadedFunc_CheckCsLim;
+            pCall->enmFunction = kIemThreadedFunc_BltIn_CheckCsLim;
 
         iemThreadedCopyOpcodeBytesInline(pVCpu, &pTb->pabOpcodes[offOpcode], cbInstr);
@@ -1176,4 +1179,43 @@
 }
 
+
+/**
+ * Emits an IRQ check call and checks for pending IRQs.
+ *
+ * @returns true if IRQs are pending and can be dispatched, false if not.
+ * @param   pVCpu       The cross context virtual CPU structure of the calling
+ *                      thread.
+ * @param   pTb         The transation block.
+ */
+static bool iemThreadedCompileCheckIrq(PVMCPUCC pVCpu, PIEMTB pTb)
+{
+    pVCpu->iem.s.cInstrTillIrqCheck = 32;
+
+    /*
+     * Emit the call first.
+     */
+    AssertReturn(pTb->Thrd.cCalls < pTb->Thrd.cAllocated, true);
+    PIEMTHRDEDCALLENTRY pCall = &pTb->Thrd.paCalls[pTb->Thrd.cCalls++];
+    pCall->enmFunction = kIemThreadedFunc_BltIn_CheckIrq;
+    pCall->uUnused0    = 0;
+    pCall->offOpcode   = 0;
+    pCall->cbOpcode    = 0;
+    pCall->idxRange    = 0;
+    pCall->auParams[0] = 0;
+    pCall->auParams[1] = 0;
+    pCall->auParams[2] = 0;
+
+
+    /*
+     * Check for IRQs.
+     */
+    uint64_t fCpu = pVCpu->fLocalForcedActions;
+    fCpu &= VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_INTERRUPT_NMI | VMCPU_FF_INTERRUPT_SMI;
+    if (RT_LIKELY(   !fCpu
+                  || (   !(fCpu & ~(VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC))
+                      && !pVCpu->cpum.GstCtx.rflags.Bits.u1IF)))
+        return false;
+    return true;
+}
 
 
@@ -1251,4 +1293,10 @@
             return iemExecStatusCodeFiddling(pVCpu, rcStrict);
         }
+
+        /* Check for IRQs? */
+        if (pVCpu->iem.s.cInstrTillIrqCheck-- > 0)
+        { /* likely */ }
+        else if (iemThreadedCompileCheckIrq(pVCpu, pTb))
+            break;
 
         /* Still space in the TB? */
Index: trunk/src/VBox/VMM/VMMAll/IEMAllThrdTables.h
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllThrdTables.h	(revision 100760)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllThrdTables.h	(revision 100761)
@@ -275,12 +275,11 @@
 
     IEM_MC2_BEGIN_EMIT_CALLS();
-    IEM_MC2_EMIT_CALL_2(kIemThreadedFunc_DeferToCImpl0, (uintptr_t)pfnCImpl, IEM_GET_INSTR_LEN(pVCpu));
+    IEM_MC2_EMIT_CALL_2(kIemThreadedFunc_BltIn_DeferToCImpl0, (uintptr_t)pfnCImpl, IEM_GET_INSTR_LEN(pVCpu));
     IEM_MC2_END_EMIT_CALLS(fFlags);
 
-    /* We have to repeat work normally done by kdCImplFlags and
-       ThreadedFunctionVariation.emitThreadedCallStmts here. */
-    if (fFlags & (IEM_CIMPL_F_END_TB | IEM_CIMPL_F_MODE | IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_BRANCH_FAR | IEM_CIMPL_F_REP))
-        pVCpu->iem.s.fEndTb = true;
-
+    /*
+     * We have to repeat work normally done by kdCImplFlags and
+     * ThreadedFunctionVariation.emitThreadedCallStmts here.
+     */
     AssertCompile(IEM_CIMPL_F_BRANCH_DIRECT      == IEMBRANCHED_F_DIRECT);
     AssertCompile(IEM_CIMPL_F_BRANCH_INDIRECT    == IEMBRANCHED_F_INDIRECT);
@@ -288,6 +287,14 @@
     AssertCompile(IEM_CIMPL_F_BRANCH_CONDITIONAL == IEMBRANCHED_F_CONDITIONAL);
     AssertCompile(IEM_CIMPL_F_BRANCH_FAR         == IEMBRANCHED_F_FAR);
-    if (fFlags & IEM_CIMPL_F_BRANCH_ANY)
+
+    if (fFlags & (IEM_CIMPL_F_END_TB | IEM_CIMPL_F_MODE | IEM_CIMPL_F_VMEXIT | IEM_CIMPL_F_BRANCH_FAR | IEM_CIMPL_F_REP))
+        pVCpu->iem.s.fEndTb = true;
+    else if (fFlags & IEM_CIMPL_F_BRANCH_ANY)
         pVCpu->iem.s.fTbBranched = fFlags & (IEM_CIMPL_F_BRANCH_ANY | IEM_CIMPL_F_BRANCH_FAR | IEM_CIMPL_F_BRANCH_CONDITIONAL);
+
+    if (fFlags & IEM_CIMPL_F_CHECK_IRQ)
+        pVCpu->iem.s.cInstrTillIrqCheck = 0;
+    else if (fFlags & IEM_CIMPL_F_CHECK_IRQ_DELAYED)
+        pVCpu->iem.s.cInstrTillIrqCheck = 1;
 
     return pfnCImpl(pVCpu, IEM_GET_INSTR_LEN(pVCpu));
Index: trunk/src/VBox/VMM/include/IEMInternal.h
===================================================================
--- trunk/src/VBox/VMM/include/IEMInternal.h	(revision 100760)
+++ trunk/src/VBox/VMM/include/IEMInternal.h	(revision 100761)
@@ -1166,6 +1166,11 @@
     /** Whether to end the current TB. */
     bool                    fEndTb;
+    /** Number of instructions before we need emit an IRQ check call again.
+     * This helps making sure we don't execute too long w/o checking for
+     * interrupts and that we can forcedly perform IRQ checks one instruction
+     * after an STI and immediately following POPF, IRETF and similar. */
+    uint8_t                 cInstrTillIrqCheck;
     /** Spaced reserved for recompiler data / alignment. */
-    bool                    afRecompilerStuff1[4];
+    bool                    afRecompilerStuff1[3];
     /** Previous GCPhysInstrBuf value - only valid if fTbCrossedPage is set.   */
     RTGCPHYS                GCPhysInstrBufPrev;
@@ -4990,4 +4995,5 @@
 IEM_DECL_IEMTHREADEDFUNC_PROTO(iemThreadedFunc_BltIn_DeferToCImpl0);
 
+IEM_DECL_IEMTHREADEDFUNC_PROTO(iemThreadedFunc_BltIn_CheckIrq);
 IEM_DECL_IEMTHREADEDFUNC_PROTO(iemThreadedFunc_BltIn_CheckMode);
 IEM_DECL_IEMTHREADEDFUNC_PROTO(iemThreadedFunc_BltIn_CheckCsLim);
Index: trunk/src/VBox/VMM/include/IEMMc.h
===================================================================
--- trunk/src/VBox/VMM/include/IEMMc.h	(revision 100760)
+++ trunk/src/VBox/VMM/include/IEMMc.h	(revision 100761)
@@ -1261,12 +1261,17 @@
 /** May change the status bits (X86_EFL_STATUS_BITS) in RFLAGS . */
 #define IEM_CIMPL_F_STATUS_FLAGS        RT_BIT_32(7)
+/** May enable interrupts, so recheck IRQ immediately afterwards. */
+#define IEM_CIMPL_F_CHECK_IRQ           RT_BIT_32(8)
+/** May enable interrupts, but actual enabling may be delayed one instruction
+ *  to do interrupt inhibiting, so recheck IRQ after the next instruction. */
+#define IEM_CIMPL_F_CHECK_IRQ_DELAYED   RT_BIT_32(9)
 /** May trigger a VM exit. */
-#define IEM_CIMPL_F_VMEXIT              RT_BIT_32(8)
+#define IEM_CIMPL_F_VMEXIT              RT_BIT_32(10)
 /** May modify FPU state. */
-#define IEM_CIMPL_F_FPU                 RT_BIT_32(9)
+#define IEM_CIMPL_F_FPU                 RT_BIT_32(11)
 /** REP prefixed instruction which may yield before updating PC. */
-#define IEM_CIMPL_F_REP                 RT_BIT_32(10)
+#define IEM_CIMPL_F_REP                 RT_BIT_32(12)
 /** Force end of TB after the instruction.    */
-#define IEM_CIMPL_F_END_TB              RT_BIT_32(11)
+#define IEM_CIMPL_F_END_TB              RT_BIT_32(13)
 /** Convenience: Raise exception (technically unnecessary, since it shouldn't return VINF_SUCCESS). */
 #define IEM_CIMPL_F_XCPT \
