Index: /trunk/include/VBox/hwaccm.h
===================================================================
--- /trunk/include/VBox/hwaccm.h	(revision 21207)
+++ /trunk/include/VBox/hwaccm.h	(revision 21208)
@@ -109,4 +109,7 @@
 VMMR0DECL(VMCPUID) HWACCMR0GetVMCPUId(PVM pVM);
 
+VMMR0DECL(void) HWACCMR0SavePendingIOPortRead(PVMCPU pVCpu, RTGCPTR GCPtrRIP, unsigned uPort, unsigned uAndVal, unsigned cbSize);
+VMMR0DECL(void) HWACCMR0SavePendingIOPortWrite(PVMCPU pVCpu, RTGCPTR GCPtrRIP, unsigned uPort, unsigned uValue, unsigned cbSize);
+
 /** @} */
 #endif /* IN_RING0 */
Index: /trunk/src/VBox/VMM/EMHandleRCTmpl.h
===================================================================
--- /trunk/src/VBox/VMM/EMHandleRCTmpl.h	(revision 21207)
+++ /trunk/src/VBox/VMM/EMHandleRCTmpl.h	(revision 21208)
@@ -126,10 +126,10 @@
                                     PATMFL_MMIO_ACCESS | ((SELMGetCpuModeFromSelector(pVM, pCtx->eflags, pCtx->cs, &pCtx->csHid) == CPUMODE_32BIT) ? PATMFL_CODE32 : 0));
             if (RT_FAILURE(rc))
-                rc = emR3RawExecuteInstruction(pVM, pVCpu, "MMIO");
+                rc = emR3ExecuteInstruction(pVM, pVCpu, "MMIO");
             break;
 
         case VINF_PATM_HC_MMIO_PATCH_WRITE:
             AssertFailed(); /* not yet implemented. */
-            rc = emR3RawExecuteInstruction(pVM, pVCpu, "MMIO");
+            rc = emR3ExecuteInstruction(pVM, pVCpu, "MMIO");
             break;
 #endif /* EMHANDLERC_WITH_PATM */
@@ -200,5 +200,5 @@
         case VINF_IOM_HC_IOPORT_READ:
         case VINF_IOM_HC_IOPORT_WRITE:
-            rc = emR3RawExecuteIOInstruction(pVM, pVCpu);
+            rc = emR3ExecuteIOInstruction(pVM, pVCpu);
             break;
 
@@ -209,5 +209,5 @@
         case VINF_IOM_HC_MMIO_WRITE:
         case VINF_IOM_HC_MMIO_READ_WRITE:
-            rc = emR3RawExecuteInstruction(pVM, pVCpu, "MMIO");
+            rc = emR3ExecuteInstruction(pVM, pVCpu, "MMIO");
             break;
 
@@ -226,17 +226,17 @@
          */
         case VINF_EM_RAW_EMULATE_INSTR_LDT_FAULT:
-            rc = emR3RawExecuteInstruction(pVM, pVCpu, "LDT FAULT: ");
+            rc = emR3ExecuteInstruction(pVM, pVCpu, "LDT FAULT: ");
             break;
         case VINF_EM_RAW_EMULATE_INSTR_GDT_FAULT:
-            rc = emR3RawExecuteInstruction(pVM, pVCpu, "GDT FAULT: ");
+            rc = emR3ExecuteInstruction(pVM, pVCpu, "GDT FAULT: ");
             break;
         case VINF_EM_RAW_EMULATE_INSTR_IDT_FAULT:
-            rc = emR3RawExecuteInstruction(pVM, pVCpu, "IDT FAULT: ");
+            rc = emR3ExecuteInstruction(pVM, pVCpu, "IDT FAULT: ");
             break;
         case VINF_EM_RAW_EMULATE_INSTR_TSS_FAULT:
-            rc = emR3RawExecuteInstruction(pVM, pVCpu, "TSS FAULT: ");
+            rc = emR3ExecuteInstruction(pVM, pVCpu, "TSS FAULT: ");
             break;
         case VINF_EM_RAW_EMULATE_INSTR_PD_FAULT:
-            rc = emR3RawExecuteInstruction(pVM, pVCpu, "PD FAULT: ");
+            rc = emR3ExecuteInstruction(pVM, pVCpu, "PD FAULT: ");
             break;
         case VINF_EM_RAW_EMULATE_INSTR_HLT:
@@ -248,5 +248,5 @@
 #ifdef EMHANDLERC_WITH_PATM
         case VINF_PATM_PENDING_IRQ_AFTER_IRET:
-            rc = emR3RawExecuteInstruction(pVM, pVCpu, "EMUL: ", VINF_PATM_PENDING_IRQ_AFTER_IRET);
+            rc = emR3ExecuteInstruction(pVM, pVCpu, "EMUL: ", VINF_PATM_PENDING_IRQ_AFTER_IRET);
             break;
 
@@ -256,5 +256,5 @@
 #endif
         case VINF_EM_RAW_EMULATE_INSTR:
-            rc = emR3RawExecuteInstruction(pVM, pVCpu, "EMUL: ");
+            rc = emR3ExecuteInstruction(pVM, pVCpu, "EMUL: ");
             break;
 
Index: /trunk/src/VBox/VMM/EMHwaccm.cpp
===================================================================
--- /trunk/src/VBox/VMM/EMHwaccm.cpp	(revision 21207)
+++ /trunk/src/VBox/VMM/EMHwaccm.cpp	(revision 21208)
@@ -78,6 +78,6 @@
 *   Internal Functions                                                         *
 *******************************************************************************/
-DECLINLINE(int) emR3RawExecuteInstruction(PVM pVM, PVMCPU pVCpu, const char *pszPrefix, int rcGC = VINF_SUCCESS);
-static int emR3RawExecuteIOInstruction(PVM pVM, PVMCPU pVCpu);
+DECLINLINE(int) emR3ExecuteInstruction(PVM pVM, PVMCPU pVCpu, const char *pszPrefix, int rcGC = VINF_SUCCESS);
+static int emR3ExecuteIOInstruction(PVM pVM, PVMCPU pVCpu);
 static int emR3HwaccmForcedActions(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
 
@@ -181,7 +181,7 @@
  */
 #ifdef LOG_ENABLED
-static int emR3RawExecuteInstructionWorker(PVM pVM, PVMCPU pVCpu, int rcGC, const char *pszPrefix)
+static int emR3ExecuteInstructionWorker(PVM pVM, PVMCPU pVCpu, int rcGC, const char *pszPrefix)
 #else
-static int emR3RawExecuteInstructionWorker(PVM pVM, PVMCPU pVCpu, int rcGC)
+static int emR3ExecuteInstructionWorker(PVM pVM, PVMCPU pVCpu, int rcGC)
 #endif
 {
@@ -277,10 +277,10 @@
  * @param   rcGC        GC return code
  */
-DECLINLINE(int) emR3RawExecuteInstruction(PVM pVM, PVMCPU pVCpu, const char *pszPrefix, int rcGC)
+DECLINLINE(int) emR3ExecuteInstruction(PVM pVM, PVMCPU pVCpu, const char *pszPrefix, int rcGC)
 {
 #ifdef LOG_ENABLED
-    return emR3RawExecuteInstructionWorker(pVM, pVCpu, rcGC, pszPrefix);
+    return emR3ExecuteInstructionWorker(pVM, pVCpu, rcGC, pszPrefix);
 #else
-    return emR3RawExecuteInstructionWorker(pVM, pVCpu, rcGC);
+    return emR3ExecuteInstructionWorker(pVM, pVCpu, rcGC);
 #endif
 }
@@ -293,5 +293,5 @@
  * @param   pVCpu       VMCPU handle.
  */
-static int emR3RawExecuteIOInstruction(PVM pVM, PVMCPU pVCpu)
+static int emR3ExecuteIOInstruction(PVM pVM, PVMCPU pVCpu)
 {
     int         rc;
@@ -378,5 +378,5 @@
     }
     STAM_PROFILE_STOP(&pVCpu->em.s.StatIOEmu, a);
-    return emR3RawExecuteInstruction(pVM, pVCpu, "IO: ");
+    return emR3ExecuteInstruction(pVM, pVCpu, "IO: ");
 }
 
Index: /trunk/src/VBox/VMM/EMRaw.cpp
===================================================================
--- /trunk/src/VBox/VMM/EMRaw.cpp	(revision 21207)
+++ /trunk/src/VBox/VMM/EMRaw.cpp	(revision 21208)
@@ -80,10 +80,10 @@
 *******************************************************************************/
 static int emR3RawForcedActions(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
-DECLINLINE(int) emR3RawExecuteInstruction(PVM pVM, PVMCPU pVCpu, const char *pszPrefix, int rcGC = VINF_SUCCESS);
+DECLINLINE(int) emR3ExecuteInstruction(PVM pVM, PVMCPU pVCpu, const char *pszPrefix, int rcGC = VINF_SUCCESS);
 static int emR3RawGuestTrap(PVM pVM, PVMCPU pVCpu);
 static int emR3PatchTrap(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, int gcret);
 static int emR3SingleStepExecRem(PVM pVM, uint32_t cIterations);
 static int emR3RawPrivileged(PVM pVM, PVMCPU pVCpu);
-static int emR3RawExecuteIOInstruction(PVM pVM, PVMCPU pVCpu);
+static int emR3ExecuteIOInstruction(PVM pVM, PVMCPU pVCpu);
 static int emR3RawRingSwitch(PVM pVM, PVMCPU pVCpu);
 
@@ -323,7 +323,7 @@
  */
 #ifdef LOG_ENABLED
-static int emR3RawExecuteInstructionWorker(PVM pVM, PVMCPU pVCpu, int rcGC, const char *pszPrefix)
+static int emR3ExecuteInstructionWorker(PVM pVM, PVMCPU pVCpu, int rcGC, const char *pszPrefix)
 #else
-static int emR3RawExecuteInstructionWorker(PVM pVM, PVMCPU pVCpu, int rcGC)
+static int emR3ExecuteInstructionWorker(PVM pVM, PVMCPU pVCpu, int rcGC)
 #endif
 {
@@ -358,5 +358,5 @@
     if (PATMIsPatchGCAddr(pVM, pCtx->eip))
     {
-        Log(("emR3RawExecuteInstruction: In patch block. eip=%RRv\n", (RTRCPTR)pCtx->eip));
+        Log(("emR3ExecuteInstruction: In patch block. eip=%RRv\n", (RTRCPTR)pCtx->eip));
 
         RTGCPTR pNewEip;
@@ -369,5 +369,5 @@
              */
             case VINF_SUCCESS:
-                Log(("emR3RawExecuteInstruction: Executing instruction starting at new address %RGv IF=%d VMIF=%x\n",
+                Log(("emR3ExecuteInstruction: Executing instruction starting at new address %RGv IF=%d VMIF=%x\n",
                      pNewEip, pCtx->eflags.Bits.u1IF, pVCpu->em.s.pPatmGCState->uVMFlags));
                 pCtx->eip = pNewEip;
@@ -380,10 +380,10 @@
                      */
                     Log(("PATCH: IF=1 -> emulate last instruction as it can't be interrupted!!\n"));
-                    return emR3RawExecuteInstruction(pVM, pVCpu, "PATCHIR");
+                    return emR3ExecuteInstruction(pVM, pVCpu, "PATCHIR");
                 }
                 else if (rcGC == VINF_PATM_PENDING_IRQ_AFTER_IRET)
                 {
                     /* special case: iret, that sets IF,  detected a pending irq/event */
-                    return emR3RawExecuteInstruction(pVM, pVCpu, "PATCHIRET");
+                    return emR3ExecuteInstruction(pVM, pVCpu, "PATCHIRET");
                 }
                 return VINF_EM_RESCHEDULE_REM;
@@ -393,8 +393,8 @@
              */
             case VINF_PATCH_EMULATE_INSTR:
-                Log(("emR3RawExecuteInstruction: Emulate patched instruction at %RGv IF=%d VMIF=%x\n",
+                Log(("emR3ExecuteInstruction: Emulate patched instruction at %RGv IF=%d VMIF=%x\n",
                      pNewEip, pCtx->eflags.Bits.u1IF, pVCpu->em.s.pPatmGCState->uVMFlags));
                 pCtx->eip = pNewEip;
-                return emR3RawExecuteInstruction(pVM, pVCpu, "PATCHIR");
+                return emR3ExecuteInstruction(pVM, pVCpu, "PATCHIR");
 
             /*
@@ -402,5 +402,5 @@
              */
             case VERR_PATCH_DISABLED:
-                Log(("emR3RawExecuteInstruction: Disabled patch -> new eip %RGv IF=%d VMIF=%x\n",
+                Log(("emR3ExecuteInstruction: Disabled patch -> new eip %RGv IF=%d VMIF=%x\n",
                      pNewEip, pCtx->eflags.Bits.u1IF, pVCpu->em.s.pPatmGCState->uVMFlags));
                 pCtx->eip = pNewEip;
@@ -411,5 +411,5 @@
                      */
                     Log(("PATCH: IF=1 -> emulate last instruction as it can't be interrupted!!\n"));
-                    return emR3RawExecuteInstruction(pVM, pVCpu, "PATCHIR");
+                    return emR3ExecuteInstruction(pVM, pVCpu, "PATCHIR");
                 }
                 return VINF_EM_RESCHEDULE_REM;
@@ -486,10 +486,10 @@
  * @param   rcGC        GC return code
  */
-DECLINLINE(int) emR3RawExecuteInstruction(PVM pVM, PVMCPU pVCpu, const char *pszPrefix, int rcGC)
+DECLINLINE(int) emR3ExecuteInstruction(PVM pVM, PVMCPU pVCpu, const char *pszPrefix, int rcGC)
 {
 #ifdef LOG_ENABLED
-    return emR3RawExecuteInstructionWorker(pVM, pVCpu, rcGC, pszPrefix);
+    return emR3ExecuteInstructionWorker(pVM, pVCpu, rcGC, pszPrefix);
 #else
-    return emR3RawExecuteInstructionWorker(pVM, pVCpu, rcGC);
+    return emR3ExecuteInstructionWorker(pVM, pVCpu, rcGC);
 #endif
 }
@@ -502,5 +502,5 @@
  * @param   pVCpu       VMCPU handle.
  */
-static int emR3RawExecuteIOInstruction(PVM pVM, PVMCPU pVCpu)
+static int emR3ExecuteIOInstruction(PVM pVM, PVMCPU pVCpu)
 {
     int         rc;
@@ -586,5 +586,5 @@
     }
     STAM_PROFILE_STOP(&pVCpu->em.s.StatIOEmu, a);
-    return emR3RawExecuteInstruction(pVM, pVCpu, "IO: ");
+    return emR3ExecuteInstruction(pVM, pVCpu, "IO: ");
 }
 
@@ -702,5 +702,5 @@
                     return rc;
                 }
-                return emR3RawExecuteInstruction(pVM, pVCpu, "Monitor: ");
+                return emR3ExecuteInstruction(pVM, pVCpu, "Monitor: ");
             }
         }
@@ -724,5 +724,5 @@
             rc = TRPMResetTrap(pVCpu);
             AssertRC(rc);
-            return emR3RawExecuteInstruction(pVM, pVCpu, "IO Guest Trap: ");
+            return emR3ExecuteInstruction(pVM, pVCpu, "IO Guest Trap: ");
         }
     }
@@ -809,5 +809,5 @@
 
     /* go to the REM to emulate a single instruction */
-    return emR3RawExecuteInstruction(pVM, pVCpu, "RSWITCH: ");
+    return emR3ExecuteInstruction(pVM, pVCpu, "RSWITCH: ");
 }
 
@@ -947,5 +947,5 @@
                     /* Note: possibly because a reschedule is required (e.g. iret to V86 code) */
 
-                    return emR3RawExecuteInstruction(pVM, pVCpu, "PATCHIR");
+                    return emR3ExecuteInstruction(pVM, pVCpu, "PATCHIR");
                     /* Interrupts are enabled; just go back to the original instruction.
                     return VINF_SUCCESS; */
@@ -962,5 +962,5 @@
                 pCtx->eip = pNewEip;
                 AssertRelease(pCtx->eip);
-                return emR3RawExecuteInstruction(pVM, pVCpu, "PATCHEMUL: ");
+                return emR3ExecuteInstruction(pVM, pVCpu, "PATCHEMUL: ");
 
             /*
@@ -979,5 +979,5 @@
                      */
                     Log(("PATCH: IF=1 -> emulate last instruction as it can't be interrupted!!\n"));
-                    return emR3RawExecuteInstruction(pVM, pVCpu, "PATCHIR");
+                    return emR3ExecuteInstruction(pVM, pVCpu, "PATCHIR");
                 }
                 return VINF_EM_RESCHEDULE_REM;
@@ -1242,5 +1242,5 @@
         return emR3PatchTrap(pVM, pVCpu, pCtx, VINF_PATM_PATCH_TRAP_GP);
 
-    return emR3RawExecuteInstruction(pVM, pVCpu, "PRIV");
+    return emR3ExecuteInstruction(pVM, pVCpu, "PRIV");
 }
 
Index: /trunk/src/VBox/VMM/HWACCMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/HWACCMInternal.h	(revision 21207)
+++ /trunk/src/VBox/VMM/HWACCMInternal.h	(revision 21208)
@@ -168,4 +168,15 @@
     uint64_t            u;
 } VMX_CAPABILITY;
+
+typedef enum
+{
+    HWACCMPENDINGIO_INVALID = 0,
+    HWACCMPENDINGIO_PORT_READ,
+    HWACCMPENDINGIO_PORT_WRITE,
+    HWACCMPENDINGIO_STRING_READ,
+    HWACCMPENDINGIO_STRING_WRITE,
+    /** The usual 32-bit paranoia. */
+    HWACCMPENDINGIO_32BIT_HACK   = 0x7fffffff
+} HWACCMPENDINGIO;
 
 /**
@@ -582,4 +593,29 @@
         uint64_t                cr0;
     } EmulateIoBlock;
+
+    struct
+    {
+        /* Pending IO operation type. */
+        HWACCMPENDINGIO         enmType;
+        uint32_t                uPadding;
+        union
+        {
+            struct
+            {
+                RTGCPTR         rip;
+                unsigned        uPort;
+                unsigned        uAndVal;
+                unsigned        cbSize;
+            } Read;
+            struct
+            {
+                RTGCPTR         rip;
+                unsigned        uPort;
+                unsigned        uValue;
+                unsigned        cbSize;
+            } Write;
+            uint64_t            aRaw[4];
+        } Port;
+    } PendingIO;
 
     /** Currenty shadow paging mode. */
Index: /trunk/src/VBox/VMM/VMMR0/HWACCMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HWACCMR0.cpp	(revision 21207)
+++ /trunk/src/VBox/VMM/VMMR0/HWACCMR0.cpp	(revision 21208)
@@ -1218,4 +1218,42 @@
 
     return 0;
+}
+
+/**
+ * Save a pending IO read.
+ *
+ * @param   pVCpu           The VMCPU to operate on.
+ * @param   GCPtrRIP        Address of IO instruction
+ * @param   uPort           Port address
+ * @param   uAndVal         And mask for saving the result in eax
+ * @param   cbSize          Read size
+ */
+VMMR0DECL(void) HWACCMR0SavePendingIOPortRead(PVMCPU pVCpu, RTGCPTR GCPtrRIP, unsigned uPort, unsigned uAndVal, unsigned cbSize)
+{
+    pVCpu->hwaccm.s.PendingIO.enmType       = HWACCMPENDINGIO_PORT_READ;
+    pVCpu->hwaccm.s.PendingIO.Port.Read.rip      = GCPtrRIP;
+    pVCpu->hwaccm.s.PendingIO.Port.Read.uPort    = uPort;
+    pVCpu->hwaccm.s.PendingIO.Port.Read.uAndVal  = uAndVal;
+    pVCpu->hwaccm.s.PendingIO.Port.Read.cbSize   = cbSize;
+    return;
+}
+
+/**
+ * Save a pending IO write.
+ *
+ * @param   pVCpu           The VMCPU to operate on.
+ * @param   GCPtrRIP        Address of IO instruction
+ * @param   uPort           Port address
+ * @param   uValue          Value to write
+ * @param   cbSize          Read size
+ */
+VMMR0DECL(void) HWACCMR0SavePendingIOPortWrite(PVMCPU pVCpu, RTGCPTR GCPtrRIP, unsigned uPort, unsigned uValue, unsigned cbSize)
+{
+    pVCpu->hwaccm.s.PendingIO.enmType        = HWACCMPENDINGIO_PORT_WRITE;
+    pVCpu->hwaccm.s.PendingIO.Port.Write.rip      = GCPtrRIP;
+    pVCpu->hwaccm.s.PendingIO.Port.Write.uPort    = uPort;
+    pVCpu->hwaccm.s.PendingIO.Port.Write.uValue   = uValue;
+    pVCpu->hwaccm.s.PendingIO.Port.Write.cbSize   = cbSize;
+    return;
 }
 
Index: /trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp	(revision 21207)
+++ /trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp	(revision 21208)
@@ -2108,4 +2108,6 @@
                 STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitIOWrite);
                 rc = IOMIOPortWrite(pVM, IoExitInfo.n.u16Port, pCtx->eax & uAndVal, uIOSize);
+                if (rc == VINF_IOM_HC_IOPORT_WRITE)
+                    HWACCMR0SavePendingIOPortWrite(pVCpu, pCtx->rip, IoExitInfo.n.u16Port, pCtx->eax & uAndVal, uIOSize);
             }
             else
@@ -2121,4 +2123,7 @@
                     Log2(("IOMIOPortRead %RGv %x %x size=%d\n", (RTGCPTR)pCtx->rip, IoExitInfo.n.u16Port, u32Val & uAndVal, uIOSize));
                 }
+                else
+                if (rc == VINF_IOM_HC_IOPORT_READ)
+                    HWACCMR0SavePendingIOPortRead(pVCpu, pCtx->rip, IoExitInfo.n.u16Port, uAndVal, uIOSize);
             }
         }
Index: /trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp	(revision 21207)
+++ /trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp	(revision 21208)
@@ -3391,4 +3391,6 @@
                 STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitIOWrite);
                 rc = IOMIOPortWrite(pVM, uPort, pCtx->eax & uAndVal, cbSize);
+                if (rc == VINF_IOM_HC_IOPORT_WRITE)
+                    HWACCMR0SavePendingIOPortWrite(pVCpu, pCtx->rip, uPort, pCtx->eax & uAndVal, cbSize);
             }
             else
@@ -3403,4 +3405,7 @@
                     pCtx->eax = (pCtx->eax & ~uAndVal) | (u32Val & uAndVal);
                 }
+                else
+                if (rc == VINF_IOM_HC_IOPORT_READ)
+                    HWACCMR0SavePendingIOPortRead(pVCpu, pCtx->rip, uPort, uAndVal, cbSize);
             }
         }
