Changeset 74693 in vbox
- Timestamp:
- Oct 9, 2018 5:15:41 AM (6 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
-
include/VBox/vmm/hm_vmx.h (modified) (2 diffs)
-
src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h (modified) (3 diffs)
-
src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/hm_vmx.h
r74683 r74693 2504 2504 #define VMXINSTRID_IO_OUT (0x16 | VMXINSTRID_VALID) 2505 2505 #define VMXINSTRID_IO_OUTS (0x17 | VMXINSTRID_VALID) 2506 #define VMXINSTRID_MOV_TO_DRX (0x18 | VMXINSTRID_VALID) 2507 #define VMXINSTRID_MOV_FROM_DRX (0x19 | VMXINSTRID_VALID) 2506 2508 /** @} */ 2507 2509 … … 2612 2614 /** 8-11: General purpose register number. */ 2613 2615 #define VMX_EXIT_QUAL_DRX_GENREG(a) (((a) >> 8) & 0xf) 2614 /** Rest: reserved. */ 2616 2617 /** Bit fields for Exit qualification due to Mov DRx. */ 2618 #define VMX_BF_EXIT_QUAL_DRX_REGISTER_SHIFT 0 2619 #define VMX_BF_EXIT_QUAL_DRX_REGISTER_MASK UINT64_C(0x0000000000000007) 2620 #define VMX_BF_EXIT_QUAL_DRX_RSVD_1_SHIFT 3 2621 #define VMX_BF_EXIT_QUAL_DRX_RSVD_1_MASK UINT64_C(0x0000000000000008) 2622 #define VMX_BF_EXIT_QUAL_DRX_DIRECTION_SHIFT 4 2623 #define VMX_BF_EXIT_QUAL_DRX_DIRECTION_MASK UINT64_C(0x0000000000000010) 2624 #define VMX_BF_EXIT_QUAL_DRX_RSVD_5_7_SHIFT 5 2625 #define VMX_BF_EXIT_QUAL_DRX_RSVD_5_7_MASK UINT64_C(0x00000000000000e0) 2626 #define VMX_BF_EXIT_QUAL_DRX_GENREG_SHIFT 8 2627 #define VMX_BF_EXIT_QUAL_DRX_GENREG_MASK UINT64_C(0x0000000000000f00) 2628 #define VMX_BF_EXIT_QUAL_DRX_RSVD_12_63_SHIFT 12 2629 #define VMX_BF_EXIT_QUAL_DRX_RSVD_12_63_MASK UINT64_C(0xfffffffffffff000) 2630 RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_EXIT_QUAL_DRX_, UINT64_C(0), UINT64_MAX, 2631 (REGISTER, RSVD_1, DIRECTION, RSVD_5_7, GENREG, RSVD_12_63)); 2615 2632 /** @} */ 2616 2633 -
trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h
r74661 r74693 5282 5282 { 5283 5283 IEM_SVM_CHECK_READ_CR0_INTERCEPT(pVCpu, 0 /* uExitInfo1 */, 0 /* uExitInfo2 */); 5284 /** @todo NSTVMX: SMSW CR0 masking. */ 5284 5285 5285 5286 switch (enmEffOpSize) … … 5901 5902 IEM_CIMPL_DEF_2(iemCImpl_mov_Rd_Dd, uint8_t, iGReg, uint8_t, iDrReg) 5902 5903 { 5904 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX 5905 /* 5906 * Check nested-guest VMX intercept. 5907 * Unlike most other intercepts, the Mov DRx intercept takes preceedence 5908 * over CPL and CR4.DE and even DR4/DR5 checks. 5909 * 5910 * See Intel spec. 25.1.3 "Instructions That Cause VM Exits Conditionally". 5911 */ 5912 if (IEM_VMX_IS_NON_ROOT_MODE(pVCpu)) 5913 { 5914 VBOXSTRICTRC rcStrict = iemVmxVmexitInstrMovDrX(pVCpu, VMXINSTRID_MOV_FROM_DRX, iDrReg, iGReg, cbInstr); 5915 if (rcStrict != VINF_VMX_INTERCEPT_NOT_ACTIVE) 5916 return rcStrict; 5917 } 5918 #endif 5919 5903 5920 /* 5904 5921 * Check preconditions. 5905 5922 */ 5906 5907 5923 /* Raise GPs. */ 5908 5924 if (pVCpu->iem.s.uCpl != 0) … … 5994 6010 IEM_CIMPL_DEF_2(iemCImpl_mov_Dd_Rd, uint8_t, iDrReg, uint8_t, iGReg) 5995 6011 { 6012 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX 6013 /* 6014 * Check nested-guest VMX intercept. 6015 * Unlike most other intercepts, the Mov DRx intercept takes preceedence 6016 * over CPL and CR4.DE and even DR4/DR5 checks. 6017 * 6018 * See Intel spec. 25.1.3 "Instructions That Cause VM Exits Conditionally". 6019 */ 6020 if (IEM_VMX_IS_NON_ROOT_MODE(pVCpu)) 6021 { 6022 VBOXSTRICTRC rcStrict = iemVmxVmexitInstrMovDrX(pVCpu, VMXINSTRID_MOV_TO_DRX, iDrReg, iGReg, cbInstr); 6023 if (rcStrict != VINF_VMX_INTERCEPT_NOT_ACTIVE) 6024 return rcStrict; 6025 } 6026 #endif 6027 5996 6028 /* 5997 6029 * Check preconditions. -
trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h
r74684 r74693 3292 3292 3293 3293 /** 3294 * VMX VM-exit handler for VM-exits due to 'Mov DRx,GReg' (DRx write) and 'Mov 3295 * GReg,DRx' (DRx read). 3296 * 3297 * @returns VBox strict status code. 3298 * @param pVCpu The cross context virtual CPU structure. 3299 * @param uInstrid The instruction identity (VMXINSTRID_MOV_TO_DRX or 3300 * VMXINSTRID_MOV_FROM_DRX). 3301 * @param iDrReg The debug register being accessed. 3302 * @param iGReg The general register to/from which the DRx value is being 3303 * store/loaded. 3304 * @param cbInstr The instruction length in bytes. 3305 */ 3306 IEM_STATIC VBOXSTRICTRC iemVmxVmexitInstrMovDrX(PVMCPU pVCpu, VMXINSTRID uInstrId, uint8_t iDrReg, uint8_t iGReg, 3307 uint8_t cbInstr) 3308 { 3309 Assert(iDrReg <= 7); 3310 Assert(uInstrId == VMXINSTRID_MOV_TO_DRX || uInstrId == VMXINSTRID_MOV_FROM_DRX); 3311 3312 PCVMXVVMCS pVmcs = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs); 3313 Assert(pVmcs); 3314 3315 if (pVmcs->u32ProcCtls & VMX_PROC_CTLS_MOV_DR_EXIT) 3316 { 3317 uint32_t const uDirection = uInstrId == VMXINSTRID_MOV_TO_DRX ? VMX_EXIT_QUAL_DRX_DIRECTION_WRITE 3318 : VMX_EXIT_QUAL_DRX_DIRECTION_READ; 3319 VMXVEXITINFO ExitInfo; 3320 RT_ZERO(ExitInfo); 3321 ExitInfo.uReason = VMX_EXIT_MOV_DRX; 3322 ExitInfo.cbInstr = cbInstr; 3323 ExitInfo.u64Qual = RT_BF_MAKE(VMX_BF_EXIT_QUAL_DRX_REGISTER, iDrReg) 3324 | RT_BF_MAKE(VMX_BF_EXIT_QUAL_DRX_DIRECTION, uDirection) 3325 | RT_BF_MAKE(VMX_BF_EXIT_QUAL_DRX_GENREG, iGReg); 3326 return iemVmxVmexitInstrWithInfo(pVCpu, &ExitInfo); 3327 } 3328 3329 return VINF_VMX_INTERCEPT_NOT_ACTIVE; 3330 } 3331 3332 3333 /** 3294 3334 * VMX VM-exit handler for VM-exits due to I/O instructions (IN and OUT). 3295 3335 * … … 3355 3395 if (fIntercept) 3356 3396 { 3357 uint32_t const uDirection = uInstrId == VMXINSTRID_IO_INS ? VMX_EXIT_QUAL_IO_DIRECTION_IN 3358 : VMX_EXIT_QUAL_IO_DIRECTION_OUT; 3397 /* 3398 * Figure out the guest-linear address and the direction bit (INS/OUTS). 3399 */ 3400 /** @todo r=ramshankar: Is there something in IEM that already does this? */ 3401 static uint64_t const s_auAddrSizeMasks[] = { UINT64_C(0xffff), UINT64_C(0xffffffff), UINT64_C(0xffffffffffffffff) }; 3402 uint8_t const iSegReg = ExitInstrInfo.StrIo.iSegReg; 3403 uint8_t const uAddrSize = ExitInstrInfo.StrIo.u3AddrSize; 3404 uint64_t const uAddrSizeMask = s_auAddrSizeMasks[uAddrSize]; 3405 3406 uint32_t uDirection; 3407 uint64_t uGuestLinearAddr; 3408 if (uInstrId == VMXINSTRID_IO_INS) 3409 { 3410 uDirection = VMX_EXIT_QUAL_IO_DIRECTION_IN; 3411 uGuestLinearAddr = pVCpu->cpum.GstCtx.aSRegs[iSegReg].u64Base + (pVCpu->cpum.GstCtx.rdi & uAddrSizeMask); 3412 } 3413 else 3414 { 3415 uDirection = VMX_EXIT_QUAL_IO_DIRECTION_OUT; 3416 uGuestLinearAddr = pVCpu->cpum.GstCtx.aSRegs[iSegReg].u64Base + (pVCpu->cpum.GstCtx.rsi & uAddrSizeMask); 3417 } 3418 3419 /* 3420 * If the segment is ununsable, the guest-linear address in undefined. 3421 * We shall clear it for consistency. 3422 * 3423 * See Intel spec. 27.2.1 "Basic VM-Exit Information". 3424 */ 3425 if (pVCpu->cpum.GstCtx.aSRegs[iSegReg].Attr.n.u1Unusable) 3426 uGuestLinearAddr = 0; 3427 3359 3428 VMXVEXITINFO ExitInfo; 3360 3429 RT_ZERO(ExitInfo); 3361 ExitInfo.uReason = VMX_EXIT_IO_INSTR; 3362 ExitInfo.cbInstr = cbInstr; 3363 ExitInfo.InstrInfo = ExitInstrInfo; 3364 ExitInfo.u64Qual = RT_BF_MAKE(VMX_BF_EXIT_QUAL_IO_WIDTH, cbAccess - 1) 3365 | RT_BF_MAKE(VMX_BF_EXIT_QUAL_IO_DIRECTION, uDirection) 3366 | RT_BF_MAKE(VMX_BF_EXIT_QUAL_IO_IS_STRING, 1) 3367 | RT_BF_MAKE(VMX_BF_EXIT_QUAL_IO_IS_REP, fRep) 3368 | RT_BF_MAKE(VMX_BF_EXIT_QUAL_IO_ENCODING, 0) /* DX (not immediate). */ 3369 | RT_BF_MAKE(VMX_BF_EXIT_QUAL_IO_PORT, u16Port); 3430 ExitInfo.uReason = VMX_EXIT_IO_INSTR; 3431 ExitInfo.cbInstr = cbInstr; 3432 ExitInfo.InstrInfo = ExitInstrInfo; 3433 ExitInfo.u64GuestLinearAddr = uGuestLinearAddr; 3434 ExitInfo.u64Qual = RT_BF_MAKE(VMX_BF_EXIT_QUAL_IO_WIDTH, cbAccess - 1) 3435 | RT_BF_MAKE(VMX_BF_EXIT_QUAL_IO_DIRECTION, uDirection) 3436 | RT_BF_MAKE(VMX_BF_EXIT_QUAL_IO_IS_STRING, 1) 3437 | RT_BF_MAKE(VMX_BF_EXIT_QUAL_IO_IS_REP, fRep) 3438 | RT_BF_MAKE(VMX_BF_EXIT_QUAL_IO_ENCODING, VMX_EXIT_QUAL_IO_ENCODING_DX) 3439 | RT_BF_MAKE(VMX_BF_EXIT_QUAL_IO_PORT, u16Port); 3370 3440 return iemVmxVmexitInstrWithInfo(pVCpu, &ExitInfo); 3371 3441 }
Note:
See TracChangeset
for help on using the changeset viewer.

