Index: trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h	(revision 73937)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h	(revision 73959)
@@ -1041,17 +1041,19 @@
  * @param   pVCpu           The cross context virtual CPU structure.
  * @param   cbInstr         The instruction length.
+ * @param   iEffSeg         The effective segment register to use with @a u64Val.
+ *                          Pass UINT8_MAX if it is a register access.
+ * @param   enmEffAddrMode  The effective addressing mode.
+ * @param   u64Val          The value to write (or guest linear address to the
+ *                          value), @a iEffSeg will indicate if it's a memory
+ *                          operand.
  * @param   uFieldEnc       The VMCS field encoding.
- * @param   u64Val          The value to write (or guest linear address to the
- *                          value), @a pExitInstrInfo will indicate whether it's a
- *                          memory or register operand.
- * @param   pExitInstrInfo  Pointer to the VM-exit instruction information field.
- * @param   GCPtrDisp       The displacement field for @a GCPtrVmcs if any.
- */
-IEM_STATIC VBOXSTRICTRC iemVmxVmwrite(PVMCPU pVCpu, uint8_t cbInstr, uint32_t uFieldEnc, uint64_t u64Val,
-                                      PCVMXEXITINSTRINFO pExitInstrInfo, RTGCPTR GCPtrDisp)
+ * @param   pExitInfo       Pointer to the VM-exit information struct.
+ */
+IEM_STATIC VBOXSTRICTRC iemVmxVmwrite(PVMCPU pVCpu, uint8_t cbInstr, uint8_t iEffSeg, IEMMODE enmEffAddrMode,
+                                      uint64_t u64Val, uint32_t uFieldEnc, PCVMXVEXITINFO pExitInfo)
 {
     if (IEM_IS_VMX_NON_ROOT_MODE(pVCpu))
     {
-        RT_NOREF(GCPtrDisp);
+        RT_NOREF(pExitInfo);
         /** @todo NSTVMX: intercept. */
         /** @todo NSTVMX: VMCS shadowing intercept (VMREAD/VMWRITE bitmap). */
@@ -1089,19 +1091,19 @@
 
     /* If the VMWRITE instruction references memory, access the specified in memory operand. */
-    if (!pExitInstrInfo->VmreadVmwrite.fIsRegOperand)
-    {
-        uint8_t const uAddrSize = pExitInstrInfo->VmreadVmwrite.u3AddrSize;
-        static uint64_t const s_auAddrSizeMasks[] = { UINT64_C(0xffff), UINT64_C(0xffffffff), UINT64_C(0xffffffffffffffff), 0 };
-        AssertRCReturn(uAddrSize != 3, VERR_IEM_IPE_1);
-        RTGCPTR const GCPtrVal = u64Val & s_auAddrSizeMasks[uAddrSize];
+    bool const fIsRegOperand = iEffSeg == UINT8_MAX;
+    if (fIsRegOperand)
+    {
+        static uint64_t const s_auAddrSizeMasks[] = { UINT64_C(0xffff), UINT64_C(0xffffffff), UINT64_C(0xffffffffffffffff) };
+        Assert(enmEffAddrMode < RT_ELEMENTS(s_auAddrSizeMasks));
+        RTGCPTR const GCPtrVal = u64Val & s_auAddrSizeMasks[enmEffAddrMode];
 
         /* Read the value from the specified guest memory location. */
         VBOXSTRICTRC rcStrict;
         if (pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT)
-            rcStrict = iemMemFetchDataU64(pVCpu, &u64Val, pExitInstrInfo->VmreadVmwrite.iSegReg, GCPtrVal);
+            rcStrict = iemMemFetchDataU64(pVCpu, &u64Val, iEffSeg, GCPtrVal);
         else
         {
             uint32_t u32Val;
-            rcStrict = iemMemFetchDataU32(pVCpu, &u32Val, pExitInstrInfo->VmreadVmwrite.iSegReg, GCPtrVal);
+            rcStrict = iemMemFetchDataU32(pVCpu, &u32Val, iEffSeg, GCPtrVal);
             u64Val = u32Val;
         }
@@ -1182,17 +1184,18 @@
  * @param   pVCpu           The cross context virtual CPU structure.
  * @param   cbInstr         The instruction length.
+ * @param   iEffSeg         The effective segment register to use with @a GCPtrVmcs.
  * @param   GCPtrVmcs       The linear address of the VMCS pointer.
- * @param   pExitInstrInfo  Pointer to the VM-exit instruction information field.
- * @param   GCPtrDisp       The displacement field for @a GCPtrVmcs if any.
+ * @param   pExitInfo       Pointer to the VM-exit information struct. Optional, can
+ *                          be NULL.
  *
  * @remarks Common VMX instruction checks are already expected to by the caller,
  *          i.e. VMX operation, CR4.VMXE, Real/V86 mode, EFER/CS.L checks.
  */
-IEM_STATIC VBOXSTRICTRC iemVmxVmclear(PVMCPU pVCpu, uint8_t cbInstr, RTGCPHYS GCPtrVmcs, PCVMXEXITINSTRINFO pExitInstrInfo,
-                                      RTGCPTR GCPtrDisp)
+IEM_STATIC VBOXSTRICTRC iemVmxVmclear(PVMCPU pVCpu, uint8_t cbInstr, uint8_t iEffSeg, RTGCPHYS GCPtrVmcs,
+                                      PCVMXVEXITINFO pExitInfo)
 {
     if (IEM_IS_VMX_NON_ROOT_MODE(pVCpu))
     {
-        RT_NOREF(GCPtrDisp);
+        RT_NOREF(pExitInfo);
         /** @todo NSTVMX: intercept. */
     }
@@ -1209,5 +1212,5 @@
     /* Get the VMCS pointer from the location specified by the source memory operand. */
     RTGCPHYS GCPhysVmcs;
-    VBOXSTRICTRC rcStrict = iemMemFetchDataU64(pVCpu, &GCPhysVmcs, pExitInstrInfo->VmxXsave.iSegReg, GCPtrVmcs);
+    VBOXSTRICTRC rcStrict = iemMemFetchDataU64(pVCpu, &GCPhysVmcs, iEffSeg, GCPtrVmcs);
     if (RT_UNLIKELY(rcStrict != VINF_SUCCESS))
     {
@@ -1292,18 +1295,19 @@
  * @param   pVCpu           The cross context virtual CPU structure.
  * @param   cbInstr         The instruction length.
+ * @param   iEffSeg         The effective segment register to use with @a GCPtrVmcs.
  * @param   GCPtrVmcs       The linear address of where to store the current VMCS
  *                          pointer.
- * @param   pExitInstrInfo  Pointer to the VM-exit instruction information field.
- * @param   GCPtrDisp       The displacement field for @a GCPtrVmcs if any.
+ * @param   pExitInfo       Pointer to the VM-exit information struct. Optional, can
+ *                          be NULL.
  *
  * @remarks Common VMX instruction checks are already expected to by the caller,
  *          i.e. VMX operation, CR4.VMXE, Real/V86 mode, EFER/CS.L checks.
  */
-IEM_STATIC VBOXSTRICTRC iemVmxVmptrst(PVMCPU pVCpu, uint8_t cbInstr, RTGCPHYS GCPtrVmcs, PCVMXEXITINSTRINFO pExitInstrInfo,
-                                      RTGCPTR GCPtrDisp)
+IEM_STATIC VBOXSTRICTRC iemVmxVmptrst(PVMCPU pVCpu, uint8_t cbInstr, uint8_t iEffSeg, RTGCPHYS GCPtrVmcs,
+                                      PCVMXVEXITINFO pExitInfo)
 {
     if (IEM_IS_VMX_NON_ROOT_MODE(pVCpu))
     {
-        RT_NOREF(GCPtrDisp);
+        RT_NOREF(pExitInfo);
         /** @todo NSTVMX: intercept. */
     }
@@ -1320,6 +1324,5 @@
     /* Set the VMCS pointer to the location specified by the destination memory operand. */
     AssertCompile(NIL_RTGCPHYS == ~(RTGCPHYS)0U);
-    VBOXSTRICTRC rcStrict = iemMemStoreDataU64(pVCpu, pExitInstrInfo->VmxXsave.iSegReg, GCPtrVmcs,
-                                               IEM_VMX_GET_CURRENT_VMCS(pVCpu));
+    VBOXSTRICTRC rcStrict = iemMemStoreDataU64(pVCpu, iEffSeg, GCPtrVmcs, IEM_VMX_GET_CURRENT_VMCS(pVCpu));
     if (RT_LIKELY(rcStrict == VINF_SUCCESS))
     {
@@ -1342,16 +1345,16 @@
  * @param   cbInstr         The instruction length.
  * @param   GCPtrVmcs       The linear address of the current VMCS pointer.
- * @param   pExitInstrInfo  Pointer to the VM-exit instruction information field.
- * @param   GCPtrDisp       The displacement field for @a GCPtrVmcs if any.
+ * @param   pExitInfo       Pointer to the virtual VM-exit information struct.
+ *                          Optional, can be NULL.
  *
  * @remarks Common VMX instruction checks are already expected to by the caller,
  *          i.e. VMX operation, CR4.VMXE, Real/V86 mode, EFER/CS.L checks.
  */
-IEM_STATIC VBOXSTRICTRC iemVmxVmptrld(PVMCPU pVCpu, uint8_t cbInstr, RTGCPHYS GCPtrVmcs, PCVMXEXITINSTRINFO pExitInstrInfo,
-                                      RTGCPTR GCPtrDisp)
+IEM_STATIC VBOXSTRICTRC iemVmxVmptrld(PVMCPU pVCpu, uint8_t cbInstr, uint8_t iEffSeg, RTGCPHYS GCPtrVmcs,
+                                      PCVMXVEXITINFO pExitInfo)
 {
     if (IEM_IS_VMX_NON_ROOT_MODE(pVCpu))
     {
-        RT_NOREF(GCPtrDisp);
+        RT_NOREF(pExitInfo);
         /** @todo NSTVMX: intercept. */
     }
@@ -1368,5 +1371,5 @@
     /* Get the VMCS pointer from the location specified by the source memory operand. */
     RTGCPHYS GCPhysVmcs;
-    VBOXSTRICTRC rcStrict = iemMemFetchDataU64(pVCpu, &GCPhysVmcs, pExitInstrInfo->VmxXsave.iSegReg, GCPtrVmcs);
+    VBOXSTRICTRC rcStrict = iemMemFetchDataU64(pVCpu, &GCPhysVmcs, iEffSeg, GCPtrVmcs);
     if (RT_UNLIKELY(rcStrict != VINF_SUCCESS))
     {
@@ -1473,16 +1476,18 @@
  * @param   pVCpu           The cross context virtual CPU structure.
  * @param   cbInstr         The instruction length.
+ * @param   iEffSeg         The effective segment register to use with @a
+ *                          GCPtrVmxon.
  * @param   GCPtrVmxon      The linear address of the VMXON pointer.
- * @param   pExitInstrInfo  Pointer to the VM-exit instruction information field.
- * @param   GCPtrDisp       The displacement field for @a GCPtrVmxon if any.
+ * @param   pExitInfo       Pointer to the VM-exit instruction information struct.
+ *                          Optional, can  be NULL.
  *
  * @remarks Common VMX instruction checks are already expected to by the caller,
  *          i.e. CR4.VMXE, Real/V86 mode, EFER/CS.L checks.
  */
-IEM_STATIC VBOXSTRICTRC iemVmxVmxon(PVMCPU pVCpu, uint8_t cbInstr, RTGCPHYS GCPtrVmxon, PCVMXEXITINSTRINFO pExitInstrInfo,
-                                    RTGCPTR GCPtrDisp)
+IEM_STATIC VBOXSTRICTRC iemVmxVmxon(PVMCPU pVCpu, uint8_t cbInstr, uint8_t iEffSeg, RTGCPHYS GCPtrVmxon,
+                                    PCVMXVEXITINFO pExitInfo)
 {
 #if defined(VBOX_WITH_NESTED_HWVIRT_ONLY_IN_IEM) && !defined(IN_RING3)
-    RT_NOREF5(pVCpu, cbInstr, GCPtrVmxon, pExitInstrInfo, GCPtrDisp);
+    RT_NOREF5(pVCpu, cbInstr, iEffSeg, GCPtrVmxon, pExitInfo);
     return VINF_EM_RAW_EMULATE_INSTR;
 #else
@@ -1534,5 +1539,5 @@
         /* Get the VMXON pointer from the location specified by the source memory operand. */
         RTGCPHYS GCPhysVmxon;
-        VBOXSTRICTRC rcStrict = iemMemFetchDataU64(pVCpu, &GCPhysVmxon, pExitInstrInfo->VmxXsave.iSegReg, GCPtrVmxon);
+        VBOXSTRICTRC rcStrict = iemMemFetchDataU64(pVCpu, &GCPhysVmxon, iEffSeg, GCPtrVmxon);
         if (RT_UNLIKELY(rcStrict != VINF_SUCCESS))
         {
@@ -1625,5 +1630,5 @@
     else if (IEM_IS_VMX_NON_ROOT_MODE(pVCpu))
     {
-        RT_NOREF(GCPtrDisp);
+        RT_NOREF(pExitInfo);
         /** @todo NSTVMX: intercept. */
     }
@@ -1651,10 +1656,7 @@
  * Implements 'VMXON'.
  */
-IEM_CIMPL_DEF_1(iemCImpl_vmxon, RTGCPTR, GCPtrVmxon)
-{
-    RTGCPTR GCPtrDisp;
-    VMXEXITINSTRINFO ExitInstrInfo;
-    ExitInstrInfo.u = iemVmxGetExitInstrInfo(pVCpu, VMX_EXIT_VMXON, VMX_INSTR_ID_NONE, &GCPtrDisp);
-    return iemVmxVmxon(pVCpu, cbInstr, GCPtrVmxon, &ExitInstrInfo, GCPtrDisp);
+IEM_CIMPL_DEF_2(iemCImpl_vmxon, uint8_t, iEffSeg, RTGCPTR, GCPtrVmxon)
+{
+    return iemVmxVmxon(pVCpu, cbInstr, iEffSeg, GCPtrVmxon, NULL /* pExitInfo */);
 }
 
@@ -1725,10 +1727,7 @@
  * Implements 'VMPTRLD'.
  */
-IEM_CIMPL_DEF_1(iemCImpl_vmptrld, RTGCPTR, GCPtrVmcs)
-{
-    RTGCPTR GCPtrDisp;
-    VMXEXITINSTRINFO ExitInstrInfo;
-    ExitInstrInfo.u = iemVmxGetExitInstrInfo(pVCpu, VMX_EXIT_VMPTRLD, VMX_INSTR_ID_NONE, &GCPtrDisp);
-    return iemVmxVmptrld(pVCpu, cbInstr, GCPtrVmcs, &ExitInstrInfo, GCPtrDisp);
+IEM_CIMPL_DEF_2(iemCImpl_vmptrld, uint8_t, iEffSeg, RTGCPTR, GCPtrVmcs)
+{
+    return iemVmxVmptrld(pVCpu, cbInstr, iEffSeg, GCPtrVmcs, NULL /* pExitInfo */);
 }
 
@@ -1737,10 +1736,7 @@
  * Implements 'VMPTRST'.
  */
-IEM_CIMPL_DEF_1(iemCImpl_vmptrst, RTGCPTR, GCPtrVmcs)
-{
-    RTGCPTR GCPtrDisp;
-    VMXEXITINSTRINFO ExitInstrInfo;
-    ExitInstrInfo.u = iemVmxGetExitInstrInfo(pVCpu, VMX_EXIT_VMPTRST, VMX_INSTR_ID_NONE, &GCPtrDisp);
-    return iemVmxVmptrst(pVCpu, cbInstr, GCPtrVmcs, &ExitInstrInfo, GCPtrDisp);
+IEM_CIMPL_DEF_2(iemCImpl_vmptrst, uint8_t, iEffSeg, RTGCPTR, GCPtrVmcs)
+{
+    return iemVmxVmptrst(pVCpu, cbInstr, iEffSeg, GCPtrVmcs, NULL /* pExitInfo */);
 }
 
@@ -1749,10 +1745,7 @@
  * Implements 'VMCLEAR'.
  */
-IEM_CIMPL_DEF_1(iemCImpl_vmclear, RTGCPTR, GCPtrVmcs)
-{
-    RTGCPTR GCPtrDisp;
-    VMXEXITINSTRINFO ExitInstrInfo;
-    ExitInstrInfo.u = iemVmxGetExitInstrInfo(pVCpu, VMX_EXIT_VMCLEAR, VMX_INSTR_ID_NONE, &GCPtrDisp);
-    return iemVmxVmclear(pVCpu, cbInstr, GCPtrVmcs, &ExitInstrInfo, GCPtrDisp);
+IEM_CIMPL_DEF_2(iemCImpl_vmclear, uint8_t, iEffSeg, RTGCPTR, GCPtrVmcs)
+{
+    return iemVmxVmclear(pVCpu, cbInstr, iEffSeg, GCPtrVmcs, NULL /* pExitInfo */);
 }
 
@@ -1761,9 +1754,7 @@
  * Implements 'VMWRITE' register.
  */
-IEM_CIMPL_DEF_2(iemCImpl_vmwrite_reg, uint32_t, u32VmcsFieldEnc, uint64_t, u64Val)
-{
-    VMXEXITINSTRINFO ExitInstrInfo;
-    ExitInstrInfo.u = iemVmxGetExitInstrInfo(pVCpu, VMX_EXIT_VMWRITE, VMX_INSTR_ID_NONE, NULL /* pGCPtrDisp */);
-    return iemVmxVmwrite(pVCpu, cbInstr, u32VmcsFieldEnc, u64Val, &ExitInstrInfo, 0 /* GCPtrDisp */);
+IEM_CIMPL_DEF_2(iemCImpl_vmwrite_reg, uint64_t, u64Val, uint32_t, uFieldEnc)
+{
+    return iemVmxVmwrite(pVCpu, cbInstr, UINT8_MAX /*iEffSeg*/, IEMMODE_64BIT /* N/A */, u64Val, uFieldEnc, NULL /* pExitInfo */);
 }
 
@@ -1772,10 +1763,7 @@
  * Implements 'VMWRITE' memory.
  */
-IEM_CIMPL_DEF_2(iemCImpl_vmwrite_mem, uint32_t, u32VmcsFieldEnc, RTGCUINTPTR64, GCPtrVal)
-{
-    RTGCPTR GCPtrDisp;
-    VMXEXITINSTRINFO ExitInstrInfo;
-    ExitInstrInfo.u = iemVmxGetExitInstrInfo(pVCpu, VMX_EXIT_VMWRITE, VMX_INSTR_ID_NONE, &GCPtrDisp);
-    return iemVmxVmwrite(pVCpu, cbInstr, u32VmcsFieldEnc, GCPtrVal, &ExitInstrInfo, GCPtrDisp);
+IEM_CIMPL_DEF_4(iemCImpl_vmwrite_mem, uint8_t, iEffSeg, IEMMODE, enmEffAddrMode, RTGCPTR, GCPtrVal, uint32_t, uFieldEnc)
+{
+    return iemVmxVmwrite(pVCpu, cbInstr, iEffSeg, enmEffAddrMode, GCPtrVal, uFieldEnc,  NULL /* pExitInfo */);
 }
 
