Changeset 99663 in vbox for trunk/src/VBox/VMM/VMMAll
- Timestamp:
- May 8, 2023 10:19:01 AM (20 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/VMXAllTemplate.cpp.h
r99659 r99663 1697 1697 1698 1698 /** 1699 * Gets the guest interruptibility-state and updates related force-flags. 1699 * Gets the guest interruptibility-state and updates related internal eflags 1700 * inhibition state. 1700 1701 * 1701 1702 * @returns Guest's interruptibility-state. 1702 * @param pVCpu 1703 * @param pVCpu The cross context virtual CPU structure. 1703 1704 * 1704 1705 * @remarks No-long-jump zone!!! 1705 1706 */ 1706 static uint32_t vmxHCGetGuestIntrState AndUpdateFFs(PVMCPUCC pVCpu)1707 static uint32_t vmxHCGetGuestIntrStateWithUpdate(PVMCPUCC pVCpu) 1707 1708 { 1708 1709 uint32_t fIntrState; … … 4858 4859 * 4859 4860 * @returns Strict VBox status code (i.e. informational status codes too). 4860 * @param pVCpu The cross context virtual CPU structure. 4861 * @param pVmcsInfo The VMCS information structure. 4862 * @param pfIntrState Where to store the VT-x guest-interruptibility state. 4863 */ 4864 static VBOXSTRICTRC vmxHCEvaluatePendingEvent(PVMCPUCC pVCpu, PVMXVMCSINFO pVmcsInfo, uint32_t *pfIntrState) 4865 { 4866 Assert(pfIntrState); 4861 * @param pVCpu The cross context virtual CPU structure. 4862 * @param pVmcsInfo The VMCS information structure. 4863 */ 4864 static VBOXSTRICTRC vmxHCEvaluatePendingEvent(PVMCPUCC pVCpu, PVMXVMCSINFO pVmcsInfo) 4865 { 4867 4866 Assert(!TRPMHasTrap(pVCpu)); 4868 4869 /*4870 * Compute/update guest-interruptibility state related FFs.4871 * The FFs will be used below while evaluating events to be injected.4872 */4873 *pfIntrState = vmxHCGetGuestIntrStateAndUpdateFFs(pVCpu);4874 4867 4875 4868 /* … … 4878 4871 */ 4879 4872 if ( !VCPU_2_VMXSTATE(pVCpu).Event.fPending 4880 && !CPUMIsInInterruptShadow WithUpdate(&pVCpu->cpum.GstCtx))4873 && !CPUMIsInInterruptShadow(&pVCpu->cpum.GstCtx)) 4881 4874 { 4882 4875 /** @todo SMI. SMIs take priority over NMIs. */ … … 4991 4984 * 4992 4985 * @returns Strict VBox status code (i.e. informational status codes too). 4993 * @param pVCpu The cross context virtual CPU structure. 4994 * @param pVmcsInfo The VMCS information structure. 4995 * @param pfIntrState Where to store the VT-x guest-interruptibility state. 4986 * @param pVCpu The cross context virtual CPU structure. 4987 * @param pVmcsInfo The VMCS information structure. 4996 4988 * 4997 4989 * @remarks The guest must be in VMX non-root mode. 4998 4990 */ 4999 static VBOXSTRICTRC vmxHCEvaluatePendingEventNested(PVMCPUCC pVCpu, PVMXVMCSINFO pVmcsInfo, uint32_t *pfIntrState) 5000 { 5001 NOREF(pVmcsInfo); 4991 static VBOXSTRICTRC vmxHCEvaluatePendingEventNested(PVMCPUCC pVCpu, PVMXVMCSINFO pVmcsInfo) 4992 { 5002 4993 PCCPUMCTX pCtx = &pVCpu->cpum.GstCtx; 5003 4994 5004 Assert(pfIntrState);5005 4995 Assert(CPUMIsGuestInVmxNonRootMode(pCtx)); 5006 4996 Assert(!TRPMHasTrap(pVCpu)); 5007 5008 /*5009 * Compute/update guest-interruptibility state related FFs.5010 * The FFs will be used below while evaluating events to be injected.5011 */5012 *pfIntrState = vmxHCGetGuestIntrStateAndUpdateFFs(pVCpu);5013 4997 5014 4998 /* … … 5038 5022 * See Intel spec. 25.4.1 "Event Blocking". 5039 5023 */ 5040 if (!CPUMIsInInterruptShadow WithUpdate(&pVCpu->cpum.GstCtx))5024 if (!CPUMIsInInterruptShadow(&pVCpu->cpum.GstCtx)) 5041 5025 { /* likely */ } 5042 5026 else … … 5108 5092 * by other VM-exits (like a preemption timer), see @bugref{9562#c18}. 5109 5093 * 5110 * See Intel spec. 25.4.1 "Event Blocking".5111 *5112 5094 * NMIs block external interrupts as they are dispatched through the interrupt gate (vector 2) 5113 5095 * which automatically clears EFLAGS.IF. Also it's possible an NMI handler could enable interrupts 5114 5096 * and thus we should not check for NMI inhibition here. 5115 5097 * 5098 * See Intel spec. 25.4.1 "Event Blocking". 5116 5099 * See Intel spec. 6.8.1 "Masking Maskable Hardware Interrupts". 5117 5100 */ 5118 5101 if ( VMCPU_FF_IS_ANY_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC) 5119 && !VCPU_2_VMXSTATE(pVCpu).fSingleInstruction 5120 && CPUMIsGuestVmxPhysIntrEnabled(pCtx)) 5102 && !VCPU_2_VMXSTATE(pVCpu).fSingleInstruction) 5121 5103 { 5122 5104 Assert(!DBGFIsStepping(pVCpu)); 5123 5124 /* Nested-guest external interrupt VM-exit. */ 5125 if ( CPUMIsGuestVmxPinCtlsSet(pCtx, VMX_PIN_CTLS_EXT_INT_EXIT) 5126 && !CPUMIsGuestVmxExitCtlsSet(pCtx, VMX_EXIT_CTLS_ACK_EXT_INT)) 5127 { 5128 VBOXSTRICTRC rcStrict = IEMExecVmxVmexitExtInt(pVCpu, 0 /* uVector */, true /* fIntPending */); 5129 Assert(rcStrict != VINF_VMX_INTERCEPT_NOT_ACTIVE); 5130 return rcStrict; 5131 } 5132 5133 /* 5134 * Fetch the external interrupt from the interrupt controller. 5135 * Once PDMGetInterrupt() returns an interrupt we -must- deliver it or pass it to 5136 * the nested-hypervisor. We cannot re-request the interrupt from the controller again. 5137 */ 5138 uint8_t u8Interrupt; 5139 int rc = PDMGetInterrupt(pVCpu, &u8Interrupt); 5140 if (RT_SUCCESS(rc)) 5141 { 5142 /* Nested-guest external interrupt VM-exit when the "acknowledge interrupt on exit" is enabled. */ 5143 if (CPUMIsGuestVmxPinCtlsSet(pCtx, VMX_PIN_CTLS_EXT_INT_EXIT)) 5105 int rc = vmxHCImportGuestStateEx(pVCpu, pVmcsInfo, CPUMCTX_EXTRN_RFLAGS); 5106 AssertRC(rc); 5107 if (CPUMIsGuestVmxPhysIntrEnabled(pCtx)) 5108 { 5109 /* Nested-guest external interrupt VM-exit. */ 5110 if ( CPUMIsGuestVmxPinCtlsSet(pCtx, VMX_PIN_CTLS_EXT_INT_EXIT) 5111 && !CPUMIsGuestVmxExitCtlsSet(pCtx, VMX_EXIT_CTLS_ACK_EXT_INT)) 5144 5112 { 5145 Assert(CPUMIsGuestVmxExitCtlsSet(pCtx, VMX_EXIT_CTLS_ACK_EXT_INT)); 5146 VBOXSTRICTRC rcStrict = IEMExecVmxVmexitExtInt(pVCpu, u8Interrupt, false /* fIntPending */); 5113 VBOXSTRICTRC rcStrict = IEMExecVmxVmexitExtInt(pVCpu, 0 /* uVector */, true /* fIntPending */); 5147 5114 Assert(rcStrict != VINF_VMX_INTERCEPT_NOT_ACTIVE); 5148 5115 return rcStrict; 5149 5116 } 5150 vmxHCSetPendingExtInt(pVCpu, u8Interrupt); 5151 return VINF_SUCCESS; 5117 5118 /* 5119 * Fetch the external interrupt from the interrupt controller. 5120 * Once PDMGetInterrupt() returns an interrupt we -must- deliver it or pass it to 5121 * the nested-hypervisor. We cannot re-request the interrupt from the controller again. 5122 */ 5123 uint8_t u8Interrupt; 5124 rc = PDMGetInterrupt(pVCpu, &u8Interrupt); 5125 if (RT_SUCCESS(rc)) 5126 { 5127 /* Nested-guest external interrupt VM-exit when the "acknowledge interrupt on exit" is enabled. */ 5128 if (CPUMIsGuestVmxPinCtlsSet(pCtx, VMX_PIN_CTLS_EXT_INT_EXIT)) 5129 { 5130 Assert(CPUMIsGuestVmxExitCtlsSet(pCtx, VMX_EXIT_CTLS_ACK_EXT_INT)); 5131 VBOXSTRICTRC rcStrict = IEMExecVmxVmexitExtInt(pVCpu, u8Interrupt, false /* fIntPending */); 5132 Assert(rcStrict != VINF_VMX_INTERCEPT_NOT_ACTIVE); 5133 return rcStrict; 5134 } 5135 vmxHCSetPendingExtInt(pVCpu, u8Interrupt); 5136 return VINF_SUCCESS; 5137 } 5152 5138 } 5153 5139 }
Note:
See TracChangeset
for help on using the changeset viewer.