VirtualBox

Changeset 74015 in vbox for trunk/src


Ignore:
Timestamp:
Sep 1, 2018 4:20:29 AM (6 years ago)
Author:
vboxsync
Message:

VMM/IEM: Nested VMX: bugref:9180 Add missing diagnostics for vmclear, vmptrld, vmptrst. Moved a couple of macros to VMX specific
code. Fixed confusing/conflicting "VmxRoot" failure for vmxon, replaced with "AlreadyVmxRoot" to distinguish this particular case.

Location:
trunk/src/VBox/VMM
Files:
5 edited

Legend:

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

    r73983 r74015  
    5959    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmxon_Success         , "Success"       ),
    6060    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmxon_ShadowVmcs      , "ShadowVmcs"    ),
     61    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmxon_VmxAlreadyRoot  , "VmxAlreadyRoot"),
    6162    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmxon_Vmxe            , "Vmxe"          ),
    6263    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmxon_VmcsRevId       , "VmcsRevId"     ),
    63     VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmxon_VmxRoot         , "VmxRoot"       ),
    6464    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmxon_VmxRootCpl      , "VmxRootCpl"    ),
    6565    /* VMXOFF. */
     
    7373    /* VMPTRLD. */
    7474    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmptrld_Cpl           , "Cpl"           ),
     75    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmptrld_LongModeCS    , "LongModeCS"    ),
    7576    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmptrld_PtrAbnormal   , "PtrAbnormal"   ),
    7677    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmptrld_PtrAlign      , "PtrAlign"      ),
     
    7980    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmptrld_PtrVmxon      , "PtrVmxon"      ),
    8081    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmptrld_PtrWidth      , "PtrWidth"      ),
     82    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmptrld_RealOrV86Mode , "RealOrV86Mode" ),
    8183    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmptrld_ShadowVmcs    , "ShadowVmcs"    ),
    8284    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmptrld_Success       , "Success"       ),
    83     VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmptrld_VmcsRevId     , "VmcsRevId"     )
     85    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmptrld_VmcsRevId     , "VmcsRevId"     ),
     86    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmptrld_VmxRoot       , "VmxRoot"       ),
    8487    /* VMPTRST. */
    8588    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmptrst_Cpl           , "Cpl"           ),
     89    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmptrst_LongModeCS    , "LongModeCS"    ),
    8690    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmptrst_PtrMap        , "PtrMap"        ),
     91    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmptrst_RealOrV86Mode , "RealOrV86Mode" ),
    8792    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmptrst_Success       , "Success"       ),
     93    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmptrst_VmxRoot       , "VmxRoot"       ),
    8894    /* VMCLEAR. */
    8995    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmclear_Cpl           , "Cpl"           ),
     96    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmclear_LongModeCS    , "LongModeCS"    ),
    9097    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmclear_PtrAbnormal   , "PtrAbnormal"   ),
    9198    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmclear_PtrAlign      , "PtrAlign"      ),
     
    94101    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmclear_PtrVmxon      , "PtrVmxon"      ),
    95102    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmclear_PtrWidth      , "PtrWidth"      ),
     103    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmclear_RealOrV86Mode , "RealOrV86Mode" ),
    96104    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmclear_Success       , "Success"       ),
     105    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmclear_VmxRoot       , "VmxRoot"       ),
    97106    /* VMWRITE. */
    98107    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmwrite_Cpl           , "Cpl"           ),
     
    100109    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmwrite_FieldRo       , "FieldRo"       ),
    101110    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmwrite_LinkPtrInvalid, "LinkPtrInvalid"),
     111    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmwrite_LongModeCS    , "LongModeCS"    ),
    102112    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmwrite_PtrInvalid    , "PtrInvalid"    ),
    103113    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmwrite_PtrMap        , "PtrMap"        ),
     114    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmwrite_RealOrV86Mode , "RealOrV86Mode" ),
    104115    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmwrite_Success       , "Success"       ),
     116    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmwrite_VmxRoot       , "VmxRoot"       ),
    105117    /* VMREAD. */
    106118    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmread_Cpl            , "Cpl"           ),
    107119    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmread_FieldInvalid   , "FieldInvalid"  ),
    108120    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmread_LinkPtrInvalid , "LinkPtrInvalid"),
     121    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmread_LongModeCS     , "LongModeCS"    ),
    109122    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmread_PtrInvalid     , "PtrInvalid"    ),
    110123    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmread_PtrMap         , "PtrMap"        ),
    111     VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmread_Success        , "Success"       )
     124    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmread_RealOrV86Mode  , "RealOrV86Mode" ),
     125    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmread_Success        , "Success"       ),
     126    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmread_VmxRoot        , "VmxRoot"       )
    112127    /* kVmxVInstrDiag_Last */
    113128};
  • trunk/src/VBox/VMM/VMMAll/IEMAll.cpp

    r73983 r74015  
    386386#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
    387387/**
    388  * Check the common VMX instruction preconditions.
    389  */
    390 #define IEM_VMX_INSTR_COMMON_CHECKS(a_pVCpu, a_szInstr, a_InsDiagPrefix) \
    391     do { \
    392         if (!IEM_IS_VMX_ENABLED(a_pVCpu)) \
    393         { \
    394             Log((a_szInstr ": CR4.VMXE not enabled -> #UD\n")); \
    395             (a_pVCpu)->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = a_InsDiagPrefix##_Vmxe; \
    396             return iemRaiseUndefinedOpcode(a_pVCpu); \
    397         } \
    398         if (IEM_IS_REAL_OR_V86_MODE(a_pVCpu)) \
    399         { \
    400             Log((a_szInstr ": Real or v8086 mode -> #UD\n")); \
    401             (a_pVCpu)->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = a_InsDiagPrefix##_RealOrV86Mode; \
    402             return iemRaiseUndefinedOpcode(a_pVCpu); \
    403         } \
    404         if (IEM_IS_LONG_MODE(a_pVCpu) && !IEM_IS_64BIT_CODE(a_pVCpu)) \
    405         { \
    406             Log((a_szInstr ": Long mode without 64-bit code segment -> #UD\n")); \
    407             (a_pVCpu)->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = a_InsDiagPrefix##_LongModeCS; \
    408             return iemRaiseUndefinedOpcode(a_pVCpu); \
    409         } \
    410     } while (0)
    411 
    412 /**
    413388 * Check if VMX is enabled.
    414389 */
     
    418393 * Check if the guest has entered VMX root operation.
    419394 */
    420 #define IEM_IS_VMX_ROOT_MODE(a_pVCpu)                        (CPUMIsGuestInVmxRootMode(IEM_GET_CTX(pVCpu)))
     395#define IEM_IS_VMX_ROOT_MODE(a_pVCpu)                        (CPUMIsGuestInVmxRootMode(IEM_GET_CTX(a_pVCpu)))
    421396
    422397/**
    423398 * Check if the guest has entered VMX non-root operation.
    424399 */
    425 #define IEM_IS_VMX_NON_ROOT_MODE(a_pVCpu)                    (CPUMIsGuestInVmxNonRootMode(IEM_GET_CTX(pVCpu)))
     400#define IEM_IS_VMX_NON_ROOT_MODE(a_pVCpu)                    (CPUMIsGuestInVmxNonRootMode(IEM_GET_CTX(a_pVCpu)))
    426401
    427402#else
     
    1257112546/** This instruction raises an \#UD in real and V8086 mode or when not using a
    1257212547 *  64-bit code segment when in long mode (applicable to all VMX instructions
    12573  *  except VMCALL). */
    12574 # define IEMOP_HLP_VMX_INSTR() \
     12548 *  except VMCALL).
     12549 *
     12550 *  @note Update IEM_VMX_INSTR_CHECKS() if changes are made here.
     12551 */
     12552#define IEMOP_HLP_VMX_INSTR(a_szInstr, a_InsDiagPrefix) \
    1257512553    do \
    1257612554    { \
     
    1258012558        { /* likely */ } \
    1258112559        else \
    12582             return IEMOP_RAISE_INVALID_OPCODE(); \
     12560        { \
     12561            if (IEM_IS_REAL_OR_V86_MODE(pVCpu)) \
     12562            { \
     12563                pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = a_InsDiagPrefix##_RealOrV86Mode; \
     12564                Log5((a_szInstr ": Real or v8086 mode -> #UD\n")); \
     12565                return IEMOP_RAISE_INVALID_OPCODE(); \
     12566            } \
     12567            if (IEM_IS_LONG_MODE(pVCpu) && !IEM_IS_64BIT_CODE(pVCpu)) \
     12568            { \
     12569                pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = a_InsDiagPrefix##_LongModeCS; \
     12570                Log5((a_szInstr ": Long mode without 64-bit code segment -> #UD\n")); \
     12571                return IEMOP_RAISE_INVALID_OPCODE(); \
     12572            } \
     12573        } \
    1258312574    } while (0)
    1258412575
    1258512576/** The instruction can only be executed in VMX operation (VMX root mode and
    1258612577 * non-root mode).
    12587  */
    12588 # define IEMOP_HLP_IN_VMX_OPERATION() \
     12578 *
     12579 *  @note Update IEM_VMX_IN_VMX_OPERATION if changes are made here.
     12580 */
     12581# define IEMOP_HLP_IN_VMX_OPERATION(a_szInstr, a_InsDiagPrefix) \
    1258912582    do \
    1259012583    { \
    1259112584        if (IEM_IS_VMX_ROOT_MODE(pVCpu)) { /* likely */ } \
    12592         else return IEMOP_RAISE_INVALID_OPCODE(); \
     12585        else \
     12586        { \
     12587            pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = a_InsDiagPrefix##_VmxRoot; \
     12588            Log5((a_szInstr ": Not in VMX operation (root mode) -> #UD\n")); \
     12589            return IEMOP_RAISE_INVALID_OPCODE(); \
     12590        } \
    1259312591    } while (0)
    1259412592#endif /* VBOX_WITH_NESTED_HWVIRT_VMX */
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h

    r73984 r74015  
    386386    { \
    387387        (a_pVCpu)->cpum.GstCtx.hwvirt.vmx.GCPhysVmcs = NIL_RTGCPHYS; \
     388    } while (0)
     389
     390/** Check the common VMX instruction preconditions.
     391 * @note Any changes here, also check if IEMOP_HLP_VMX_INSTR needs updating.
     392 */
     393#define IEM_VMX_INSTR_CHECKS(a_pVCpu, a_szInstr, a_InsDiagPrefix) \
     394    do { \
     395        if (   !IEM_IS_REAL_OR_V86_MODE(a_pVCpu) \
     396            && (   !IEM_IS_LONG_MODE(a_pVCpu) \
     397                ||  IEM_IS_64BIT_CODE(a_pVCpu))) \
     398        { /* likely */ } \
     399        else \
     400        { \
     401            if (IEM_IS_REAL_OR_V86_MODE(a_pVCpu)) \
     402            { \
     403                Log((a_szInstr ": Real or v8086 mode -> #UD\n")); \
     404                (a_pVCpu)->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = a_InsDiagPrefix##_RealOrV86Mode; \
     405                return iemRaiseUndefinedOpcode(a_pVCpu); \
     406            } \
     407            if (IEM_IS_LONG_MODE(a_pVCpu) && !IEM_IS_64BIT_CODE(a_pVCpu)) \
     408            { \
     409                Log((a_szInstr ": Long mode without 64-bit code segment -> #UD\n")); \
     410                (a_pVCpu)->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = a_InsDiagPrefix##_LongModeCS; \
     411                return iemRaiseUndefinedOpcode(a_pVCpu); \
     412            } \
     413        } \
     414    } while (0)
     415
     416/** Check for VMX instructions requiring to be in VMX operation.
     417 * @note Any changes here, check if IEMOP_HLP_IN_VMX_OPERATION needs udpating. */
     418#define IEM_VMX_IN_VMX_OPERATION(a_pVCpu, a_szInstr, a_InsDiagPrefix) \
     419    do \
     420    { \
     421        if (IEM_IS_VMX_ROOT_MODE(a_pVCpu)) \
     422        { /* likely */ } \
     423        else \
     424        { \
     425            Log((a_szInstr ": Not in VMX operation (root mode) -> #UD\n")); \
     426            (a_pVCpu)->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = a_InsDiagPrefix##_VmxRoot; \
     427            return iemRaiseUndefinedOpcode(a_pVCpu); \
     428        } \
    388429    } while (0)
    389430
     
    19001941    /* VMXON when already in VMX root mode. */
    19011942    iemVmxVmFail(pVCpu, VMXINSTRERR_VMXON_IN_VMXROOTMODE);
    1902     pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmxon_VmxRoot;
     1943    pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmxon_VmxAlreadyRoot;
    19031944    iemRegAddToRipAndClearRF(pVCpu, cbInstr);
    19041945    return VINF_SUCCESS;
     
    19251966    return VINF_EM_RAW_EMULATE_INSTR;
    19261967# else
    1927     IEM_VMX_INSTR_COMMON_CHECKS(pVCpu, "vmxoff", kVmxVInstrDiag_Vmxoff);
    1928     if (!IEM_IS_VMX_ROOT_MODE(pVCpu))
    1929     {
    1930         Log(("vmxoff: Not in VMX root mode -> #GP(0)\n"));
    1931         pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmxoff_VmxRoot;
    1932         return iemRaiseUndefinedOpcode(pVCpu);
    1933     }
     1968    IEM_VMX_IN_VMX_OPERATION(pVCpu, "vmxoff", kVmxVInstrDiag_Vmxoff);
     1969    IEM_VMX_INSTR_CHECKS(pVCpu, "vmxoff", kVmxVInstrDiag_Vmxoff);
    19341970
    19351971    if (IEM_IS_VMX_NON_ROOT_MODE(pVCpu))
     
    19792015
    19802016/**
     2017 * Implements 'VMLAUNCH'.
     2018 */
     2019IEM_CIMPL_DEF_0(iemCImpl_vmlaunch)
     2020{
     2021    RT_NOREF2(pVCpu, cbInstr);
     2022    /** @todo NSTVMX: VMLAUNCH impl. */
     2023    return VERR_IEM_IPE_2;
     2024}
     2025
     2026
     2027/**
    19812028 * Implements 'VMPTRLD'.
    19822029 */
     
    20502097}
    20512098
    2052 
    20532099#endif
    20542100
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsTwoByte0f.cpp.h

    r73983 r74015  
    248248
    249249/** Opcode 0x0f 0x01 /0. */
     250#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
     251FNIEMOP_DEF(iemOp_Grp7_vmlaunch)
     252{
     253    IEMOP_MNEMONIC(vmlaunch, "vmlaunch");
     254    IEMOP_HLP_DONE_DECODING();
     255    return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_vmlaunch);
     256}
     257#else
    250258FNIEMOP_DEF(iemOp_Grp7_vmlaunch)
    251259{
     
    253261    return IEMOP_RAISE_INVALID_OPCODE();
    254262}
     263#endif
    255264
    256265
     
    42834292{
    42844293    IEMOP_MNEMONIC(vmread, "vmread Ey,Gy");
    4285     IEMOP_HLP_IN_VMX_OPERATION();
    4286     IEMOP_HLP_VMX_INSTR();
     4294    IEMOP_HLP_IN_VMX_OPERATION("vmread", kVmxVInstrDiag_Vmread);
     4295    IEMOP_HLP_VMX_INSTR("vmread", kVmxVInstrDiag_Vmread);
    42874296    IEMMODE const enmEffOpSize = pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT ? IEMMODE_64BIT : IEMMODE_32BIT;
    42884297
     
    43654374{
    43664375    IEMOP_MNEMONIC(vmwrite, "vmwrite Gy,Ey");
    4367     IEMOP_HLP_IN_VMX_OPERATION();
    4368     IEMOP_HLP_VMX_INSTR();
     4376    IEMOP_HLP_IN_VMX_OPERATION("vmwrite", kVmxVInstrDiag_Vmwrite);
     4377    IEMOP_HLP_VMX_INSTR("vmwrite", kVmxVInstrDiag_Vmwrite);
    43694378    IEMMODE const enmEffOpSize = pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT ? IEMMODE_64BIT : IEMMODE_32BIT;
    43704379
     
    85808589{
    85818590    IEMOP_MNEMONIC(vmptrld, "vmptrld");
    8582     IEMOP_HLP_IN_VMX_OPERATION();
    8583     IEMOP_HLP_VMX_INSTR();
     8591    IEMOP_HLP_IN_VMX_OPERATION("vmptrld", kVmxVInstrDiag_Vmptrld);
     8592    IEMOP_HLP_VMX_INSTR("vmptrld", kVmxVInstrDiag_Vmptrld);
    85848593    IEM_MC_BEGIN(2, 0);
    85858594    IEM_MC_ARG(uint8_t, iEffSeg,     0);
     
    86018610{
    86028611    IEMOP_MNEMONIC(vmclear, "vmclear");
    8603     IEMOP_HLP_IN_VMX_OPERATION();
    8604     IEMOP_HLP_VMX_INSTR();
     8612    IEMOP_HLP_IN_VMX_OPERATION("vmclear", kVmxVInstrDiag_Vmclear);
     8613    IEMOP_HLP_VMX_INSTR("vmclear", kVmxVInstrDiag_Vmclear);
    86058614    IEM_MC_BEGIN(2, 0);
    86068615    IEM_MC_ARG(uint8_t, iEffSeg,     0);
     
    86228631{
    86238632    IEMOP_MNEMONIC(vmxon, "vmxon");
    8624     IEMOP_HLP_VMX_INSTR();
     8633    IEMOP_HLP_VMX_INSTR("vmxon", kVmxVInstrDiag_Vmxon);
    86258634    IEM_MC_BEGIN(2, 0);
    86268635    IEM_MC_ARG(uint8_t, iEffSeg,     0);
     
    86428651{
    86438652    IEMOP_MNEMONIC(vmptrst, "vmptrst");
    8644     IEMOP_HLP_IN_VMX_OPERATION();
    8645     IEMOP_HLP_VMX_INSTR();
     8653    IEMOP_HLP_IN_VMX_OPERATION("vmptrst", kVmxVInstrDiag_Vmptrst);
     8654    IEMOP_HLP_VMX_INSTR("vmptrst", kVmxVInstrDiag_Vmptrst);
    86468655    IEM_MC_BEGIN(2, 0);
    86478656    IEM_MC_ARG(uint8_t, iEffSeg,     0);
  • trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp

    r73937 r74015  
    129129#define IEMOP_HLP_DONE_DECODING_NO_SIZE_OP_REPZ_OR_REPNZ_PREFIXES()                                 do { } while (0)
    130130#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
    131 # define IEMOP_HLP_VMX_INSTR()                              do { } while (0)
    132 # define IEMOP_HLP_IN_VMX_OPERATION()                       do { } while (0)
     131# define IEMOP_HLP_VMX_INSTR(a_szInstr, a_InsDiagPrefix)                                            do { } while (0)
     132# define IEMOP_HLP_IN_VMX_OPERATION(a_szInstr, a_InsDiagPrefix)                                     do { } while (0)
    133133#endif
    134134
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