Changeset 80458 in vbox
- Timestamp:
- Aug 28, 2019 8:30:21 AM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
r80386 r80458 13772 13772 13773 13773 13774 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX 13775 /** 13776 * Deals with VMCPU_FF_VMX_APIC_WRITE, VMCPU_FF_VMX_MTF, VMCPU_FF_VMX_NMI_WINDOW 13777 * and VMCPU_FF_VMX_INT_WINDOW. 13778 * 13779 * @returns Modified rcStrict. 13780 * @param pVCpu The cross context virtual CPU structure of the calling thread. 13781 * @param rcStrict The instruction execution status. 13782 */ 13783 static VBOXSTRICTRC iemHandleNestedInstructionBoundraryFFs(PVMCPUCC pVCpu, VBOXSTRICTRC rcStrict) 13784 { 13785 if (!VMCPU_FF_IS_ANY_SET(pVCpu, VMCPU_FF_VMX_APIC_WRITE | VMCPU_FF_VMX_MTF)) 13786 { 13787 /* VMX preemption timer takes priority over NMI-window exits. */ 13788 if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_PREEMPT_TIMER)) 13789 { 13790 rcStrict = iemVmxVmexitPreemptTimer(pVCpu); 13791 if (rcStrict == VINF_VMX_INTERCEPT_NOT_ACTIVE) 13792 rcStrict = VINF_SUCCESS; 13793 else 13794 { 13795 Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)); 13796 Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_PREEMPT_TIMER)); 13797 return rcStrict; 13798 } 13799 } 13800 else 13801 rcStrict = VINF_SUCCESS; 13802 13803 /* 13804 * Check remaining intercepts. 13805 * 13806 * NMI-window and Interrupt-window VM-exits. 13807 * Interrupt shadow (block-by-STI and Mov SS) inhibits interrupts and may also block NMIs. 13808 * Event injection during VM-entry takes priority over NMI-window and interrupt-window VM-exits. 13809 * 13810 * See Intel spec. 26.7.6 "NMI-Window Exiting". 13811 * See Intel spec. 26.7.5 "Interrupt-Window Exiting and Virtual-Interrupt Delivery". 13812 */ 13813 if ( VMCPU_FF_IS_ANY_SET(pVCpu, VMCPU_FF_VMX_NMI_WINDOW | VMCPU_FF_VMX_INT_WINDOW) 13814 && !VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS) 13815 && !TRPMHasTrap(pVCpu)) 13816 { 13817 Assert(pVCpu->cpum.GstCtx.hwvirt.vmx.fInterceptEvents); 13818 if ( VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_NMI_WINDOW) 13819 && CPUMIsGuestVmxVirtNmiBlocking(pVCpu, &pVCpu->cpum.GstCtx)) 13820 { 13821 rcStrict = iemVmxVmexit(pVCpu, VMX_EXIT_NMI_WINDOW, 0 /* u64ExitQual */); 13822 Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_NMI_WINDOW)); 13823 } 13824 else if ( VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_INT_WINDOW) 13825 && CPUMIsGuestVmxVirtIntrEnabled(pVCpu, &pVCpu->cpum.GstCtx)) 13826 { 13827 rcStrict = iemVmxVmexit(pVCpu, VMX_EXIT_INT_WINDOW, 0 /* u64ExitQual */); 13828 Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_INT_WINDOW)); 13829 } 13830 } 13831 } 13832 /* TPR-below threshold/APIC write has the highest priority. */ 13833 else if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_APIC_WRITE)) 13834 { 13835 rcStrict = iemVmxApicWriteEmulation(pVCpu); 13836 Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)); 13837 Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_APIC_WRITE)); 13838 } 13839 /* MTF takes priority over VMX-preemption timer. */ 13840 else 13841 { 13842 rcStrict = iemVmxVmexit(pVCpu, VMX_EXIT_MTF, 0 /* u64ExitQual */); 13843 Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)); 13844 Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_MTF)); 13845 } 13846 return rcStrict; 13847 } 13848 #endif /* VBOX_WITH_NESTED_HWVIRT_VMX */ 13849 13850 13774 13851 /** 13775 13852 * Makes status code addjustments (pass up from I/O and access handler) … … 13922 13999 */ 13923 14000 if ( rcStrict == VINF_SUCCESS 13924 && CPUMIsGuestInVmxNonRootMode(IEM_GET_CTX(pVCpu))) 13925 { 13926 bool fCheckRemainingIntercepts = true; 13927 /* TPR-below threshold/APIC write has the highest priority. */ 13928 if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_APIC_WRITE)) 13929 { 13930 rcStrict = iemVmxApicWriteEmulation(pVCpu); 13931 fCheckRemainingIntercepts = false; 13932 Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)); 13933 Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_APIC_WRITE)); 13934 } 13935 /* MTF takes priority over VMX-preemption timer. */ 13936 else if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_MTF)) 13937 { 13938 rcStrict = iemVmxVmexit(pVCpu, VMX_EXIT_MTF, 0 /* u64ExitQual */); 13939 fCheckRemainingIntercepts = false; 13940 Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)); 13941 Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_MTF)); 13942 } 13943 /* VMX preemption timer takes priority over NMI-window exits. */ 13944 else if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_PREEMPT_TIMER)) 13945 { 13946 rcStrict = iemVmxVmexitPreemptTimer(pVCpu); 13947 if (rcStrict == VINF_VMX_INTERCEPT_NOT_ACTIVE) 13948 rcStrict = VINF_SUCCESS; 13949 else 13950 { 13951 fCheckRemainingIntercepts = false; 13952 Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)); 13953 Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_PREEMPT_TIMER)); 13954 } 13955 } 13956 13957 /* 13958 * Check remaining intercepts. 13959 * 13960 * NMI-window and Interrupt-window VM-exits. 13961 * Interrupt shadow (block-by-STI and Mov SS) inhibits interrupts and may also block NMIs. 13962 * Event injection during VM-entry takes priority over NMI-window and interrupt-window VM-exits. 13963 * 13964 * See Intel spec. 26.7.6 "NMI-Window Exiting". 13965 * See Intel spec. 26.7.5 "Interrupt-Window Exiting and Virtual-Interrupt Delivery". 13966 */ 13967 if ( fCheckRemainingIntercepts 13968 && !TRPMHasTrap(pVCpu) 13969 && !VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)) 13970 { 13971 Assert(pVCpu->cpum.GstCtx.hwvirt.vmx.fInterceptEvents); 13972 if ( VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_NMI_WINDOW) 13973 && CPUMIsGuestVmxVirtNmiBlocking(pVCpu, &pVCpu->cpum.GstCtx)) 13974 { 13975 rcStrict = iemVmxVmexit(pVCpu, VMX_EXIT_NMI_WINDOW, 0 /* u64ExitQual */); 13976 Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_NMI_WINDOW)); 13977 } 13978 else if ( VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_INT_WINDOW) 13979 && CPUMIsGuestVmxVirtIntrEnabled(pVCpu, &pVCpu->cpum.GstCtx)) 13980 { 13981 rcStrict = iemVmxVmexit(pVCpu, VMX_EXIT_INT_WINDOW, 0 /* u64ExitQual */); 13982 Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_INT_WINDOW)); 13983 } 13984 } 13985 } 14001 && CPUMIsGuestInVmxNonRootMode(IEM_GET_CTX(pVCpu)) 14002 && VMCPU_FF_IS_ANY_SET(pVCpu, VMCPU_FF_VMX_APIC_WRITE | VMCPU_FF_VMX_MTF | VMCPU_FF_VMX_NMI_WINDOW | VMCPU_FF_VMX_INT_WINDOW)) 14003 rcStrict = iemHandleNestedInstructionBoundraryFFs(pVCpu, rcStrict); 13986 14004 #endif 13987 14005
Note:
See TracChangeset
for help on using the changeset viewer.