VirtualBox

Changeset 52140 in vbox


Ignore:
Timestamp:
Jul 23, 2014 5:08:54 AM (11 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
95172
Message:

VMM/HMVMXR0: Fix NMI redelivery when the original delivery caused an exception VM-exit.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp

    r52125 r52140  
    58365836            }
    58375837        }
    5838         else
     5838        else if (   uIntType == VMX_IDT_VECTORING_INFO_TYPE_HW_XCPT
     5839                 || uIntType == VMX_IDT_VECTORING_INFO_TYPE_EXT_INT
     5840                 || uIntType == VMX_IDT_VECTORING_INFO_TYPE_NMI)
    58395841        {
    58405842            /*
    58415843             * If event delivery caused an EPT violation/misconfig or APIC access VM-exit, then the VM-exit
    5842              * interruption-information will not be valid and we end up here. In such cases, it is sufficient to reflect the
    5843              * original exception to the guest after handling the VM-exit.
     5844             * interruption-information will not be valid as it's not an exception and we end up here. In such cases,
     5845             * it is sufficient to reflect the original exception to the guest after handling the VM-exit.
    58445846             */
    5845             if (   uIntType == VMX_IDT_VECTORING_INFO_TYPE_NMI
    5846                 && (pVCpu->hm.s.vmx.u32PinCtls & VMX_VMCS_CTRL_PIN_EXEC_VIRTUAL_NMI))
    5847             {
    5848                 /*
    5849                  * On CPUs that support Virtual NMIs, if this exception occurred while delivering the NMI, we need to clear
    5850                  * the block-by-NMI field in the guest interruptibility-state before re-delivering the NMI, otherwise the
    5851                  * subsequent VM-entry would fail.
    5852                  * See Intel spec. 30.7.1.2 "Resuming Guest Software after Handling an Exception". See @bugref{7445}.
    5853                  */
    5854                 Assert(VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_BLOCK_NMIS));
    5855                 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_BLOCK_NMIS);
    5856                 enmReflect = VMXREFLECTXCPT_XCPT;
    5857             }
    5858             else if (   uIntType == VMX_IDT_VECTORING_INFO_TYPE_HW_XCPT
    5859                      || uIntType == VMX_IDT_VECTORING_INFO_TYPE_EXT_INT
    5860                      || uIntType == VMX_IDT_VECTORING_INFO_TYPE_NMI)
    5861             {
    5862                 enmReflect = VMXREFLECTXCPT_XCPT;
    5863             }
     5847            enmReflect = VMXREFLECTXCPT_XCPT;
     5848        }
     5849
     5850        /*
     5851         * On CPUs that support Virtual NMIs, if this VM-exit (be it an exception or EPT violation/misconfig etc.) occurred
     5852         * while delivering the NMI, we need to clear the block-by-NMI field in the guest interruptibility-state before
     5853         * re-delivering the NMI after handling the VM-exit. Otherwise the subsequent VM-entry would fail.
     5854         *
     5855         * See Intel spec. 30.7.1.2 "Resuming Guest Software after Handling an Exception". See @bugref{7445}.
     5856         */
     5857        if (   uIntType == VMX_IDT_VECTORING_INFO_TYPE_NMI
     5858            && enmReflect == VMXREFLECTXCPT_XCPT
     5859            && (pVCpu->hm.s.vmx.u32PinCtls & VMX_VMCS_CTRL_PIN_EXEC_VIRTUAL_NMI)
     5860            && VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_BLOCK_NMIS))
     5861        {
     5862            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_BLOCK_NMIS);
    58645863        }
    58655864
     
    59195918        /*
    59205919         * Execution of IRET caused this fault when NMI blocking was in effect (i.e we're in the guest NMI handler).
    5921          * We need to reset the block-by-NMI field so that NMIs remain blocked until the IRET execution is completed.
     5920         * We need to set the block-by-NMI field so that NMIs remain blocked until the IRET execution is restarted.
    59225921         * See Intel spec. 30.7.1.2 "Resuming guest software after handling an exception".
    59235922         */
     
    79957994    /* Clear interrupt-window exiting control. */
    79967995    if (pVCpu->hm.s.vmx.u32ProcCtls & VMX_VMCS_CTRL_PROC_EXEC_INT_WINDOW_EXIT)
     7996    {
    79977997        hmR0VmxClearIntWindowExitVmcs(pVCpu);
     7998        Assert(!pVCpu->hm.s.Event.fPending);
     7999    }
     8000
     8001    /* Clear NMI-window exiting control. */
     8002    if (pVCpu->hm.s.vmx.u32ProcCtls & VMX_VMCS_CTRL_PROC_EXEC_NMI_WINDOW_EXIT)
     8003    {
     8004        hmR0VmxClearNmiWindowExitVmcs(pVCpu);
     8005        Assert(!pVCpu->hm.s.Event.fPending);
     8006    }
    79988007
    79998008    if (!pVCpu->hm.s.Event.fPending)
     
    99519960
    99529961    /*
    9953      * Clear block-by-STI if it's active. The force-flag couldn't have been set by block-by-Mov SS in
    9954      * hmR0VmxSaveGuestIntrState() when this VM-exit happened, as Intel CPUs are consistent with
    9955      * block-by-Mov SS and NMIs. See @bugref{7445}.
     9962     * If block-by-STI is set when we get this VM-exit, it means the CPU doesn't block NMIs following STI.
     9963     * It is therefore safe to unblock STI and deliver the NMI ourselves. See @bugref{7445}.
    99569964     */
    9957     if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS))
     9965    uint32_t uIntrState = 0;
     9966    int rc = VMXReadVmcs32(VMX_VMCS32_GUEST_INTERRUPTIBILITY_STATE, &uIntrState);
     9967    AssertRCReturn(rc, rc);
     9968
     9969    bool const fBlockSti = RT_BOOL(uIntrState & VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_STI);
     9970    if (   fBlockSti
     9971        && VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS))
     9972    {
    99589973        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS);
     9974    }
    99599975
    99609976    /* Indicate that we no longer need to VM-exit when the guest is ready to receive NMIs, it is now ready */
Note: See TracChangeset for help on using the changeset viewer.

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