VirtualBox

Changeset 99659 in vbox for trunk


Ignore:
Timestamp:
May 8, 2023 9:44:52 AM (17 months ago)
Author:
vboxsync
Message:

VMM: Nested VMX: bugref:10318 Fix external interrupt delivery/VM-exits to not check the NMI inhibition condition.
Added a comment to clarify that the delivery of the NMI (through an interrupt gate) will automatically clear EFLAGS.IF.

File:
1 edited

Legend:

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

    r99657 r99659  
    50325032
    50335033    /*
    5034      * Interrupt shadows may block NMIs.
    5035      * Interrupt shadows may block external-interrupt VM-exits.
    5036      * NMI inhibition blocks NMIs in addition to external interrupts.
     5034     * Interrupt shadows MAY block NMIs.
     5035     * They also blocks external-interrupts and MAY block external-interrupt VM-exits.
    50375036     *
    50385037     * See Intel spec. 24.4.2 "Guest Non-Register State".
    50395038     * See Intel spec. 25.4.1 "Event Blocking".
    5040      * See Intel spec. 6.7 "Nonmaskable Interrupt (NMI)".
    50415039     */
    5042     if (   !CPUMIsInInterruptShadowWithUpdate(&pVCpu->cpum.GstCtx)
    5043         && !CPUMAreInterruptsInhibitedByNmi(&pVCpu->cpum.GstCtx))
     5040    if (!CPUMIsInInterruptShadowWithUpdate(&pVCpu->cpum.GstCtx))
    50445041    { /* likely */ }
    50455042    else
     
    50495046
    50505047    /*
    5051      * Nested-guest NMI-window exiting.
    5052      * The NMI-window exit must happen regardless of whether an NMI is pending
    5053      * provided virtual-NMI blocking is not in effect.
    5054      *
    5055      * See Intel spec. 25.2 "Other Causes Of VM Exits".
     5048     * NMIs.
     5049     * NMIs take priority over interrupts.
    50565050     */
    5057     if (    VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_NMI_WINDOW)
    5058         && !CPUMIsGuestVmxVirtNmiBlocking(pCtx))
    5059     {
    5060         Assert(CPUMIsGuestVmxProcCtlsSet(&pVCpu->cpum.GstCtx, VMX_PROC_CTLS_NMI_WINDOW_EXIT));
    5061         return IEMExecVmxVmexit(pVCpu, VMX_EXIT_NMI_WINDOW, 0 /* u64ExitQual */);
    5062     }
    5063 
    5064     /*
    5065      * For a nested-guest, the FF always indicates the outer guest's ability to
    5066      * receive an NMI while the guest-interruptibility state bit depends on whether
    5067      * the nested-hypervisor is using virtual-NMIs.
    5068      *
    5069      * It is very important that we also clear the force-flag if we are causing
    5070      * an NMI VM-exit as it is the responsibility of the nested-hypervisor to deal
    5071      * with re-injecting or discarding the NMI. This fixes the bug that showed up
    5072      * with SMP Windows Server 2008 R2 with Hyper-V enabled, see @bugref{10318#c19}.
    5073      */
    5074     if (VMCPU_FF_TEST_AND_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_NMI))
    5075     {
    5076         if (CPUMIsGuestVmxPinCtlsSet(pCtx, VMX_PIN_CTLS_NMI_EXIT))
    5077             return IEMExecVmxVmexitXcptNmi(pVCpu);
    5078         vmxHCSetPendingXcptNmi(pVCpu);
    5079         return VINF_SUCCESS;
     5051    if (!CPUMAreInterruptsInhibitedByNmi(&pVCpu->cpum.GstCtx))
     5052    {
     5053        /*
     5054         * Nested-guest NMI-window exiting.
     5055         * The NMI-window exit must happen regardless of whether an NMI is pending
     5056         * provided virtual-NMI blocking is not in effect.
     5057         *
     5058         * See Intel spec. 25.2 "Other Causes Of VM Exits".
     5059         */
     5060        if (    VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_NMI_WINDOW)
     5061            && !CPUMIsGuestVmxVirtNmiBlocking(pCtx))
     5062        {
     5063            Assert(CPUMIsGuestVmxProcCtlsSet(&pVCpu->cpum.GstCtx, VMX_PROC_CTLS_NMI_WINDOW_EXIT));
     5064            return IEMExecVmxVmexit(pVCpu, VMX_EXIT_NMI_WINDOW, 0 /* u64ExitQual */);
     5065        }
     5066
     5067        /*
     5068         * For a nested-guest, the FF always indicates the outer guest's ability to
     5069         * receive an NMI while the guest-interruptibility state bit depends on whether
     5070         * the nested-hypervisor is using virtual-NMIs.
     5071         *
     5072         * It is very important that we also clear the force-flag if we are causing
     5073         * an NMI VM-exit as it is the responsibility of the nested-hypervisor to deal
     5074         * with re-injecting or discarding the NMI. This fixes the bug that showed up
     5075         * with SMP Windows Server 2008 R2 with Hyper-V enabled, see @bugref{10318#c19}.
     5076         */
     5077        if (VMCPU_FF_TEST_AND_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_NMI))
     5078        {
     5079            if (CPUMIsGuestVmxPinCtlsSet(pCtx, VMX_PIN_CTLS_NMI_EXIT))
     5080                return IEMExecVmxVmexitXcptNmi(pVCpu);
     5081            vmxHCSetPendingXcptNmi(pVCpu);
     5082            return VINF_SUCCESS;
     5083        }
    50805084    }
    50815085
     
    51055109     *
    51065110     * See Intel spec. 25.4.1 "Event Blocking".
     5111     *
     5112     * NMIs block external interrupts as they are dispatched through the interrupt gate (vector 2)
     5113     * which automatically clears EFLAGS.IF. Also it's possible an NMI handler could enable interrupts
     5114     * and thus we should not check for NMI inhibition here.
     5115     *
     5116     * See Intel spec. 6.8.1 "Masking Maskable Hardware Interrupts".
    51075117     */
    51085118    if (    VMCPU_FF_IS_ANY_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC)
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