Changeset 74753 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Oct 11, 2018 9:01:28 AM (6 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h
r74751 r74753 3539 3539 3540 3540 /** 3541 * VMX VM-exit handler for VM-exits due to MWAIT. 3542 * 3543 * @returns VBox strict status code. 3544 * @param pVCpu The cross context virtual CPU structure. 3545 * @param fMonitorHwArmed Whether the address-range monitor hardware is armed. 3546 * @param cbInstr The instruction length in bytes. 3547 */ 3548 IEM_STATIC VBOXSTRICTRC iemVmxVmexitInstrMwait(PVMCPU pVCpu, bool fMonitorHwArmed, uint8_t cbInstr) 3549 { 3550 VMXVEXITINFO ExitInfo; 3551 RT_ZERO(ExitInfo); 3552 ExitInfo.uReason = VMX_EXIT_MWAIT; 3553 ExitInfo.cbInstr = cbInstr; 3554 ExitInfo.u64Qual = fMonitorHwArmed; 3555 return iemVmxVmexitInstrWithInfo(pVCpu, &ExitInfo); 3556 } 3557 3558 3559 /** 3560 * VMX VM-exit handler for VM-exits due to PAUSE. 3561 * 3562 * @returns VBox strict status code. 3563 * @param pVCpu The cross context virtual CPU structure. 3564 * @param cbInstr The instruction length in bytes. 3565 */ 3566 IEM_STATIC VBOXSTRICTRC iemVmxVmexitInstrPause(PVMCPU pVCpu, uint8_t cbInstr) 3567 { 3568 PCVMXVVMCS pVmcs = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs); 3569 Assert(pVmcs); 3570 3571 /* 3572 * The PAUSE VM-exit is controlled by the "PAUSE exiting" control and the 3573 * "PAUSE-loop exiting" control. 3574 * 3575 * The PLE-Gap is the maximum number of TSC ticks between two successive executions of 3576 * the PAUSE instruction before we cause a VM-exit. The PLE-Window is the maximum amount 3577 * of TSC ticks the guest is allowed to execute in a pause loop before we must cause 3578 * a VM-exit. 3579 * 3580 * See Intel spec. 24.6.13 "Controls for PAUSE-Loop Exiting". 3581 * See Intel spec. 25.1.3 "Instructions That Cause VM Exits Conditionally". 3582 */ 3583 bool fIntercept = false; 3584 if (pVmcs->u32ProcCtls & VMX_PROC_CTLS_PAUSE_EXIT) 3585 fIntercept = true; 3586 else if (pVmcs->u32ProcCtls2 & VMX_PROC_CTLS2_PAUSE_LOOP_EXIT) 3587 { 3588 IEM_CTX_IMPORT_RET(pVCpu, CPUMCTX_EXTRN_HWVIRT); 3589 3590 uint64_t *puFirstPauseLoopTick = &pVCpu->cpum.GstCtx.hwvirt.vmx.uFirstPauseLoopTick; 3591 uint64_t const uPrevPauseTick = pVCpu->cpum.GstCtx.hwvirt.vmx.uPrevPauseTick; 3592 uint32_t const uPleGap = pVmcs->u32PleGap; 3593 uint32_t const uPleWindow = pVmcs->u32PleWindow; 3594 uint64_t const uTick = TMCpuTickGet(pVCpu); 3595 if (uTick - uPrevPauseTick > uPleGap) 3596 *puFirstPauseLoopTick = uTick; 3597 else if (uTick - *puFirstPauseLoopTick > uPleWindow) 3598 fIntercept = true; 3599 } 3600 3601 if (fIntercept) 3602 { 3603 VMXVEXITINFO ExitInfo; 3604 RT_ZERO(ExitInfo); 3605 ExitInfo.uReason = VMX_EXIT_PAUSE; 3606 ExitInfo.cbInstr = cbInstr; 3607 return iemVmxVmexitInstrWithInfo(pVCpu, &ExitInfo); 3608 } 3609 3610 return VINF_VMX_INTERCEPT_NOT_ACTIVE; 3611 } 3612 3613 3614 /** 3541 3615 * VMX VM-exit handler for VM-exits due to task switches. 3542 3616 * … … 3715 3789 3716 3790 return VINF_VMX_INTERCEPT_NOT_ACTIVE; 3717 }3718 3719 3720 /**3721 * VMX VM-exit handler for VM-exits due to MWAIT instruction.3722 *3723 * @returns VBox strict status code.3724 * @param pVCpu The cross context virtual CPU structure.3725 * @param fMonitorHwArmed Whether the address-range monitor hardware is armed.3726 * @param cbInstr The instruction length in bytes.3727 */3728 IEM_STATIC VBOXSTRICTRC iemVmxVmexitInstrMwait(PVMCPU pVCpu, bool fMonitorHwArmed, uint8_t cbInstr)3729 {3730 VMXVEXITINFO ExitInfo;3731 RT_ZERO(ExitInfo);3732 ExitInfo.uReason = VMX_EXIT_MWAIT;3733 ExitInfo.cbInstr = cbInstr;3734 ExitInfo.u64Qual = fMonitorHwArmed;3735 return iemVmxVmexitInstrWithInfo(pVCpu, &ExitInfo);3736 3791 } 3737 3792 … … 7051 7106 } 7052 7107 7108 7109 /** 7110 * Implements VMX's implementation of PAUSE. 7111 */ 7112 IEM_CIMPL_DEF_0(iemCImpl_vmx_pause) 7113 { 7114 if (IEM_VMX_IS_NON_ROOT_MODE(pVCpu)) 7115 { 7116 VBOXSTRICTRC rcStrict = iemVmxVmexitInstrPause(pVCpu, cbInstr); 7117 if (rcStrict != VINF_VMX_INTERCEPT_NOT_ACTIVE) 7118 return rcStrict; 7119 } 7120 7121 /* 7122 * Outside VMX non-root operation or if the PAUSE instruction does not cause 7123 * a VM-exit, the instruction operates normally. 7124 */ 7125 iemRegAddToRipAndClearRF(pVCpu, cbInstr); 7126 return VINF_SUCCESS; 7127 } 7128 7053 7129 #endif /* VBOX_WITH_NESTED_HWVIRT_VMX */ 7054 7130 -
trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsOneByte.cpp.h
r74661 r74753 4455 4455 { 4456 4456 IEMOP_MNEMONIC(pause, "pause"); 4457 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX 4458 if (IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fVmx) 4459 return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_vmx_pause); 4460 #endif 4457 4461 #ifdef VBOX_WITH_NESTED_HWVIRT_SVM 4458 4462 if (IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fSvm) -
trunk/src/VBox/VMM/VMMR3/CPUM.cpp
r74660 r74753 3189 3189 pHlp->pfnPrintf(pHlp, " fInVmxNonRootMode = %RTbool\n", pCtx->hwvirt.vmx.fInVmxNonRootMode); 3190 3190 pHlp->pfnPrintf(pHlp, " fInterceptEvents = %RTbool\n", pCtx->hwvirt.vmx.fInterceptEvents); 3191 pHlp->pfnPrintf(pHlp, " uFirstPauseLoopTick = %RX64\n", pCtx->hwvirt.vmx.uFirstPauseLoopTick); 3192 pHlp->pfnPrintf(pHlp, " uPrevPauseTick = %RX64\n", pCtx->hwvirt.vmx.uPrevPauseTick); 3191 3193 3192 3194 /** @todo NSTVMX: Dump remaining/new fields. */
Note:
See TracChangeset
for help on using the changeset viewer.