Index: /trunk/include/VBox/vmm/rem.h
===================================================================
--- /trunk/include/VBox/vmm/rem.h	(revision 62286)
+++ /trunk/include/VBox/vmm/rem.h	(revision 62287)
@@ -86,6 +86,4 @@
 REMR3DECL(void) REMR3NotifyHandlerPhysicalDeregister(PVM pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhys, RTGCPHYS cb, bool fHasHCHandler, bool fRestoreAsRAM);
 REMR3DECL(void) REMR3NotifyHandlerPhysicalModify(PVM pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhysOld, RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fHasHCHandler, bool fRestoreAsRAM);
-REMR3DECL(void) REMR3NotifyPendingInterrupt(PVM pVM, PVMCPU pVCpu, uint8_t u8Interrupt);
-REMR3DECL(uint32_t) REMR3QueryPendingInterrupt(PVM pVM, PVMCPU pVCpu);
 REMR3DECL(void) REMR3NotifyInterruptSet(PVM pVM, PVMCPU pVCpu);
 REMR3DECL(void) REMR3NotifyInterruptClear(PVM pVM, PVMCPU pVCpu);
Index: /trunk/src/VBox/VMM/VMMR3/EM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/EM.cpp	(revision 62286)
+++ /trunk/src/VBox/VMM/VMMR3/EM.cpp	(revision 62287)
@@ -1990,13 +1990,4 @@
                 fWakeupPending = true;
             }
-#ifdef VBOX_WITH_REM
-            /** @todo really ugly; if we entered the hlt state when exiting the recompiler and an interrupt was pending, we previously got stuck in the halted state. */
-            else if (REMR3QueryPendingInterrupt(pVM, pVCpu) != REM_NO_PENDING_IRQ)
-            {
-                Log2(("REMR3QueryPendingInterrupt -> %#x\n", REMR3QueryPendingInterrupt(pVM, pVCpu)));
-                rc2 = VINF_EM_RESCHEDULE_REM;
-                UPDATE_RC();
-            }
-#endif
         }
 
Index: /trunk/src/VBox/VMM/VMMR3/EMRaw.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/EMRaw.cpp	(revision 62286)
+++ /trunk/src/VBox/VMM/VMMR3/EMRaw.cpp	(revision 62287)
@@ -1304,7 +1304,4 @@
          */
 #ifdef VBOX_STRICT
-# ifdef VBOX_WITH_REM
-        Assert(REMR3QueryPendingInterrupt(pVM, pVCpu) == REM_NO_PENDING_IRQ);
-# endif
         Assert(pCtx->eflags.Bits.u1VM || (pCtx->ss.Sel & X86_SEL_RPL) == 3 || (pCtx->ss.Sel & X86_SEL_RPL) == 0
                || (EMIsRawRing1Enabled(pVM) && (pCtx->ss.Sel & X86_SEL_RPL) == 1));
Index: /trunk/src/VBox/VMM/VMMR3/TRPM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/TRPM.cpp	(revision 62286)
+++ /trunk/src/VBox/VMM/VMMR3/TRPM.cpp	(revision 62287)
@@ -1496,9 +1496,5 @@
     Assert(enmEvent == TRPM_HARDWARE_INT);
 
-    if (   !EMIsSupervisorCodeRecompiled(pVM)
-#ifdef VBOX_WITH_REM
-        && REMR3QueryPendingInterrupt(pVM, pVCpu) == REM_NO_PENDING_IRQ
-#endif
-        )
+    if (!EMIsSupervisorCodeRecompiled(pVM))
     {
 #ifdef TRPM_FORWARD_TRAPS_IN_GC
@@ -1550,12 +1546,6 @@
                 STAM_COUNTER_INC(&pVM->trpm.s.StatForwardFailNoHandler);
 
-# if 1
             rc = TRPMAssertTrap(pVCpu, u8Interrupt, enmEvent);
             AssertRCReturn(rc, rc);
-# else
-#  ifdef VBOX_WITH_REM
-            REMR3NotifyPendingInterrupt(pVM, pVCpu, u8Interrupt);
-#  endif
-#endif
         }
         else
Index: /trunk/src/VBox/VMM/include/REMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/REMInternal.h	(revision 62286)
+++ /trunk/src/VBox/VMM/include/REMInternal.h	(revision 62287)
@@ -156,6 +156,6 @@
     uint32_t                cCanExecuteRaw;
 
-    /** Pending interrupt (~0 -> nothing). */
-    uint32_t                u32PendingInterrupt;
+    /** Pending interrupt that remR3LoadDone will assert with TRPM. */
+    uint32_t                uStateLoadPendingInterrupt;
 
     /** Number of recorded invlpg instructions. */
Index: /trunk/src/recompiler/VBoxREM.def
===================================================================
--- /trunk/src/recompiler/VBoxREM.def	(revision 62286)
+++ /trunk/src/recompiler/VBoxREM.def	(revision 62287)
@@ -5,5 +5,5 @@
 
 ;
-; Copyright (C) 2006-2011 Oracle Corporation
+; Copyright (C) 2006-2016 Oracle Corporation
 ;
 ; This file is part of VirtualBox Open Source Edition (OSE), as
@@ -48,5 +48,3 @@
     REMR3NotifyCodePageChanged
     REMR3IsPageAccessHandled
-    REMR3NotifyPendingInterrupt
-    REMR3QueryPendingInterrupt
 
Index: /trunk/src/recompiler/VBoxREMWrapper.cpp
===================================================================
--- /trunk/src/recompiler/VBoxREMWrapper.cpp	(revision 62286)
+++ /trunk/src/recompiler/VBoxREMWrapper.cpp	(revision 62287)
@@ -5,5 +5,5 @@
  */
 /*
- * Copyright (C) 2006-2013 Oracle Corporation
+ * Copyright (C) 2006-2016 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -376,6 +376,4 @@
 static DECLCALLBACKPTR(void, pfnREMR3NotifyFF)(PVM);
 static DECLCALLBACKPTR(int, pfnREMR3NotifyCodePageChanged)(PVM, PVMCPU, RTGCPTR);
-static DECLCALLBACKPTR(void, pfnREMR3NotifyPendingInterrupt)(PVM, PVMCPU, uint8_t);
-static DECLCALLBACKPTR(uint32_t, pfnREMR3QueryPendingInterrupt)(PVM, PVMCPU);
 static DECLCALLBACKPTR(int, pfnREMR3DisasEnableStepping)(PVM, bool);
 static DECLCALLBACKPTR(bool, pfnREMR3IsPageAccessHandled)(PVM, RTGCPHYS);
@@ -1200,6 +1198,4 @@
     { "REMR3NotifyFF",                          (void *)&pfnREMR3NotifyFF,                          &g_aArgsVM[0],                              RT_ELEMENTS(g_aArgsVM),                                REMFNDESC_FLAGS_RET_VOID,   0,              NULL },
     { "REMR3NotifyCodePageChanged",             (void *)&pfnREMR3NotifyCodePageChanged,             &g_aArgsNotifyCodePageChanged[0],           RT_ELEMENTS(g_aArgsNotifyCodePageChanged),             REMFNDESC_FLAGS_RET_INT,    sizeof(int),    NULL },
-    { "REMR3NotifyPendingInterrupt",            (void *)&pfnREMR3NotifyPendingInterrupt,            &g_aArgsNotifyPendingInterrupt[0],          RT_ELEMENTS(g_aArgsNotifyPendingInterrupt),            REMFNDESC_FLAGS_RET_VOID,   0,              NULL },
-    { "REMR3QueryPendingInterrupt",             (void *)&pfnREMR3QueryPendingInterrupt,             &g_aArgsVMandVMCPU[0],                      RT_ELEMENTS(g_aArgsVMandVMCPU),                        REMFNDESC_FLAGS_RET_INT,    sizeof(uint32_t), NULL },
     { "REMR3DisasEnableStepping",               (void *)&pfnREMR3DisasEnableStepping,               &g_aArgsDisasEnableStepping[0],             RT_ELEMENTS(g_aArgsDisasEnableStepping),               REMFNDESC_FLAGS_RET_INT,    sizeof(int),    NULL },
     { "REMR3IsPageAccessHandled",               (void *)&pfnREMR3IsPageAccessHandled,               &g_aArgsIsPageAccessHandled[0],             RT_ELEMENTS(g_aArgsIsPageAccessHandled),               REMFNDESC_FLAGS_RET_INT,    sizeof(bool),   NULL }
@@ -2448,22 +2444,4 @@
 }
 
-REMR3DECL(void) REMR3NotifyPendingInterrupt(PVM pVM, PVMCPU pVCpu, uint8_t u8Interrupt)
-{
-#ifndef USE_REM_STUBS
-    Assert(VALID_PTR(pfnREMR3NotifyPendingInterrupt));
-    pfnREMR3NotifyPendingInterrupt(pVM, pVCpu, u8Interrupt);
-#endif
-}
-
-REMR3DECL(uint32_t) REMR3QueryPendingInterrupt(PVM pVM, PVMCPU pVCpu)
-{
-#ifdef USE_REM_STUBS
-    return REM_NO_PENDING_IRQ;
-#else
-    Assert(VALID_PTR(pfnREMR3QueryPendingInterrupt));
-    return pfnREMR3QueryPendingInterrupt(pVM, pVCpu);
-#endif
-}
-
 REMR3DECL(void) REMR3NotifyInterruptSet(PVM pVM, PVMCPU pVCpu)
 {
Index: /trunk/src/recompiler/VBoxRecompiler.c
===================================================================
--- /trunk/src/recompiler/VBoxRecompiler.c	(revision 62286)
+++ /trunk/src/recompiler/VBoxRecompiler.c	(revision 62287)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2006-2013 Oracle Corporation
+ * Copyright (C) 2006-2016 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -112,4 +112,5 @@
 static DECLCALLBACK(int) remR3Save(PVM pVM, PSSMHANDLE pSSM);
 static DECLCALLBACK(int) remR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass);
+static DECLCALLBACK(int) remR3LoadDone(PVM pVM, PSSMHANDLE pSSM);
 static void     remR3StateUpdate(PVM pVM, PVMCPU pVCpu);
 static int      remR3InitPhysRamSizeAndDirtyMap(PVM pVM, bool fGuarded);
@@ -352,5 +353,5 @@
 
     /* Nothing is pending by default */
-    pVM->rem.s.u32PendingInterrupt = REM_NO_PENDING_IRQ;
+    pVM->rem.s.uStateLoadPendingInterrupt = REM_NO_PENDING_IRQ;
 
     /*
@@ -372,5 +373,5 @@
                                NULL, NULL, NULL,
                                NULL, remR3Save, NULL,
-                               NULL, remR3Load, NULL);
+                               NULL, remR3Load, remR3LoadDone);
     if (RT_FAILURE(rc))
         return rc;
@@ -637,5 +638,5 @@
     /* Remember if we've entered raw mode (vital for ring 1 checks in e.g. iret emulation). */
     SSMR3PutU32(pSSM, !!(pRem->Env.state & CPU_RAW_RING0));
-    SSMR3PutU32(pSSM, pVM->rem.s.u32PendingInterrupt);
+    SSMR3PutU32(pSSM, REM_NO_PENDING_IRQ);
 
     return SSMR3PutU32(pSSM, ~0);       /* terminator */
@@ -732,7 +733,10 @@
     }
 
-    rc = SSMR3GetUInt(pSSM, &pVM->rem.s.u32PendingInterrupt);
-    if (RT_FAILURE(rc))
-        return rc;
+    rc = SSMR3GetUInt(pSSM, &pVM->rem.s.uStateLoadPendingInterrupt);
+    AssertRCReturn(rc, rc);
+    AssertLogRelMsgReturn(   pVM->rem.s.uStateLoadPendingInterrupt == REM_NO_PENDING_IRQ
+                          || pVM->rem.s.uStateLoadPendingInterrupt < 256,
+                          ("uStateLoadPendingInterrupt=%#x\n", pVM->rem.s.uStateLoadPendingInterrupt),
+                          VERR_SSM_UNEXPECTED_DATA);
 
     /* check the terminator. */
@@ -769,4 +773,19 @@
 }
 
+
+/**
+ * @callback_method_impl{FNSSMINTLOADDONE,
+ *    For pushing misdesigned pending-interrupt mess to TRPM where it belongs. }
+ */
+static DECLCALLBACK(int) remR3LoadDone(PVM pVM, PSSMHANDLE pSSM)
+{
+    if (pVM->rem.s.uStateLoadPendingInterrupt != REM_NO_PENDING_IRQ)
+    {
+        int rc = TRPMAssertTrap(&pVM->aCpus[0], pVM->rem.s.uStateLoadPendingInterrupt, TRPM_HARDWARE_INT);
+        AssertLogRelMsgReturn(rc, ("uStateLoadPendingInterrupt=%#x rc=%Rrc\n", pVM->rem.s.uStateLoadPendingInterrupt, rc), rc);
+        pVM->rem.s.uStateLoadPendingInterrupt = REM_NO_PENDING_IRQ;
+    }
+    return VINF_SUCCESS;
+}
 
 
@@ -1119,6 +1138,5 @@
         pVM->rem.s.Env.interrupt_request = CPU_INTERRUPT_SINGLE_INSTR;
 #endif
-        if (   VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_UPDATE_APIC | VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC)
-            || pVM->rem.s.u32PendingInterrupt != REM_NO_PENDING_IRQ)
+        if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_UPDATE_APIC | VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC))
             pVM->rem.s.Env.interrupt_request |= CPU_INTERRUPT_HARD;
         RTLogPrintf("remR3RunLoggingStep: interrupt_request=%#x halted=%d exception_index=%#x\n",
@@ -2520,9 +2538,6 @@
         APICUpdatePendingInterrupts(pVCpu);
 #endif
-    if (    pVM->rem.s.u32PendingInterrupt != REM_NO_PENDING_IRQ
-        ||  VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC))
-    {
+    if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC))
         pVM->rem.s.Env.interrupt_request |= CPU_INTERRUPT_HARD;
-    }
 
     /*
@@ -4242,32 +4257,4 @@
 
 /* -+- FF notifications -+- */
-
-
-/**
- * Notification about a pending interrupt.
- *
- * @param   pVM             VM Handle.
- * @param   pVCpu           VMCPU Handle.
- * @param   u8Interrupt     Interrupt
- * @thread  The emulation thread.
- */
-REMR3DECL(void) REMR3NotifyPendingInterrupt(PVM pVM, PVMCPU pVCpu, uint8_t u8Interrupt)
-{
-    Assert(pVM->rem.s.u32PendingInterrupt == REM_NO_PENDING_IRQ);
-    pVM->rem.s.u32PendingInterrupt = u8Interrupt;
-}
-
-/**
- * Notification about a pending interrupt.
- *
- * @returns Pending interrupt or REM_NO_PENDING_IRQ
- * @param   pVM             VM Handle.
- * @param   pVCpu           VMCPU Handle.
- * @thread  The emulation thread.
- */
-REMR3DECL(uint32_t) REMR3QueryPendingInterrupt(PVM pVM, PVMCPU pVCpu)
-{
-    return pVM->rem.s.u32PendingInterrupt;
-}
 
 /**
@@ -4521,17 +4508,5 @@
      */
     /* Note! We assume we will go directly to the recompiler to handle the pending interrupt! */
-    /** @todo r=bird: In the long run we should just do the interrupt handling in EM/CPUM/TRPM/somewhere and
-     * if we cannot execute the interrupt handler in raw-mode just reschedule to REM. Once that is done we
-     * remove this kludge. */
-    if (env->pVM->rem.s.u32PendingInterrupt != REM_NO_PENDING_IRQ)
-    {
-        rc = VINF_SUCCESS;
-        Assert(env->pVM->rem.s.u32PendingInterrupt <= 255);
-        u8Interrupt = env->pVM->rem.s.u32PendingInterrupt;
-        env->pVM->rem.s.u32PendingInterrupt = REM_NO_PENDING_IRQ;
-    }
-    else
-        rc = PDMGetInterrupt(env->pVCpu, &u8Interrupt);
-
+    rc = PDMGetInterrupt(env->pVCpu, &u8Interrupt);
     LogFlow(("cpu_get_pic_interrupt: u8Interrupt=%d rc=%Rrc pc=%04x:%08llx ~flags=%08llx\n",
              u8Interrupt, rc, env->segs[R_CS].selector, (uint64_t)env->eip, (uint64_t)env->eflags));
