Changeset 81806 in vbox
- Timestamp:
- Nov 12, 2019 2:49:30 PM (5 years ago)
- svn:sync-xref-src-repo-rev:
- 134597
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
r81791 r81806 5080 5080 AssertRC(rc); 5081 5081 5082 /*5083 * Setup pending debug exceptions if the guest is single-stepping using EFLAGS.TF.5084 *5085 * We must avoid setting any automatic debug exceptions delivery when single-stepping5086 * through the hypervisor debugger using EFLAGS.TF.5087 */5088 if ( !pVmxTransient->fIsNestedGuest5089 && !pVCpu->hm.s.fSingleInstruction5090 && fEFlags.Bits.u1TF)5091 {5092 /** @todo r=ramshankar: Warning!! We ASSUME EFLAGS.TF will not cleared on5093 * premature trips to ring-3 esp since IEM does not yet handle it. */5094 rc = VMXWriteVmcsNw(VMX_VMCS_GUEST_PENDING_DEBUG_XCPTS, VMX_VMCS_GUEST_PENDING_DEBUG_XCPT_BS);5095 AssertRC(rc);5096 }5097 /* else: for nested-guest currently handling while merging controls. */5098 5099 5082 ASMAtomicUoAndU64(&pVCpu->hm.s.fCtxChanged, ~HM_CHANGED_GUEST_RFLAGS); 5100 5083 Log4Func(("eflags=%#RX32\n", fEFlags.u32)); … … 8156 8139 8157 8140 /* Clear the events from the VMCS. */ 8158 int rc = VMXWriteVmcs32(VMX_VMCS32_CTRL_ENTRY_INTERRUPTION_INFO, 0); 8159 AssertRC(rc);8141 int rc = VMXWriteVmcs32(VMX_VMCS32_CTRL_ENTRY_INTERRUPTION_INFO, 0); AssertRC(rc); 8142 rc = VMXWriteVmcs32(VMX_VMCS_GUEST_PENDING_DEBUG_XCPTS, 0); AssertRC(rc); 8160 8143 } 8161 8144 #ifdef VBOX_STRICT … … 8740 8723 Assert(VMMRZCallRing3IsEnabled(pVCpu)); 8741 8724 8742 bool const fBlockMovSS = RT_BOOL(fIntrState & VMX_VMCS_GUEST_INT_STATE_BLOCK_MOVSS); 8743 bool const fBlockSti = RT_BOOL(fIntrState & VMX_VMCS_GUEST_INT_STATE_BLOCK_STI); 8744 8745 Assert(!fBlockSti || !(ASMAtomicUoReadU64(&pVCpu->cpum.GstCtx.fExtrn) & CPUMCTX_EXTRN_RFLAGS)); 8746 Assert(!fBlockSti || pVCpu->cpum.GstCtx.eflags.Bits.u1IF); /* Cannot set block-by-STI when interrupts are disabled. */ 8747 Assert(!(fIntrState & VMX_VMCS_GUEST_INT_STATE_BLOCK_SMI)); /* We don't support block-by-SMI yet.*/ 8748 Assert(!TRPMHasTrap(pVCpu)); 8725 #ifdef VBOX_STRICT 8726 /* 8727 * Verify guest-interruptibility state. 8728 * 8729 * We put this in a scoped block so we do not accidentally use fBlockSti or fBlockMovSS, 8730 * since injecting an event may modify the interruptibility state and we must thus always 8731 * use fIntrState. 8732 */ 8733 { 8734 bool const fBlockMovSS = RT_BOOL(fIntrState & VMX_VMCS_GUEST_INT_STATE_BLOCK_MOVSS); 8735 bool const fBlockSti = RT_BOOL(fIntrState & VMX_VMCS_GUEST_INT_STATE_BLOCK_STI); 8736 Assert(!fBlockSti || !(ASMAtomicUoReadU64(&pVCpu->cpum.GstCtx.fExtrn) & CPUMCTX_EXTRN_RFLAGS)); 8737 Assert(!fBlockSti || pVCpu->cpum.GstCtx.eflags.Bits.u1IF); /* Cannot set block-by-STI when interrupts are disabled. */ 8738 Assert(!(fIntrState & VMX_VMCS_GUEST_INT_STATE_BLOCK_SMI)); /* We don't support block-by-SMI yet.*/ 8739 Assert(!TRPMHasTrap(pVCpu)); 8740 NOREF(fBlockMovSS); NOREF(fBlockSti); 8741 } 8742 #endif 8749 8743 8750 8744 VBOXSTRICTRC rcStrict = VINF_SUCCESS; … … 8762 8756 if (uIntType == VMX_ENTRY_INT_INFO_TYPE_EXT_INT) 8763 8757 { 8764 bool const fBlockInt = !(pVCpu->cpum.GstCtx.eflags.u32 & X86_EFL_IF); 8765 Assert(!fBlockInt); 8766 Assert(!fBlockSti); 8767 Assert(!fBlockMovSS); 8758 Assert(pVCpu->cpum.GstCtx.eflags.u32 & X86_EFL_IF); 8759 Assert(!(fIntrState & VMX_VMCS_GUEST_INT_STATE_BLOCK_STI)); 8760 Assert(!(fIntrState & VMX_VMCS_GUEST_INT_STATE_BLOCK_MOVSS)); 8768 8761 } 8769 8762 else if (uIntType == VMX_ENTRY_INT_INFO_TYPE_NMI) 8770 8763 { 8771 bool const fBlockNmi = RT_BOOL(fIntrState & VMX_VMCS_GUEST_INT_STATE_BLOCK_NMI); 8772 Assert(!fBlockSti); 8773 Assert(!fBlockMovSS); 8774 Assert(!fBlockNmi); 8764 Assert(!(fIntrState & VMX_VMCS_GUEST_INT_STATE_BLOCK_NMI)); 8765 Assert(!(fIntrState & VMX_VMCS_GUEST_INT_STATE_BLOCK_STI)); 8766 Assert(!(fIntrState & VMX_VMCS_GUEST_INT_STATE_BLOCK_MOVSS)); 8775 8767 } 8776 8768 #endif … … 8794 8786 8795 8787 /* 8796 * Update the guest-interruptibility state. 8788 * Deliver any pending debug exceptions if the guest is single-stepping using EFLAGS.TF and 8789 * is an interrupt shadow (block-by-STI or block-by-MOV SS). 8790 */ 8791 if ( (fIntrState & (VMX_VMCS_GUEST_INT_STATE_BLOCK_STI | VMX_VMCS_GUEST_INT_STATE_BLOCK_MOVSS)) 8792 && !pVmxTransient->fIsNestedGuest) 8793 { 8794 HMVMX_CPUMCTX_ASSERT(pVCpu, CPUMCTX_EXTRN_RFLAGS); 8795 8796 if (!pVCpu->hm.s.fSingleInstruction) 8797 { 8798 /* 8799 * Set or clear the BS bit depending on whether the trap flag is active or not. We need 8800 * to do both since we clear the BS bit from the VMCS while exiting to ring-3. 8801 */ 8802 Assert(!DBGFIsStepping(pVCpu)); 8803 uint8_t const fTrapFlag = !!(pVCpu->cpum.GstCtx.eflags.u32 & X86_EFL_TF); 8804 int rc = VMXWriteVmcsNw(VMX_VMCS_GUEST_PENDING_DEBUG_XCPTS, fTrapFlag << VMX_BF_VMCS_PENDING_DBG_XCPT_BS_SHIFT); 8805 AssertRC(rc); 8806 } 8807 else if (pVCpu->cpum.GstCtx.eflags.u32 & X86_EFL_TF) 8808 { 8809 /* 8810 * We must not deliver a debug exception when single-stepping in the hypervisor debugger 8811 * using EFLAGS.T. Instead, clear interrupt inhibition. 8812 */ 8813 Assert(!(pVCpu->CTX_SUFF(pVM)->hm.s.vmx.Msrs.ProcCtls.n.allowed1 & VMX_PROC_CTLS_MONITOR_TRAP_FLAG)); 8814 fIntrState = 0; 8815 } 8816 } 8817 /* else: for nested-guest currently handling while merging controls. */ 8818 8819 /* 8820 * Finally, update the guest-interruptibility state. 8797 8821 * 8798 * This is required for the real-on-v86 software interrupt injection case above, as well as8799 * updates to the guest state from ring-3 or IEM/REM.8822 * This is required for the real-on-v86 software interrupt injection, for 8823 * pending debug exceptions as well as updates to the guest state from ring-3 (IEM). 8800 8824 */ 8801 8825 int rc = VMXWriteVmcs32(VMX_VMCS32_GUEST_INT_STATE, fIntrState); … … 8810 8834 8811 8835 Assert(rcStrict == VINF_SUCCESS || rcStrict == VINF_EM_RESET || (rcStrict == VINF_EM_DBG_STEPPED && fStepping)); 8812 NOREF(fBlockMovSS); NOREF(fBlockSti);8813 8836 return rcStrict; 8814 8837 }
Note:
See TracChangeset
for help on using the changeset viewer.