Changeset 47718 in vbox for trunk/src/VBox
- Timestamp:
- Aug 14, 2013 10:33:22 AM (11 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp
r47684 r47718 98 98 99 99 100 /** @nameMacro for checking and returning from the using function for101 * 102 * 100 /** Macro for checking and returning from the using function for 101 * \#VMEXIT intercepts that maybe caused during delivering of another 102 * event in the guest. */ 103 103 #define HMSVM_CHECK_EXIT_DUE_TO_EVENT_DELIVERY() \ 104 104 do \ … … 110 110 return rc; \ 111 111 } while (0) 112 /** @} */ 113 114 115 /** 116 * @name Exception bitmap mask for all contributory exceptions. 112 113 /** Macro for upgrading a @a a_rc to VINF_EM_DBG_STEPPED after emulating an 114 * instruction that exited. */ 115 #define HMSVM_CHECK_SINGLE_STEP(a_pVCpu, a_rc) \ 116 do { \ 117 if ((a_pVCpu)->hm.s.fSingleInstruction && (a_rc) == VINF_SUCCESS) \ 118 (a_rc) = VINF_EM_DBG_STEPPED; \ 119 } while (0) 120 121 122 /** Exception bitmap mask for all contributory exceptions. 117 123 * 118 124 * Page fault is deliberately excluded here as it's conditional as to whether … … 121 127 #define HMSVM_CONTRIBUTORY_XCPT_MASK ( RT_BIT(X86_XCPT_GP) | RT_BIT(X86_XCPT_NP) | RT_BIT(X86_XCPT_SS) | RT_BIT(X86_XCPT_TS) \ 122 128 | RT_BIT(X86_XCPT_DE)) 123 /** @} */124 129 125 130 … … 1335 1340 if (fStepping) 1336 1341 { 1342 pVCpu->hm.s.fClearTrapFlag = true; 1337 1343 pVmcb->guest.u64RFlags |= X86_EFL_TF; 1338 1344 fInterceptDB = true; … … 1650 1656 pVM, pVCpu, pVCpu->hm.s.fContextUseFlags)); 1651 1657 1652 Log4(("Load: CS:RIP=%04x:% #RX64\n", pCtx->cs.Sel, pCtx->rip));1658 Log4(("Load: CS:RIP=%04x:%RX64 EFL=%#x SS:RSP=%04x:%RX64\n", pCtx->cs.Sel, pCtx->rip, pCtx->eflags.u, pCtx->ss, pCtx->rsp)); 1653 1659 1654 1660 STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatLoadGuestState, x); … … 1895 1901 1896 1902 /** 1903 * Take necessary actions before going back to ring-3. 1904 * 1897 1905 * An action requires us to go back to ring-3. This function does the necessary 1898 1906 * steps before we can safely return to ring-3. This is not the same as longjmps … … 1947 1955 else 1948 1956 pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_HOST_CONTEXT | HM_CHANGED_ALL_GUEST; 1957 1958 /* Make sure we've undo the trap flag if we tried to single step something. */ 1959 if (pVCpu->hm.s.fClearTrapFlag) 1960 { 1961 pVCpu->hm.s.fClearTrapFlag = false; 1962 pCtx->eflags.Bits.u1TF = 0; 1963 } 1949 1964 1950 1965 STAM_COUNTER_INC(&pVCpu->hm.s.StatSwitchExitToR3); … … 3625 3640 hmR0SvmUpdateRip(pVCpu, pCtx, 2); 3626 3641 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitWbinvd); 3627 return VINF_SUCCESS; 3642 int rc = VINF_SUCCESS; 3643 HMSVM_CHECK_SINGLE_STEP(pVCpu, rc); 3644 return rc; 3628 3645 } 3629 3646 … … 3638 3655 hmR0SvmUpdateRip(pVCpu, pCtx, 2); 3639 3656 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitInvd); 3640 return VINF_SUCCESS; 3657 int rc = VINF_SUCCESS; 3658 HMSVM_CHECK_SINGLE_STEP(pVCpu, rc); 3659 return rc; 3641 3660 } 3642 3661 … … 3651 3670 int rc = EMInterpretCpuId(pVM, pVCpu, CPUMCTX2CORE(pCtx)); 3652 3671 if (RT_LIKELY(rc == VINF_SUCCESS)) 3672 { 3653 3673 hmR0SvmUpdateRip(pVCpu, pCtx, 2); 3674 HMSVM_CHECK_SINGLE_STEP(pVCpu, rc); 3675 } 3654 3676 else 3655 3677 { … … 3674 3696 hmR0SvmUpdateRip(pVCpu, pCtx, 2); 3675 3697 pSvmTransient->fUpdateTscOffsetting = true; 3698 3699 /* Single step check. */ 3700 HMSVM_CHECK_SINGLE_STEP(pVCpu, rc); 3676 3701 } 3677 3702 else … … 3696 3721 hmR0SvmUpdateRip(pVCpu, pCtx, 3); 3697 3722 pSvmTransient->fUpdateTscOffsetting = true; 3723 HMSVM_CHECK_SINGLE_STEP(pVCpu, rc); 3698 3724 } 3699 3725 else … … 3715 3741 int rc = EMInterpretRdpmc(pVCpu->CTX_SUFF(pVM), pVCpu, CPUMCTX2CORE(pCtx)); 3716 3742 if (RT_LIKELY(rc == VINF_SUCCESS)) 3743 { 3717 3744 hmR0SvmUpdateRip(pVCpu, pCtx, 2); 3745 HMSVM_CHECK_SINGLE_STEP(pVCpu, rc); 3746 } 3718 3747 else 3719 3748 { … … 3739 3768 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitInvlpg); 3740 3769 Assert(rc == VINF_SUCCESS || rc == VERR_EM_INTERPRETER); 3770 HMSVM_CHECK_SINGLE_STEP(pVCpu, rc); 3741 3771 return rc; 3742 3772 } … … 3751 3781 hmR0SvmUpdateRip(pVCpu, pCtx, 1); 3752 3782 int rc = EMShouldContinueAfterHalt(pVCpu, pCtx) ? VINF_SUCCESS : VINF_EM_HALT; 3783 HMSVM_CHECK_SINGLE_STEP(pVCpu, rc); 3753 3784 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitHlt); 3754 3785 return rc; … … 3764 3795 int rc = EMInterpretMonitor(pVCpu->CTX_SUFF(pVM), pVCpu, CPUMCTX2CORE(pCtx)); 3765 3796 if (RT_LIKELY(rc == VINF_SUCCESS)) 3797 { 3766 3798 hmR0SvmUpdateRip(pVCpu, pCtx, 3); 3799 HMSVM_CHECK_SINGLE_STEP(pVCpu, rc); 3800 } 3767 3801 else 3768 3802 { … … 3793 3827 rc = VINF_SUCCESS; 3794 3828 } 3829 HMSVM_CHECK_SINGLE_STEP(pVCpu, rc); 3795 3830 } 3796 3831 else … … 3833 3868 Assert((pSvmTransient->u64ExitCode - SVM_EXIT_READ_CR0) <= 15); 3834 3869 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitCRxRead[pSvmTransient->u64ExitCode - SVM_EXIT_READ_CR0]); 3870 HMSVM_CHECK_SINGLE_STEP(pVCpu, rc); 3835 3871 return rc; 3836 3872 } … … 3874 3910 break; 3875 3911 } 3912 HMSVM_CHECK_SINGLE_STEP(pVCpu, rc); 3876 3913 } 3877 3914 else … … 3919 3956 } 3920 3957 hmR0SvmUpdateRip(pVCpu, pCtx, 2); 3921 return VINF_SUCCESS; 3958 rc = VINF_SUCCESS; 3959 HMSVM_CHECK_SINGLE_STEP(pVCpu, rc); 3960 return rc; 3922 3961 } 3923 3962 … … 3926 3965 rc = EMInterpretWrmsr(pVM, pVCpu, CPUMCTX2CORE(pCtx)); 3927 3966 if (RT_LIKELY(rc == VINF_SUCCESS)) 3967 { 3928 3968 pCtx->rip = pVmcb->ctrl.u64NextRIP; 3969 HMSVM_CHECK_SINGLE_STEP(pVCpu, rc); 3970 } 3929 3971 else 3930 3972 AssertMsg(rc == VERR_EM_INTERPRETER, ("hmR0SvmExitMsr: EMInterpretWrmsr failed rc=%Rrc\n", rc)); … … 3932 3974 else 3933 3975 { 3934 VBOXSTRICTRC rcStrict = EMInterpretInstruction(pVCpu, CPUMCTX2CORE(pCtx), 0 /* pvFault */); 3935 rc = VBOXSTRICTRC_VAL(rcStrict); 3976 rc = VBOXSTRICTRC_TODO(EMInterpretInstruction(pVCpu, CPUMCTX2CORE(pCtx), 0 /* pvFault */)); 3936 3977 if (RT_UNLIKELY(rc != VINF_SUCCESS)) 3937 3978 AssertMsg(rc == VERR_EM_INTERPRETER, ("hmR0SvmExitMsr: WrMsr. EMInterpretInstruction failed rc=%Rrc\n", rc)); 3938 3979 /* RIP updated by EMInterpretInstruction(). */ 3980 HMSVM_CHECK_SINGLE_STEP(pVCpu, rc); 3939 3981 } 3940 3982 … … 3963 4005 rc = EMInterpretRdmsr(pVM, pVCpu, CPUMCTX2CORE(pCtx)); 3964 4006 if (RT_LIKELY(rc == VINF_SUCCESS)) 4007 { 3965 4008 pCtx->rip = pVmcb->ctrl.u64NextRIP; 4009 HMSVM_CHECK_SINGLE_STEP(pVCpu, rc); 4010 } 3966 4011 else 3967 4012 AssertMsg(rc == VERR_EM_INTERPRETER, ("hmR0SvmExitMsr: EMInterpretRdmsr failed rc=%Rrc\n", rc)); … … 3969 4014 else 3970 4015 { 3971 VBOXSTRICTRC rcStrict = EMInterpretInstruction(pVCpu, CPUMCTX2CORE(pCtx), 0); 3972 rc = VBOXSTRICTRC_VAL(rcStrict); 4016 rc = VBOXSTRICTRC_TODO(EMInterpretInstruction(pVCpu, CPUMCTX2CORE(pCtx), 0)); 3973 4017 if (RT_UNLIKELY(rc != VINF_SUCCESS)) 3974 4018 AssertMsg(rc == VERR_EM_INTERPRETER, ("hmR0SvmExitMsr: RdMsr. EMInterpretInstruction failed rc=%Rrc\n", rc)); 3975 4019 /* RIP updated by EMInterpretInstruction(). */ 4020 HMSVM_CHECK_SINGLE_STEP(pVCpu, rc); 3976 4021 } 3977 4022 } … … 4028 4073 /** @todo CPUM should set this flag! */ 4029 4074 pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_DEBUG; 4075 HMSVM_CHECK_SINGLE_STEP(pVCpu, rc); 4030 4076 } 4031 4077 else … … 4171 4217 rcStrict = rcStrict2; 4172 4218 } 4219 4220 HMSVM_CHECK_SINGLE_STEP(pVCpu, rcStrict); 4173 4221 } 4174 4222 … … 4367 4415 4368 4416 int rc = hmR0SvmEmulateMovTpr(pVCpu->CTX_SUFF(pVM), pVCpu, pCtx); 4369 if (RT_UNLIKELY(rc != VINF_SUCCESS)) 4417 if (RT_LIKELY(rc == VINF_SUCCESS)) 4418 HMSVM_CHECK_SINGLE_STEP(pVCpu, rc); 4419 else 4370 4420 hmR0SvmSetPendingXcptUD(pVCpu); 4371 4421 return VINF_SUCCESS; … … 4554 4604 4555 4605 /* If we set the trap flag above, we have to clear it. */ 4556 /** @todo HM should remember what it does and possibly do this elsewhere! */ 4557 if (pVCpu->hm.s.fSingleInstruction || DBGFIsStepping(pVCpu)) 4606 if (pVCpu->hm.s.fClearTrapFlag) 4607 { 4608 pVCpu->hm.s.fClearTrapFlag = false; 4558 4609 pCtx->eflags.Bits.u1TF = 0; 4610 } 4559 4611 4560 4612 /* This can be a fault-type #DB (instruction breakpoint) or a trap-type #DB (data breakpoint). However, for both cases -
trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
r47687 r47718 3336 3336 else 3337 3337 { 3338 pMixedCtx->eflags.u32 |= X86_EFL_TF; 3339 pVCpu->hm.s.fClearTrapFlag = true; 3340 pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_RFLAGS; 3338 3341 fInterceptDB = true; 3339 pMixedCtx->eflags.u32 |= X86_EFL_TF;3340 pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_RFLAGS;3341 3342 } 3342 3343 } … … 6081 6082 6082 6083 /** 6084 * Take necessary actions before going back to ring-3. 6085 * 6083 6086 * An action requires us to go back to ring-3. This function does the necessary 6084 6087 * steps before we can safely return to ring-3. This is not the same as longjmps … … 6151 6154 else 6152 6155 pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_HOST_CONTEXT | HM_CHANGED_ALL_GUEST; 6156 6157 /* Make sure we've undo the trap flag if we tried to single step something. */ 6158 if (pVCpu->hm.s.fClearTrapFlag) 6159 { 6160 pVCpu->hm.s.fClearTrapFlag = false; 6161 pMixedCtx->eflags.Bits.u1TF = 0; 6162 } 6153 6163 6154 6164 STAM_COUNTER_INC(&pVCpu->hm.s.StatSwitchExitToR3); … … 9653 9663 AssertRCReturn(rc, rc); 9654 9664 9655 /* If we sat the trap flag above, we have to clear it. */ /** @todo HM should remember what it does and possibly do this elsewhere! */ 9656 if ( (pVCpu->hm.s.fSingleInstruction || DBGFIsStepping(pVCpu)) 9657 && !(pVCpu->CTX_SUFF(pVM)->hm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_MONITOR_TRAP_FLAG)) 9665 /* If we sat the trap flag above, we have to clear it. */ 9666 if (pVCpu->hm.s.fClearTrapFlag) 9667 { 9668 pVCpu->hm.s.fClearTrapFlag = false; 9658 9669 pMixedCtx->eflags.Bits.u1TF = 0; 9670 } 9659 9671 9660 9672 /* Refer Intel spec. Table 27-1. "Exit Qualifications for debug exceptions" for the format. */ -
trunk/src/VBox/VMM/include/HMInternal.h
r47652 r47718 524 524 /** Whether we're executing a single instruction. */ 525 525 bool fSingleInstruction; 526 uint8_t abAlignment[3]; 526 /** Set if we need to clear the trap flag because of single stepping. */ 527 bool fClearTrapFlag; 528 uint8_t abAlignment[2]; 527 529 528 530 /** World switch exit counter. */
Note:
See TracChangeset
for help on using the changeset viewer.