Changeset 87040 in vbox for trunk/src/VBox
- Timestamp:
- Dec 4, 2020 6:28:01 AM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 141724
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h
r84505 r87040 3528 3528 * If the interrupt is pending and we -do- need to acknowledge the interrupt 3529 3529 * on VM-exit, postpone VM-exit till after the interrupt controller has been 3530 * acknowledged that the interrupt has been consumed. 3530 * acknowledged that the interrupt has been consumed. Callers would have to call 3531 * us again after getting the vector (and ofc, with fIntPending with false). 3531 3532 */ 3532 3533 return VINF_VMX_INTERCEPT_NOT_ACTIVE; … … 3536 3537 * If the interrupt is no longer pending (i.e. it has been acknowledged) and the 3537 3538 * "External interrupt exiting" and "Acknowledge interrupt on VM-exit" controls are 3538 * all set, we cause the VM-exit now. We need to record the external interrupt that3539 * just occurred in the VM-exit interruption information field.3539 * all set, we need to record the vector of the external interrupt in the 3540 * VM-exit interruption information field. Otherwise, mark this field as invalid. 3540 3541 * 3541 3542 * See Intel spec. 27.2.2 "Information for VM Exits Due to Vectored Events". 3542 3543 */ 3544 uint32_t uExitIntInfo; 3543 3545 if (pVmcs->u32ExitCtls & VMX_EXIT_CTLS_ACK_EXT_INT) 3544 3546 { 3545 bool const fNmiUnblocking = pVCpu->cpum.GstCtx.hwvirt.vmx.fNmiUnblockingIret; 3546 uint32_t const uExitIntInfo = RT_BF_MAKE(VMX_BF_EXIT_INT_INFO_VECTOR, uVector) 3547 | RT_BF_MAKE(VMX_BF_EXIT_INT_INFO_TYPE, VMX_EXIT_INT_INFO_TYPE_EXT_INT) 3548 | RT_BF_MAKE(VMX_BF_EXIT_INT_INFO_NMI_UNBLOCK_IRET, fNmiUnblocking) 3549 | RT_BF_MAKE(VMX_BF_EXIT_INT_INFO_VALID, 1); 3550 iemVmxVmcsSetExitIntInfo(pVCpu, uExitIntInfo); 3551 return iemVmxVmexit(pVCpu, VMX_EXIT_EXT_INT, 0 /* u64ExitQual */); 3552 } 3547 bool const fNmiUnblocking = pVCpu->cpum.GstCtx.hwvirt.vmx.fNmiUnblockingIret; 3548 uExitIntInfo = RT_BF_MAKE(VMX_BF_EXIT_INT_INFO_VECTOR, uVector) 3549 | RT_BF_MAKE(VMX_BF_EXIT_INT_INFO_TYPE, VMX_EXIT_INT_INFO_TYPE_EXT_INT) 3550 | RT_BF_MAKE(VMX_BF_EXIT_INT_INFO_NMI_UNBLOCK_IRET, fNmiUnblocking) 3551 | RT_BF_MAKE(VMX_BF_EXIT_INT_INFO_VALID, 1); 3552 } 3553 else 3554 uExitIntInfo = 0; 3555 iemVmxVmcsSetExitIntInfo(pVCpu, uExitIntInfo); 3556 3557 /* 3558 * Cause the VM-exit whether or not the vector has been stored 3559 * in the VM-exit interruption-information field. 3560 */ 3561 return iemVmxVmexit(pVCpu, VMX_EXIT_EXT_INT, 0 /* u64ExitQual */); 3553 3562 } 3554 3563 -
trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
r87034 r87040 8913 8913 8914 8914 /* 8915 * EFLAGS.IF does not control the blocking of external interrupts when 8916 * "External interrupt exiting" set. Fixes nasty SMP hang while executing nested-guest 8917 * VCPUs on spinlocks and aren't rescued by other VM-exits (like a preemption timer), 8918 * see @bugref{9562#c18}. 8915 * We must not check EFLAGS directly when executing a nested-guest, use 8916 * CPUMIsGuestPhysIntrEnabled() instead as EFLAGS.IF does not control the blocking of 8917 * external interrupts when "External interrupt exiting" is set. This fixes a nasty 8918 * SMP hang while executing nested-guest VCPUs on spinlocks which aren't rescued by 8919 * other VM-exits (like a preemption timer), see @bugref{9562#c18}. 8919 8920 * 8920 * See Intel spec. 25.4.1 "Event Blocking" 8921 * See Intel spec. 25.4.1 "Event Blocking". 8921 8922 */ 8923 if (CPUMIsGuestPhysIntrEnabled(pVCpu)) 8924 { 8922 8925 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX 8923 if ( fIsNestedGuest 8924 && CPUMIsGuestVmxPinCtlsSet(pCtx, VMX_PIN_CTLS_EXT_INT_EXIT) 8925 && !CPUMIsGuestVmxExitCtlsSet(pCtx, VMX_EXIT_CTLS_ACK_EXT_INT)) 8926 { 8927 VBOXSTRICTRC rcStrict = IEMExecVmxVmexitExtInt(pVCpu, 0 /* uVector */, true /* fIntPending */); 8928 Assert(rcStrict != VINF_VMX_INTERCEPT_NOT_ACTIVE); 8929 return rcStrict; 8930 } 8926 if ( fIsNestedGuest 8927 && CPUMIsGuestVmxPinCtlsSet(pCtx, VMX_PIN_CTLS_EXT_INT_EXIT)) 8928 { 8929 VBOXSTRICTRC rcStrict = IEMExecVmxVmexitExtInt(pVCpu, 0 /* uVector */, true /* fIntPending */); 8930 Assert(rcStrict != VINF_VMX_INTERCEPT_NOT_ACTIVE); 8931 return rcStrict; 8932 } 8931 8933 #endif 8932 if (pCtx->eflags.u32 & X86_EFL_IF)8933 {8934 8934 uint8_t u8Interrupt; 8935 8935 rc = PDMGetInterrupt(pVCpu, &u8Interrupt); … … 8938 8938 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX 8939 8939 if ( fIsNestedGuest 8940 && CPUMIsGuestVmxPinCtlsSet(pCtx, VMX_PIN_CTLS_EXT_INT_EXIT) 8941 && CPUMIsGuestVmxExitCtlsSet(pCtx, VMX_EXIT_CTLS_ACK_EXT_INT)) 8940 && CPUMIsGuestVmxPinCtlsSet(pCtx, VMX_PIN_CTLS_EXT_INT_EXIT)) 8942 8941 { 8943 8942 VBOXSTRICTRC rcStrict = IEMExecVmxVmexitExtInt(pVCpu, u8Interrupt, false /* fIntPending */); -
trunk/src/VBox/VMM/VMMR3/EM.cpp
r82968 r87040 1498 1498 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX 1499 1499 /* Handle the "external interrupt" VM-exit intercept. */ 1500 if ( CPUMIsGuestVmxPinCtlsSet(&pVCpu->cpum.GstCtx, VMX_PIN_CTLS_EXT_INT_EXIT) 1501 && !CPUMIsGuestVmxExitCtlsSet(&pVCpu->cpum.GstCtx, VMX_EXIT_CTLS_ACK_EXT_INT)) 1500 if (CPUMIsGuestVmxPinCtlsSet(&pVCpu->cpum.GstCtx, VMX_PIN_CTLS_EXT_INT_EXIT)) 1502 1501 { 1503 1502 VBOXSTRICTRC rcStrict = IEMExecVmxVmexitExtInt(pVCpu, 0 /* uVector */, true /* fIntPending */); -
trunk/src/VBox/VMM/VMMR3/TRPM.cpp
r82968 r87040 379 379 if ( CPUMIsGuestInVmxNonRootMode(pCtx) 380 380 && CPUMIsGuestVmxInterceptEvents(pCtx) 381 && CPUMIsGuestVmxPinCtlsSet(pCtx, VMX_PIN_CTLS_EXT_INT_EXIT) 382 && CPUMIsGuestVmxExitCtlsSet(pCtx, VMX_EXIT_CTLS_ACK_EXT_INT)) 381 && CPUMIsGuestVmxPinCtlsSet(pCtx, VMX_PIN_CTLS_EXT_INT_EXIT)) 383 382 { 384 383 VBOXSTRICTRC rcStrict = IEMExecVmxVmexitExtInt(pVCpu, u8Interrupt, false /* fIntPending */);
Note:
See TracChangeset
for help on using the changeset viewer.