VirtualBox

Changeset 99663 in vbox for trunk/src/VBox/VMM/VMMAll


Ignore:
Timestamp:
May 8, 2023 10:19:01 AM (20 months ago)
Author:
vboxsync
Message:

VMM: Nested VMX: bugref:10318 Moved vmxHCGetGuestIntrStateAndUpdateFFs outside of vmxHCEvaluatePendingEvent[Nested] as it isn't used internally. Fix callers accordingly.
Fixed superfluous call to CPUMIsInInterruptShadowWithUpdate (called unconditionally), replaced subsequent calls with CPUMIsInInterruptShadow.
Import RFLAGS explicitly when an interrupt is pending in the nested-guest case.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/VMXAllTemplate.cpp.h

    r99659 r99663  
    16971697
    16981698/**
    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.
    17001701 *
    17011702 * @returns Guest's interruptibility-state.
    1702  * @param   pVCpu           The cross context virtual CPU structure.
     1703 * @param   pVCpu   The cross context virtual CPU structure.
    17031704 *
    17041705 * @remarks No-long-jump zone!!!
    17051706 */
    1706 static uint32_t vmxHCGetGuestIntrStateAndUpdateFFs(PVMCPUCC pVCpu)
     1707static uint32_t vmxHCGetGuestIntrStateWithUpdate(PVMCPUCC pVCpu)
    17071708{
    17081709    uint32_t fIntrState;
     
    48584859 *
    48594860 * @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 */
     4864static VBOXSTRICTRC vmxHCEvaluatePendingEvent(PVMCPUCC pVCpu, PVMXVMCSINFO pVmcsInfo)
     4865{
    48674866    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);
    48744867
    48754868    /*
     
    48784871     */
    48794872    if (   !VCPU_2_VMXSTATE(pVCpu).Event.fPending
    4880         && !CPUMIsInInterruptShadowWithUpdate(&pVCpu->cpum.GstCtx))
     4873        && !CPUMIsInInterruptShadow(&pVCpu->cpum.GstCtx))
    48814874    {
    48824875        /** @todo SMI. SMIs take priority over NMIs. */
     
    49914984 *
    49924985 * @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.
    49964988 *
    49974989 * @remarks The guest must be in VMX non-root mode.
    49984990 */
    4999 static VBOXSTRICTRC vmxHCEvaluatePendingEventNested(PVMCPUCC pVCpu, PVMXVMCSINFO pVmcsInfo, uint32_t *pfIntrState)
    5000 {
    5001     NOREF(pVmcsInfo);
     4991static VBOXSTRICTRC vmxHCEvaluatePendingEventNested(PVMCPUCC pVCpu, PVMXVMCSINFO pVmcsInfo)
     4992{
    50024993    PCCPUMCTX pCtx = &pVCpu->cpum.GstCtx;
    50034994
    5004     Assert(pfIntrState);
    50054995    Assert(CPUMIsGuestInVmxNonRootMode(pCtx));
    50064996    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);
    50134997
    50144998    /*
     
    50385022     * See Intel spec. 25.4.1 "Event Blocking".
    50395023     */
    5040     if (!CPUMIsInInterruptShadowWithUpdate(&pVCpu->cpum.GstCtx))
     5024    if (!CPUMIsInInterruptShadow(&pVCpu->cpum.GstCtx))
    50415025    { /* likely */ }
    50425026    else
     
    51085092     * by other VM-exits (like a preemption timer), see @bugref{9562#c18}.
    51095093     *
    5110      * See Intel spec. 25.4.1 "Event Blocking".
    5111      *
    51125094     * NMIs block external interrupts as they are dispatched through the interrupt gate (vector 2)
    51135095     * which automatically clears EFLAGS.IF. Also it's possible an NMI handler could enable interrupts
    51145096     * and thus we should not check for NMI inhibition here.
    51155097     *
     5098     * See Intel spec. 25.4.1 "Event Blocking".
    51165099     * See Intel spec. 6.8.1 "Masking Maskable Hardware Interrupts".
    51175100     */
    51185101    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)
    51215103    {
    51225104        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))
    51445112            {
    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 */);
    51475114                Assert(rcStrict != VINF_VMX_INTERCEPT_NOT_ACTIVE);
    51485115                return rcStrict;
    51495116            }
    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            }
    51525138        }
    51535139    }
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette