VirtualBox

Changeset 99656 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
May 8, 2023 8:50:13 AM (20 months ago)
Author:
vboxsync
Message:

VMM: Nested VMX: bugref:10318 NMI inhibition also blocks external interrupts. No scope of NMI-window exiting or delivering NMIs in such a case.

File:
1 edited

Legend:

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

    r99655 r99656  
    50325032
    50335033    /*
    5034      * Interrupt shadows can also block NMIs. If we are in an interrupt shadow there's
    5035      * nothing more to do here.
     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.
    50365037     *
    50375038     * See Intel spec. 24.4.2 "Guest Non-Register State".
    50385039     * See Intel spec. 25.4.1 "Event Blocking".
     5040     * See Intel spec. 6.7 "Nonmaskable Interrupt (NMI)".
    50395041     */
    5040     if (!CPUMIsInInterruptShadowWithUpdate(&pVCpu->cpum.GstCtx))
     5042    if (   CPUMIsInInterruptShadowWithUpdate(&pVCpu->cpum.GstCtx)
     5043        || CPUMAreInterruptsInhibitedByNmi(&pVCpu->cpum.GstCtx))
    50415044    { /* likely */ }
    50425045    else
     
    50465049
    50475050    /*
    5048      * NMIs.
    5049      * NMIs take priority over external interrupts.
     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.
    50505054     *
    5051      * NMI blocking is in effect after delivering an NMI until the execution of IRET.
    5052      * Only when there isn't any NMI blocking can an NMI-window VM-exit or delivery of an NMI happen.
     5055     * See Intel spec. 25.2 "Other Causes Of VM Exits".
    50535056     */
    5054     if (!CPUMAreInterruptsInhibitedByNmi(&pVCpu->cpum.GstCtx))
    5055     {
    5056         /*
    5057          * Nested-guest NMI-window exiting.
    5058          * The NMI-window exit must happen regardless of whether an NMI is pending
    5059          * provided virtual-NMI blocking is not in effect.
    5060          *
    5061          * See Intel spec. 25.2 "Other Causes Of VM Exits".
    5062          */
    5063         if (    VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_NMI_WINDOW)
    5064             && !CPUMIsGuestVmxVirtNmiBlocking(pCtx))
    5065         {
    5066             Assert(CPUMIsGuestVmxProcCtlsSet(&pVCpu->cpum.GstCtx, VMX_PROC_CTLS_NMI_WINDOW_EXIT));
    5067             return IEMExecVmxVmexit(pVCpu, VMX_EXIT_NMI_WINDOW, 0 /* u64ExitQual */);
    5068         }
    5069 
    5070         /*
    5071          * For a nested-guest, the FF always indicates the outer guest's ability to
    5072          * receive an NMI while the guest-interruptibility state bit depends on whether
    5073          * the nested-hypervisor is using virtual-NMIs.
    5074          *
    5075          * It is very important that we also clear the force-flag if we are causing
    5076          * an NMI VM-exit as it is the responsibility of the nested-hypervisor to deal
    5077          * with re-injecting or discarding the NMI. This fixes the bug that showed up
    5078          * with SMP Windows Server 2008 R2 with Hyper-V enabled, see @bugref{10318#c19}.
    5079          */
    5080         if (VMCPU_FF_TEST_AND_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_NMI))
    5081         {
    5082             if (CPUMIsGuestVmxPinCtlsSet(pCtx, VMX_PIN_CTLS_NMI_EXIT))
    5083                 return IEMExecVmxVmexitXcptNmi(pVCpu);
    5084             vmxHCSetPendingXcptNmi(pVCpu);
    5085             return VINF_SUCCESS;
    5086         }
     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;
    50875080    }
    50885081
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