VirtualBox

Changeset 74469 in vbox for trunk


Ignore:
Timestamp:
Sep 26, 2018 6:46:28 AM (6 years ago)
Author:
vboxsync
Message:

VMM/IEM: Nested VMX: bugref:9180 VM-exit handler for instructions with a ModR/M field that update the VM-exit instruction info. field.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/hm_vmx.h

    r74468 r74469  
    24412441 * instructions.
    24422442 * @{ */
    2443 typedef uint8_t VMXINSTRID;
    2444 #define VMXINSTRID_VALID                                        RT_BIT(7)
    2445 #define VMXINSTRID_IS_VALID(a)                                  (((a) >> 7) & 1)
    2446 #define VMXINSTRID_GET_ID(a)                                    ((a) & ~VMXINSTRID_VALID)
     2443typedef uint32_t VMXINSTRID;
     2444/** Whether the instruction ID field is valid. */
     2445#define VMXINSTRID_VALID                                        RT_BIT_32(31)
     2446/** Whether the instruction's primary operand in the Mod R/M byte (bits 0:3) is a
     2447 *  read or write. */
     2448#define VMXINSTRID_MODRM_PRIMARY_OP_W                           RT_BIT_32(30)
     2449/** Gets whether the instruction ID is valid or not.  */
     2450#define VMXINSTRID_IS_VALID(a)                                  (((a) >> 31) & 1)
     2451#define VMXINSTRID_IS_MODRM_PRIMARY_OP_W(a)                     (((a) >> 30) & 1)
     2452/** Gets the instruction ID.  */
     2453#define VMXINSTRID_GET_ID(a)                                    ((a) & ~(VMXINSTRID_VALID | VMXINSTRID_MODRM_PRIMARY_OP_W))
     2454/** No instruction ID info. */
    24472455#define VMXINSTRID_NONE                                         0
     2456
    24482457/** The OR'd rvalues are from the VT-x spec (valid bit is VBox specific): */
    2449 #define VMXINSTRID_SGDT                                         ((VMXINSTRID_VALID) | 0)
    2450 #define VMXINSTRID_SIDT                                         ((VMXINSTRID_VALID) | 1)
    2451 #define VMXINSTRID_LGDT                                         ((VMXINSTRID_VALID) | 2)
    2452 #define VMXINSTRID_LIDT                                         ((VMXINSTRID_VALID) | 3)
    2453 
    2454 #define VMXINSTRID_SLDT                                         ((VMXINSTRID_VALID) | 0)
    2455 #define VMXINSTRID_STR                                          ((VMXINSTRID_VALID) | 1)
    2456 #define VMXINSTRID_LLDT                                         ((VMXINSTRID_VALID) | 2)
    2457 #define VMXINSTRID_LTR                                          ((VMXINSTRID_VALID) | 3)
    2458 
    2459 /** The following are used internally and are not based on the VT-x spec:   */
    2460 #define VMXINSTRID_VMLAUNCH                                     ((VMXINSTRID_VALID) | 50)
    2461 #define VMXINSTRID_VMRESUME                                     ((VMXINSTRID_VALID) | 51)
     2458#define VMXINSTRID_SGDT                                         (0x0 | VMXINSTRID_VALID | VMXINSTRID_MODRM_PRIMARY_OP_W)
     2459#define VMXINSTRID_SIDT                                         (0x1 | VMXINSTRID_VALID | VMXINSTRID_MODRM_PRIMARY_OP_W)
     2460#define VMXINSTRID_LGDT                                         (0x2 | VMXINSTRID_VALID)
     2461#define VMXINSTRID_LIDT                                         (0x3 | VMXINSTRID_VALID)
     2462
     2463#define VMXINSTRID_SLDT                                         (0x0 | VMXINSTRID_VALID | VMXINSTRID_MODRM_PRIMARY_OP_W)
     2464#define VMXINSTRID_STR                                          (0x1 | VMXINSTRID_VALID | VMXINSTRID_MODRM_PRIMARY_OP_W)
     2465#define VMXINSTRID_LLDT                                         (0x2 | VMXINSTRID_VALID)
     2466#define VMXINSTRID_LTR                                          (0x3 | VMXINSTRID_VALID)
     2467
     2468/** The following IDs are used internally (some for logging, others for conveying
     2469 *  the ModR/M primary operand write bit): */
     2470#define VMXINSTRID_VMLAUNCH                                     (0x10 | VMXINSTRID_VALID)
     2471#define VMXINSTRID_VMRESUME                                     (0x12 | VMXINSTRID_VALID)
     2472#define VMXINSTRID_VMWRITE                                      (0x13 | VMXINSTRID_VALID | VMXINSTRID_MODRM_PRIMARY_OP_W)
    24622473/** @} */
    24632474
     
    30343045    /** The VM-exit instruction information. */
    30353046    VMXEXITINSTRINFO        InstrInfo;
    3036     /** Padding. */
    3037     uint32_t                u32Padding0;
     3047    /** The VM-exit instruction ID. */
     3048    VMXINSTRID              uInstrId;
    30383049
    30393050    /** The VM-exit qualification field. */
     
    30443055     *  instruction VM-exit. */
    30453056    RTGCPTR                 GCPtrEffAddr;
    3046 
    3047     /** The VM-exit instruction ID. */
    3048     VMXINSTRID              uInstrId;
    30493057} VMXVEXITINFO;
    30503058/** Pointer to the VMXVEXITINFO struct. */
     
    30523060/** Pointer to a const VMXVEXITINFO struct. */
    30533061typedef const VMXVEXITINFO *PCVMXVEXITINFO;
     3062AssertCompileMemberAlignment(VMXVEXITINFO, u64Qual, 8);
    30543063
    30553064/**
     
    30633072 * Intel but for our own requirements) as we use it to offset into guest memory.
    30643073 *
     3074 * Although the guest is supposed to access the VMCS only through the execution of
     3075 * VMX instructions (VMREAD, VMWRITE etc.), since the VMCS may reside in guest
     3076 * memory (e.g, active but not current VMCS), for saved-states compatibility, and
     3077 * for teleportation purposes, any newly added fields should be added to the
     3078 * appropriate reserved sections or at the end of the structure.
     3079 *
    30653080 * We always treat natural-width fields as 64-bit in our implementation since
    30663081 * it's easier, allows for teleporation in the future and does not affect guest
    30673082 * software.
    3068  *
    3069  * Although the guest is supposed to access the VMCS only through the execution of
    3070  * VMX instructions (VMREAD, VMWRITE etc.), since the VMCS may reside in guest
    3071  * memory (e.g, active but not current VMCS), for saved-states compatibility, and
    3072  * for teleportation (when implemented) any newly added fields should be added to
    3073  * the appropriate reserved sections or at the end of the structure.
    30743083 */
    30753084#pragma pack(1)
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h

    r74468 r74469  
    877877 * @param   pVCpu           The cross context virtual CPU structure.
    878878 * @param   uExitReason     The VM-exit reason.
    879  * @param   uInstrId        The VM-exit instruction identity (VMXINSTRID_XXX) if
    880  *                          any. Pass VMXINSTRID_NONE otherwise.
    881  * @param   fPrimaryOpRead  If the primary operand of the ModR/M byte (bits 0:3) is
    882  *                          a read or write.
     879 * @param   uInstrId        The VM-exit instruction identity (VMXINSTRID_XXX).
    883880 * @param   pGCPtrDisp      Where to store the displacement field. Optional, can be
    884881 *                          NULL.
    885882 */
    886 IEM_STATIC uint32_t iemVmxGetExitInstrInfo(PVMCPU pVCpu, uint32_t uExitReason, VMXINSTRID uInstrId, bool fPrimaryOpRead,
    887                                            PRTGCPTR pGCPtrDisp)
     883IEM_STATIC uint32_t iemVmxGetExitInstrInfo(PVMCPU pVCpu, uint32_t uExitReason, VMXINSTRID uInstrId, PRTGCPTR pGCPtrDisp)
    888884{
    889885    RTGCPTR          GCPtrDisp;
     
    907903        uint8_t idxReg1;
    908904        uint8_t idxReg2;
    909         if (fPrimaryOpRead)
     905        if (!VMXINSTRID_IS_MODRM_PRIMARY_OP_W(uInstrId))
    910906        {
    911907            idxReg1 = ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg;
     
    11531149         */
    11541150        uint8_t idxReg2;
    1155         if (fPrimaryOpRead)
     1151        if (!VMXINSTRID_IS_MODRM_PRIMARY_OP_W(uInstrId))
    11561152        {
    11571153            idxReg2 = bRm & X86_MODRM_RM_MASK;
     
    11871183        {
    11881184            Assert(VMXINSTRID_IS_VALID(uInstrId));
     1185            Assert(VMXINSTRID_GET_ID(uInstrId) == (uInstrId & 0x3));
    11891186            ExitInstrInfo.GdtIdt.u2InstrId = VMXINSTRID_GET_ID(uInstrId);
    11901187            ExitInstrInfo.GdtIdt.u2Undef0  = 0;
     
    11951192        {
    11961193            Assert(VMXINSTRID_IS_VALID(uInstrId));
     1194            Assert(VMXINSTRID_GET_ID(uInstrId) == (uInstrId & 0x3));
    11971195            ExitInstrInfo.LdtTr.u2InstrId = VMXINSTRID_GET_ID(uInstrId);
    11981196            ExitInstrInfo.LdtTr.u2Undef0 = 0;
     
    12111209    if (pGCPtrDisp)
    12121210        *pGCPtrDisp = GCPtrDisp;
     1211
    12131212    return ExitInstrInfo.u;
    12141213}
     
    33693368
    33703369/**
     3370 * VMX VM-exit handler for VM-exits due to instruction execution.
     3371 *
     3372 * @param   pVCpu           The cross context virtual CPU structure.
     3373 * @param   uExitReason     The VM-exit reason.
     3374 * @param   uInstrid        The instruction identity (VMXINSTRID_XXX).
     3375 * @param   cbInstr         The instruction length (in bytes).
     3376 */
     3377IEM_STATIC VBOXSTRICTRC iemVmxVmexitInstr(PVMCPU pVCpu, uint32_t uExitReason, VMXINSTRID uInstrId, uint8_t cbInstr)
     3378{
     3379    /* Construct the VM-exit instruction information. */
     3380    RTGCPTR GCPtrDisp;
     3381    uint32_t const uExitInstrInfo = iemVmxGetExitInstrInfo(pVCpu, uExitReason, uInstrId, &GCPtrDisp);
     3382
     3383    /* Update the VM-exit instruction information. */
     3384    iemVmxVmcsSetExitInstrInfo(pVCpu, uExitInstrInfo);
     3385
     3386    /*
     3387     * Update the VM-exit qualification field with displacement bytes.
     3388     * See Intel spec. 27.2.1 "Basic VM-Exit Information".
     3389     */
     3390    switch (uExitReason)
     3391    {
     3392        case VMX_EXIT_INVEPT:
     3393        case VMX_EXIT_INVPCID:
     3394        case VMX_EXIT_LDTR_TR_ACCESS:
     3395        case VMX_EXIT_GDTR_IDTR_ACCESS:
     3396        case VMX_EXIT_VMCLEAR:
     3397        case VMX_EXIT_VMPTRLD:
     3398        case VMX_EXIT_VMPTRST:
     3399        case VMX_EXIT_VMREAD:
     3400        case VMX_EXIT_VMWRITE:
     3401        case VMX_EXIT_VMXON:
     3402        case VMX_EXIT_XRSTORS:
     3403        case VMX_EXIT_XSAVES:
     3404        case VMX_EXIT_RDRAND:
     3405        case VMX_EXIT_RDSEED:
     3406            iemVmxVmcsSetExitQual(pVCpu, GCPtrDisp);
     3407            break;
     3408
     3409        default:
     3410            AssertMsgFailedReturn(("Use instruction-specific handler\n"), VERR_IEM_IPE_5);
     3411    }
     3412
     3413    /* Update the VM-exit instruction length field. */
     3414    Assert(cbInstr <= 15);
     3415    iemVmxVmcsSetExitInstrLen(pVCpu, cbInstr);
     3416
     3417    /* Perform the VM-exit. */
     3418    return iemVmxVmexit(pVCpu, uExitReason);
     3419}
     3420
     3421
     3422/**
    33713423 * Checks guest control registers, debug registers and MSRs as part of VM-entry.
    33723424 *
    3373  * @param   pVCpu           The cross context virtual CPU structure.
    3374  * @param   pszInstr        The VMX instruction name (for logging purposes).
     3425 * @param   pVCpu       The cross context virtual CPU structure.
     3426 * @param   pszInstr    The VMX instruction name (for logging purposes).
    33753427 */
    33763428IEM_STATIC int iemVmxVmentryCheckGuestControlRegsMsrs(PVMCPU pVCpu, const char *pszInstr)
     
    34793531        IEM_VMX_VMENTRY_FAILED_RET(pVCpu, pszInstr, pszFailure, kVmxVDiag_Vmentry_GuestEferMsrRsvd);
    34803532
    3481     bool const fGstLma        = RT_BOOL(pVmcs->u64HostEferMsr.u & MSR_K6_EFER_BIT_LMA);
    3482     bool const fGstLme        = RT_BOOL(pVmcs->u64HostEferMsr.u & MSR_K6_EFER_BIT_LME);
     3533    bool const fGstLma = RT_BOOL(pVmcs->u64HostEferMsr.u & MSR_K6_EFER_BIT_LMA);
     3534    bool const fGstLme = RT_BOOL(pVmcs->u64HostEferMsr.u & MSR_K6_EFER_BIT_LME);
    34833535    if (   fGstInLongMode == fGstLma
    34843536        && (   !(pVmcs->u64GuestCr0.u & X86_CR0_PG)
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