VirtualBox

Ignore:
Timestamp:
Aug 29, 2018 3:24:49 PM (6 years ago)
Author:
vboxsync
Message:

VMM/IEM, HM: Nested VMX: bugref:9180 Use VMXEXITINFO to pass decoder info to IEM. Avoid unnecessarily constructing VM-exit info.
in IEM for VMX instructions.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h

    r73937 r73959  
    10411041 * @param   pVCpu           The cross context virtual CPU structure.
    10421042 * @param   cbInstr         The instruction length.
     1043 * @param   iEffSeg         The effective segment register to use with @a u64Val.
     1044 *                          Pass UINT8_MAX if it is a register access.
     1045 * @param   enmEffAddrMode  The effective addressing mode.
     1046 * @param   u64Val          The value to write (or guest linear address to the
     1047 *                          value), @a iEffSeg will indicate if it's a memory
     1048 *                          operand.
    10431049 * @param   uFieldEnc       The VMCS field encoding.
    1044  * @param   u64Val          The value to write (or guest linear address to the
    1045  *                          value), @a pExitInstrInfo will indicate whether it's a
    1046  *                          memory or register operand.
    1047  * @param   pExitInstrInfo  Pointer to the VM-exit instruction information field.
    1048  * @param   GCPtrDisp       The displacement field for @a GCPtrVmcs if any.
    1049  */
    1050 IEM_STATIC VBOXSTRICTRC iemVmxVmwrite(PVMCPU pVCpu, uint8_t cbInstr, uint32_t uFieldEnc, uint64_t u64Val,
    1051                                       PCVMXEXITINSTRINFO pExitInstrInfo, RTGCPTR GCPtrDisp)
     1050 * @param   pExitInfo       Pointer to the VM-exit information struct.
     1051 */
     1052IEM_STATIC VBOXSTRICTRC iemVmxVmwrite(PVMCPU pVCpu, uint8_t cbInstr, uint8_t iEffSeg, IEMMODE enmEffAddrMode,
     1053                                      uint64_t u64Val, uint32_t uFieldEnc, PCVMXVEXITINFO pExitInfo)
    10521054{
    10531055    if (IEM_IS_VMX_NON_ROOT_MODE(pVCpu))
    10541056    {
    1055         RT_NOREF(GCPtrDisp);
     1057        RT_NOREF(pExitInfo);
    10561058        /** @todo NSTVMX: intercept. */
    10571059        /** @todo NSTVMX: VMCS shadowing intercept (VMREAD/VMWRITE bitmap). */
     
    10891091
    10901092    /* If the VMWRITE instruction references memory, access the specified in memory operand. */
    1091     if (!pExitInstrInfo->VmreadVmwrite.fIsRegOperand)
    1092     {
    1093         uint8_t const uAddrSize = pExitInstrInfo->VmreadVmwrite.u3AddrSize;
    1094         static uint64_t const s_auAddrSizeMasks[] = { UINT64_C(0xffff), UINT64_C(0xffffffff), UINT64_C(0xffffffffffffffff), 0 };
    1095         AssertRCReturn(uAddrSize != 3, VERR_IEM_IPE_1);
    1096         RTGCPTR const GCPtrVal = u64Val & s_auAddrSizeMasks[uAddrSize];
     1093    bool const fIsRegOperand = iEffSeg == UINT8_MAX;
     1094    if (fIsRegOperand)
     1095    {
     1096        static uint64_t const s_auAddrSizeMasks[] = { UINT64_C(0xffff), UINT64_C(0xffffffff), UINT64_C(0xffffffffffffffff) };
     1097        Assert(enmEffAddrMode < RT_ELEMENTS(s_auAddrSizeMasks));
     1098        RTGCPTR const GCPtrVal = u64Val & s_auAddrSizeMasks[enmEffAddrMode];
    10971099
    10981100        /* Read the value from the specified guest memory location. */
    10991101        VBOXSTRICTRC rcStrict;
    11001102        if (pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT)
    1101             rcStrict = iemMemFetchDataU64(pVCpu, &u64Val, pExitInstrInfo->VmreadVmwrite.iSegReg, GCPtrVal);
     1103            rcStrict = iemMemFetchDataU64(pVCpu, &u64Val, iEffSeg, GCPtrVal);
    11021104        else
    11031105        {
    11041106            uint32_t u32Val;
    1105             rcStrict = iemMemFetchDataU32(pVCpu, &u32Val, pExitInstrInfo->VmreadVmwrite.iSegReg, GCPtrVal);
     1107            rcStrict = iemMemFetchDataU32(pVCpu, &u32Val, iEffSeg, GCPtrVal);
    11061108            u64Val = u32Val;
    11071109        }
     
    11821184 * @param   pVCpu           The cross context virtual CPU structure.
    11831185 * @param   cbInstr         The instruction length.
     1186 * @param   iEffSeg         The effective segment register to use with @a GCPtrVmcs.
    11841187 * @param   GCPtrVmcs       The linear address of the VMCS pointer.
    1185  * @param   pExitInstrInfo  Pointer to the VM-exit instruction information field.
    1186  * @param   GCPtrDisp       The displacement field for @a GCPtrVmcs if any.
     1188 * @param   pExitInfo       Pointer to the VM-exit information struct. Optional, can
     1189 *                          be NULL.
    11871190 *
    11881191 * @remarks Common VMX instruction checks are already expected to by the caller,
    11891192 *          i.e. VMX operation, CR4.VMXE, Real/V86 mode, EFER/CS.L checks.
    11901193 */
    1191 IEM_STATIC VBOXSTRICTRC iemVmxVmclear(PVMCPU pVCpu, uint8_t cbInstr, RTGCPHYS GCPtrVmcs, PCVMXEXITINSTRINFO pExitInstrInfo,
    1192                                       RTGCPTR GCPtrDisp)
     1194IEM_STATIC VBOXSTRICTRC iemVmxVmclear(PVMCPU pVCpu, uint8_t cbInstr, uint8_t iEffSeg, RTGCPHYS GCPtrVmcs,
     1195                                      PCVMXVEXITINFO pExitInfo)
    11931196{
    11941197    if (IEM_IS_VMX_NON_ROOT_MODE(pVCpu))
    11951198    {
    1196         RT_NOREF(GCPtrDisp);
     1199        RT_NOREF(pExitInfo);
    11971200        /** @todo NSTVMX: intercept. */
    11981201    }
     
    12091212    /* Get the VMCS pointer from the location specified by the source memory operand. */
    12101213    RTGCPHYS GCPhysVmcs;
    1211     VBOXSTRICTRC rcStrict = iemMemFetchDataU64(pVCpu, &GCPhysVmcs, pExitInstrInfo->VmxXsave.iSegReg, GCPtrVmcs);
     1214    VBOXSTRICTRC rcStrict = iemMemFetchDataU64(pVCpu, &GCPhysVmcs, iEffSeg, GCPtrVmcs);
    12121215    if (RT_UNLIKELY(rcStrict != VINF_SUCCESS))
    12131216    {
     
    12921295 * @param   pVCpu           The cross context virtual CPU structure.
    12931296 * @param   cbInstr         The instruction length.
     1297 * @param   iEffSeg         The effective segment register to use with @a GCPtrVmcs.
    12941298 * @param   GCPtrVmcs       The linear address of where to store the current VMCS
    12951299 *                          pointer.
    1296  * @param   pExitInstrInfo  Pointer to the VM-exit instruction information field.
    1297  * @param   GCPtrDisp       The displacement field for @a GCPtrVmcs if any.
     1300 * @param   pExitInfo       Pointer to the VM-exit information struct. Optional, can
     1301 *                          be NULL.
    12981302 *
    12991303 * @remarks Common VMX instruction checks are already expected to by the caller,
    13001304 *          i.e. VMX operation, CR4.VMXE, Real/V86 mode, EFER/CS.L checks.
    13011305 */
    1302 IEM_STATIC VBOXSTRICTRC iemVmxVmptrst(PVMCPU pVCpu, uint8_t cbInstr, RTGCPHYS GCPtrVmcs, PCVMXEXITINSTRINFO pExitInstrInfo,
    1303                                       RTGCPTR GCPtrDisp)
     1306IEM_STATIC VBOXSTRICTRC iemVmxVmptrst(PVMCPU pVCpu, uint8_t cbInstr, uint8_t iEffSeg, RTGCPHYS GCPtrVmcs,
     1307                                      PCVMXVEXITINFO pExitInfo)
    13041308{
    13051309    if (IEM_IS_VMX_NON_ROOT_MODE(pVCpu))
    13061310    {
    1307         RT_NOREF(GCPtrDisp);
     1311        RT_NOREF(pExitInfo);
    13081312        /** @todo NSTVMX: intercept. */
    13091313    }
     
    13201324    /* Set the VMCS pointer to the location specified by the destination memory operand. */
    13211325    AssertCompile(NIL_RTGCPHYS == ~(RTGCPHYS)0U);
    1322     VBOXSTRICTRC rcStrict = iemMemStoreDataU64(pVCpu, pExitInstrInfo->VmxXsave.iSegReg, GCPtrVmcs,
    1323                                                IEM_VMX_GET_CURRENT_VMCS(pVCpu));
     1326    VBOXSTRICTRC rcStrict = iemMemStoreDataU64(pVCpu, iEffSeg, GCPtrVmcs, IEM_VMX_GET_CURRENT_VMCS(pVCpu));
    13241327    if (RT_LIKELY(rcStrict == VINF_SUCCESS))
    13251328    {
     
    13421345 * @param   cbInstr         The instruction length.
    13431346 * @param   GCPtrVmcs       The linear address of the current VMCS pointer.
    1344  * @param   pExitInstrInfo  Pointer to the VM-exit instruction information field.
    1345  * @param   GCPtrDisp       The displacement field for @a GCPtrVmcs if any.
     1347 * @param   pExitInfo       Pointer to the virtual VM-exit information struct.
     1348 *                          Optional, can be NULL.
    13461349 *
    13471350 * @remarks Common VMX instruction checks are already expected to by the caller,
    13481351 *          i.e. VMX operation, CR4.VMXE, Real/V86 mode, EFER/CS.L checks.
    13491352 */
    1350 IEM_STATIC VBOXSTRICTRC iemVmxVmptrld(PVMCPU pVCpu, uint8_t cbInstr, RTGCPHYS GCPtrVmcs, PCVMXEXITINSTRINFO pExitInstrInfo,
    1351                                       RTGCPTR GCPtrDisp)
     1353IEM_STATIC VBOXSTRICTRC iemVmxVmptrld(PVMCPU pVCpu, uint8_t cbInstr, uint8_t iEffSeg, RTGCPHYS GCPtrVmcs,
     1354                                      PCVMXVEXITINFO pExitInfo)
    13521355{
    13531356    if (IEM_IS_VMX_NON_ROOT_MODE(pVCpu))
    13541357    {
    1355         RT_NOREF(GCPtrDisp);
     1358        RT_NOREF(pExitInfo);
    13561359        /** @todo NSTVMX: intercept. */
    13571360    }
     
    13681371    /* Get the VMCS pointer from the location specified by the source memory operand. */
    13691372    RTGCPHYS GCPhysVmcs;
    1370     VBOXSTRICTRC rcStrict = iemMemFetchDataU64(pVCpu, &GCPhysVmcs, pExitInstrInfo->VmxXsave.iSegReg, GCPtrVmcs);
     1373    VBOXSTRICTRC rcStrict = iemMemFetchDataU64(pVCpu, &GCPhysVmcs, iEffSeg, GCPtrVmcs);
    13711374    if (RT_UNLIKELY(rcStrict != VINF_SUCCESS))
    13721375    {
     
    14731476 * @param   pVCpu           The cross context virtual CPU structure.
    14741477 * @param   cbInstr         The instruction length.
     1478 * @param   iEffSeg         The effective segment register to use with @a
     1479 *                          GCPtrVmxon.
    14751480 * @param   GCPtrVmxon      The linear address of the VMXON pointer.
    1476  * @param   pExitInstrInfo  Pointer to the VM-exit instruction information field.
    1477  * @param   GCPtrDisp       The displacement field for @a GCPtrVmxon if any.
     1481 * @param   pExitInfo       Pointer to the VM-exit instruction information struct.
     1482 *                          Optional, can  be NULL.
    14781483 *
    14791484 * @remarks Common VMX instruction checks are already expected to by the caller,
    14801485 *          i.e. CR4.VMXE, Real/V86 mode, EFER/CS.L checks.
    14811486 */
    1482 IEM_STATIC VBOXSTRICTRC iemVmxVmxon(PVMCPU pVCpu, uint8_t cbInstr, RTGCPHYS GCPtrVmxon, PCVMXEXITINSTRINFO pExitInstrInfo,
    1483                                     RTGCPTR GCPtrDisp)
     1487IEM_STATIC VBOXSTRICTRC iemVmxVmxon(PVMCPU pVCpu, uint8_t cbInstr, uint8_t iEffSeg, RTGCPHYS GCPtrVmxon,
     1488                                    PCVMXVEXITINFO pExitInfo)
    14841489{
    14851490#if defined(VBOX_WITH_NESTED_HWVIRT_ONLY_IN_IEM) && !defined(IN_RING3)
    1486     RT_NOREF5(pVCpu, cbInstr, GCPtrVmxon, pExitInstrInfo, GCPtrDisp);
     1491    RT_NOREF5(pVCpu, cbInstr, iEffSeg, GCPtrVmxon, pExitInfo);
    14871492    return VINF_EM_RAW_EMULATE_INSTR;
    14881493#else
     
    15341539        /* Get the VMXON pointer from the location specified by the source memory operand. */
    15351540        RTGCPHYS GCPhysVmxon;
    1536         VBOXSTRICTRC rcStrict = iemMemFetchDataU64(pVCpu, &GCPhysVmxon, pExitInstrInfo->VmxXsave.iSegReg, GCPtrVmxon);
     1541        VBOXSTRICTRC rcStrict = iemMemFetchDataU64(pVCpu, &GCPhysVmxon, iEffSeg, GCPtrVmxon);
    15371542        if (RT_UNLIKELY(rcStrict != VINF_SUCCESS))
    15381543        {
     
    16251630    else if (IEM_IS_VMX_NON_ROOT_MODE(pVCpu))
    16261631    {
    1627         RT_NOREF(GCPtrDisp);
     1632        RT_NOREF(pExitInfo);
    16281633        /** @todo NSTVMX: intercept. */
    16291634    }
     
    16511656 * Implements 'VMXON'.
    16521657 */
    1653 IEM_CIMPL_DEF_1(iemCImpl_vmxon, RTGCPTR, GCPtrVmxon)
    1654 {
    1655     RTGCPTR GCPtrDisp;
    1656     VMXEXITINSTRINFO ExitInstrInfo;
    1657     ExitInstrInfo.u = iemVmxGetExitInstrInfo(pVCpu, VMX_EXIT_VMXON, VMX_INSTR_ID_NONE, &GCPtrDisp);
    1658     return iemVmxVmxon(pVCpu, cbInstr, GCPtrVmxon, &ExitInstrInfo, GCPtrDisp);
     1658IEM_CIMPL_DEF_2(iemCImpl_vmxon, uint8_t, iEffSeg, RTGCPTR, GCPtrVmxon)
     1659{
     1660    return iemVmxVmxon(pVCpu, cbInstr, iEffSeg, GCPtrVmxon, NULL /* pExitInfo */);
    16591661}
    16601662
     
    17251727 * Implements 'VMPTRLD'.
    17261728 */
    1727 IEM_CIMPL_DEF_1(iemCImpl_vmptrld, RTGCPTR, GCPtrVmcs)
    1728 {
    1729     RTGCPTR GCPtrDisp;
    1730     VMXEXITINSTRINFO ExitInstrInfo;
    1731     ExitInstrInfo.u = iemVmxGetExitInstrInfo(pVCpu, VMX_EXIT_VMPTRLD, VMX_INSTR_ID_NONE, &GCPtrDisp);
    1732     return iemVmxVmptrld(pVCpu, cbInstr, GCPtrVmcs, &ExitInstrInfo, GCPtrDisp);
     1729IEM_CIMPL_DEF_2(iemCImpl_vmptrld, uint8_t, iEffSeg, RTGCPTR, GCPtrVmcs)
     1730{
     1731    return iemVmxVmptrld(pVCpu, cbInstr, iEffSeg, GCPtrVmcs, NULL /* pExitInfo */);
    17331732}
    17341733
     
    17371736 * Implements 'VMPTRST'.
    17381737 */
    1739 IEM_CIMPL_DEF_1(iemCImpl_vmptrst, RTGCPTR, GCPtrVmcs)
    1740 {
    1741     RTGCPTR GCPtrDisp;
    1742     VMXEXITINSTRINFO ExitInstrInfo;
    1743     ExitInstrInfo.u = iemVmxGetExitInstrInfo(pVCpu, VMX_EXIT_VMPTRST, VMX_INSTR_ID_NONE, &GCPtrDisp);
    1744     return iemVmxVmptrst(pVCpu, cbInstr, GCPtrVmcs, &ExitInstrInfo, GCPtrDisp);
     1738IEM_CIMPL_DEF_2(iemCImpl_vmptrst, uint8_t, iEffSeg, RTGCPTR, GCPtrVmcs)
     1739{
     1740    return iemVmxVmptrst(pVCpu, cbInstr, iEffSeg, GCPtrVmcs, NULL /* pExitInfo */);
    17451741}
    17461742
     
    17491745 * Implements 'VMCLEAR'.
    17501746 */
    1751 IEM_CIMPL_DEF_1(iemCImpl_vmclear, RTGCPTR, GCPtrVmcs)
    1752 {
    1753     RTGCPTR GCPtrDisp;
    1754     VMXEXITINSTRINFO ExitInstrInfo;
    1755     ExitInstrInfo.u = iemVmxGetExitInstrInfo(pVCpu, VMX_EXIT_VMCLEAR, VMX_INSTR_ID_NONE, &GCPtrDisp);
    1756     return iemVmxVmclear(pVCpu, cbInstr, GCPtrVmcs, &ExitInstrInfo, GCPtrDisp);
     1747IEM_CIMPL_DEF_2(iemCImpl_vmclear, uint8_t, iEffSeg, RTGCPTR, GCPtrVmcs)
     1748{
     1749    return iemVmxVmclear(pVCpu, cbInstr, iEffSeg, GCPtrVmcs, NULL /* pExitInfo */);
    17571750}
    17581751
     
    17611754 * Implements 'VMWRITE' register.
    17621755 */
    1763 IEM_CIMPL_DEF_2(iemCImpl_vmwrite_reg, uint32_t, u32VmcsFieldEnc, uint64_t, u64Val)
    1764 {
    1765     VMXEXITINSTRINFO ExitInstrInfo;
    1766     ExitInstrInfo.u = iemVmxGetExitInstrInfo(pVCpu, VMX_EXIT_VMWRITE, VMX_INSTR_ID_NONE, NULL /* pGCPtrDisp */);
    1767     return iemVmxVmwrite(pVCpu, cbInstr, u32VmcsFieldEnc, u64Val, &ExitInstrInfo, 0 /* GCPtrDisp */);
     1756IEM_CIMPL_DEF_2(iemCImpl_vmwrite_reg, uint64_t, u64Val, uint32_t, uFieldEnc)
     1757{
     1758    return iemVmxVmwrite(pVCpu, cbInstr, UINT8_MAX /*iEffSeg*/, IEMMODE_64BIT /* N/A */, u64Val, uFieldEnc, NULL /* pExitInfo */);
    17681759}
    17691760
     
    17721763 * Implements 'VMWRITE' memory.
    17731764 */
    1774 IEM_CIMPL_DEF_2(iemCImpl_vmwrite_mem, uint32_t, u32VmcsFieldEnc, RTGCUINTPTR64, GCPtrVal)
    1775 {
    1776     RTGCPTR GCPtrDisp;
    1777     VMXEXITINSTRINFO ExitInstrInfo;
    1778     ExitInstrInfo.u = iemVmxGetExitInstrInfo(pVCpu, VMX_EXIT_VMWRITE, VMX_INSTR_ID_NONE, &GCPtrDisp);
    1779     return iemVmxVmwrite(pVCpu, cbInstr, u32VmcsFieldEnc, GCPtrVal, &ExitInstrInfo, GCPtrDisp);
     1765IEM_CIMPL_DEF_4(iemCImpl_vmwrite_mem, uint8_t, iEffSeg, IEMMODE, enmEffAddrMode, RTGCPTR, GCPtrVal, uint32_t, uFieldEnc)
     1766{
     1767    return iemVmxVmwrite(pVCpu, cbInstr, iEffSeg, enmEffAddrMode, GCPtrVal, uFieldEnc,  NULL /* pExitInfo */);
    17801768}
    17811769
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette