Index: /trunk/src/VBox/VMM/VMMAll/IEMAllCImplStrInstr.cpp.h
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAllCImplStrInstr.cpp.h	(revision 74667)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAllCImplStrInstr.cpp.h	(revision 74668)
@@ -34,18 +34,21 @@
 
 #if ADDR_SIZE == 16
-# define ADDR_rDI   di
-# define ADDR_rSI   si
-# define ADDR_rCX   cx
-# define ADDR2_TYPE uint32_t
+# define ADDR_rDI       di
+# define ADDR_rSI       si
+# define ADDR_rCX       cx
+# define ADDR2_TYPE     uint32_t
+# define ADDR_VMXSTRIO  0
 #elif ADDR_SIZE == 32
-# define ADDR_rDI   edi
-# define ADDR_rSI   esi
-# define ADDR_rCX   ecx
-# define ADDR2_TYPE uint32_t
+# define ADDR_rDI       edi
+# define ADDR_rSI       esi
+# define ADDR_rCX       ecx
+# define ADDR2_TYPE     uint32_t
+# define ADDR_VMXSTRIO  1
 #elif ADDR_SIZE == 64
-# define ADDR_rDI   rdi
-# define ADDR_rSI   rsi
-# define ADDR_rCX   rcx
-# define ADDR2_TYPE uint64_t
+# define ADDR_rDI       rdi
+# define ADDR_rSI       rsi
+# define ADDR_rCX       rcx
+# define ADDR2_TYPE     uint64_t
+# define ADDR_VMXSTRIO  2
 # define IS_64_BIT_CODE(a_pVCpu)    (true)
 #else
@@ -1204,18 +1207,32 @@
     }
 
+    /*
+     * Check nested-guest I/O intercepts.
+     */
+#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
+    if (IEM_VMX_IS_NON_ROOT_MODE(pVCpu))
+    {
+        VMXEXITINSTRINFO ExitInstrInfo;
+        ExitInstrInfo.u = 0;
+        ExitInstrInfo.StrIo.u3AddrSize = ADDR_VMXSTRIO;
+        ExitInstrInfo.StrIo.iSegReg    = X86_SREG_ES;
+        rcStrict = iemVmxVmexitInstrStrIo(pVCpu, VMXINSTRID_IO_INS, pVCpu->cpum.GstCtx.dx, (OP_SIZE / 8) - 1, false /* fRep */,
+                                          ExitInstrInfo, cbInstr);
+        if (rcStrict != VINF_VMX_INTERCEPT_NOT_ACTIVE)
+            return rcStrict;
+    }
+#endif
+
 #ifdef VBOX_WITH_NESTED_HWVIRT_SVM
-    /*
-     * Check SVM nested-guest IO intercept.
-     */
     if (IEM_SVM_IS_CTRL_INTERCEPT_SET(pVCpu, SVM_CTRL_INTERCEPT_IOIO_PROT))
     {
-        rcStrict = iemSvmHandleIOIntercept(pVCpu, pVCpu->cpum.GstCtx.dx, SVMIOIOTYPE_IN, OP_SIZE / 8, ADDR_SIZE, X86_SREG_ES, false /* fRep */,
-                                           true /* fStrIo */, cbInstr);
+        rcStrict = iemSvmHandleIOIntercept(pVCpu, pVCpu->cpum.GstCtx.dx, SVMIOIOTYPE_IN, OP_SIZE / 8, ADDR_SIZE, X86_SREG_ES,
+                                           false /* fRep */, true /* fStrIo */, cbInstr);
         if (rcStrict == VINF_SVM_VMEXIT)
             return VINF_SUCCESS;
         if (rcStrict != VINF_SVM_INTERCEPT_NOT_ACTIVE)
         {
-            Log(("iemCImpl_ins_op: iemSvmHandleIOIntercept failed (u16Port=%#x, cbReg=%u) rc=%Rrc\n", pVCpu->cpum.GstCtx.dx, OP_SIZE / 8,
-                 VBOXSTRICTRC_VAL(rcStrict)));
+            Log(("iemCImpl_ins_op: iemSvmHandleIOIntercept failed (u16Port=%#x, cbReg=%u) rc=%Rrc\n", pVCpu->cpum.GstCtx.dx,
+                 OP_SIZE / 8, VBOXSTRICTRC_VAL(rcStrict)));
             return rcStrict;
         }
@@ -1275,8 +1292,22 @@
     }
 
+    /*
+     * Check nested-guest I/O intercepts.
+     */
+#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
+    if (IEM_VMX_IS_NON_ROOT_MODE(pVCpu))
+    {
+        VMXEXITINSTRINFO ExitInstrInfo;
+        ExitInstrInfo.u = 0;
+        ExitInstrInfo.StrIo.u3AddrSize = ADDR_VMXSTRIO;
+        ExitInstrInfo.StrIo.iSegReg    = X86_SREG_ES;
+        rcStrict = iemVmxVmexitInstrStrIo(pVCpu, VMXINSTRID_IO_INS, pVCpu->cpum.GstCtx.dx, (OP_SIZE / 8) - 1, true /* fRep */,
+                                          ExitInstrInfo, cbInstr);
+        if (rcStrict != VINF_VMX_INTERCEPT_NOT_ACTIVE)
+            return rcStrict;
+    }
+#endif
+
 #ifdef VBOX_WITH_NESTED_HWVIRT_SVM
-    /*
-     * Check SVM nested-guest IO intercept.
-     */
     if (IEM_SVM_IS_CTRL_INTERCEPT_SET(pVCpu, SVM_CTRL_INTERCEPT_IOIO_PROT))
     {
@@ -1476,18 +1507,32 @@
     }
 
+    /*
+     * Check nested-guest I/O intercepts.
+     */
+#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
+    if (IEM_VMX_IS_NON_ROOT_MODE(pVCpu))
+    {
+        VMXEXITINSTRINFO ExitInstrInfo;
+        ExitInstrInfo.u = 0;
+        ExitInstrInfo.StrIo.u3AddrSize = ADDR_VMXSTRIO;
+        ExitInstrInfo.StrIo.iSegReg    = iEffSeg;
+        rcStrict = iemVmxVmexitInstrStrIo(pVCpu, VMXINSTRID_IO_OUTS, pVCpu->cpum.GstCtx.dx, (OP_SIZE / 8) - 1, false /* fRep */,
+                                          ExitInstrInfo, cbInstr);
+        if (rcStrict != VINF_VMX_INTERCEPT_NOT_ACTIVE)
+            return rcStrict;
+    }
+#endif
+
 #ifdef VBOX_WITH_NESTED_HWVIRT_SVM
-    /*
-     * Check SVM nested-guest IO intercept.
-     */
     if (IEM_SVM_IS_CTRL_INTERCEPT_SET(pVCpu, SVM_CTRL_INTERCEPT_IOIO_PROT))
     {
-        rcStrict = iemSvmHandleIOIntercept(pVCpu, pVCpu->cpum.GstCtx.dx, SVMIOIOTYPE_OUT, OP_SIZE / 8, ADDR_SIZE, iEffSeg, false /* fRep */,
-                                           true /* fStrIo */, cbInstr);
+        rcStrict = iemSvmHandleIOIntercept(pVCpu, pVCpu->cpum.GstCtx.dx, SVMIOIOTYPE_OUT, OP_SIZE / 8, ADDR_SIZE, iEffSeg,
+                                           false /* fRep */, true /* fStrIo */, cbInstr);
         if (rcStrict == VINF_SVM_VMEXIT)
             return VINF_SUCCESS;
         if (rcStrict != VINF_SVM_INTERCEPT_NOT_ACTIVE)
         {
-            Log(("iemCImpl_outs_op: iemSvmHandleIOIntercept failed (u16Port=%#x, cbReg=%u) rc=%Rrc\n", pVCpu->cpum.GstCtx.dx, OP_SIZE / 8,
-                 VBOXSTRICTRC_VAL(rcStrict)));
+            Log(("iemCImpl_outs_op: iemSvmHandleIOIntercept failed (u16Port=%#x, cbReg=%u) rc=%Rrc\n", pVCpu->cpum.GstCtx.dx,
+                 OP_SIZE / 8, VBOXSTRICTRC_VAL(rcStrict)));
             return rcStrict;
         }
@@ -1535,8 +1580,22 @@
     }
 
+    /*
+     * Check nested-guest I/O intercepts.
+     */
+#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
+    if (IEM_VMX_IS_NON_ROOT_MODE(pVCpu))
+    {
+        VMXEXITINSTRINFO ExitInstrInfo;
+        ExitInstrInfo.u = 0;
+        ExitInstrInfo.StrIo.u3AddrSize = ADDR_VMXSTRIO;
+        ExitInstrInfo.StrIo.iSegReg    = iEffSeg;
+        rcStrict = iemVmxVmexitInstrStrIo(pVCpu, VMXINSTRID_IO_OUTS, pVCpu->cpum.GstCtx.dx, (OP_SIZE / 8) - 1, true /* fRep */,
+                                          ExitInstrInfo, cbInstr);
+        if (rcStrict != VINF_VMX_INTERCEPT_NOT_ACTIVE)
+            return rcStrict;
+    }
+#endif
+
 #ifdef VBOX_WITH_NESTED_HWVIRT_SVM
-    /*
-     * Check SVM nested-guest IO intercept.
-     */
     if (IEM_SVM_IS_CTRL_INTERCEPT_SET(pVCpu, SVM_CTRL_INTERCEPT_IOIO_PROT))
     {
@@ -1706,4 +1765,5 @@
 #undef ADDR_TYPE
 #undef ADDR2_TYPE
+#undef ADDR_VMXSTRIO
 #undef IS_64_BIT_CODE
 #undef IEM_CHECK_FF_YIELD_REPSTR_MAYBE_RETURN
