VirtualBox

Changeset 78983 in vbox for trunk


Ignore:
Timestamp:
Jun 5, 2019 9:02:23 AM (6 years ago)
Author:
vboxsync
Message:

VMM/EM: Nested VMX: bugref:9180 Handle interrupt-window exiting not just when an interrupt is pending. Move NMI-window exiting into the section below which checks for interrupt shadows, TRPM events avoiding checking the same couple of conditions twice.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/EM.cpp

    r78978 r78983  
    17141714
    17151715/**
    1716  * Helper for emR3ForcedActions() for VMX interrupt-window VM-exit and VMX external
    1717  * interrupt VM-exit.
     1716 * Helper for emR3ForcedActions() for VMX external interrupt VM-exit.
    17181717 *
    17191718 * @returns VBox status code.
     
    17241723#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
    17251724    Assert(CPUMIsGuestInVmxNonRootMode(&pVCpu->cpum.GstCtx));
    1726 
    1727     /* Handle the "interrupt-window" VM-exit intercept. */
    1728     if (   CPUMIsGuestPhysIntrEnabled(pVCpu)
    1729         && CPUMIsGuestVmxProcCtlsSet(pVCpu, &pVCpu->cpum.GstCtx, VMX_PROC_CTLS_INT_WINDOW_EXIT))
    1730     {
    1731         VBOXSTRICTRC rcStrict = IEMExecVmxVmexit(pVCpu, VMX_EXIT_INT_WINDOW, 0 /* uExitQual */);
    1732         if (RT_SUCCESS(rcStrict))
    1733         {
    1734             AssertMsg(   rcStrict != VINF_PGM_CHANGE_MODE
    1735                       && rcStrict != VINF_VMX_VMEXIT
    1736                       && rcStrict != VINF_NO_CHANGE, ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    1737             return VBOXSTRICTRC_VAL(rcStrict);
    1738         }
    1739 
    1740         AssertMsgFailed(("Interrupt-window VM-exit failed! rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    1741         return VINF_EM_TRIPLE_FAULT;
    1742     }
    17431725
    17441726    /* Handle the "external interrupt" VM-exit intercept. */
     
    21722154                UPDATE_RC();
    21732155        }
    2174 
    2175         /*
    2176          * VMX NMI-window VM-exit.
    2177          * Takes priority over non-maskable interrupts (NMIs).
    2178          * Interrupt shadows block NMI-window VM-exits.
    2179          * Any event that is already in TRPM (e.g. injected during VM-entry) takes priority.
    2180          *
    2181          * See Intel spec. 25.2 "Other Causes Of VM Exits".
    2182          * See Intel spec. 26.7.6 "NMI-Window Exiting".
    2183          */
    2184         if (    VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_NMI_WINDOW)
    2185             && !VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)
    2186             && !CPUMIsGuestNmiBlocking(pVCpu)
    2187             && !TRPMHasTrap(pVCpu))
    2188         {
    2189             rc2 = VBOXSTRICTRC_VAL(IEMExecVmxVmexit(pVCpu, VMX_EXIT_NMI_WINDOW, 0 /* uExitQual */));
    2190             Assert(rc2 != VINF_VMX_INTERCEPT_NOT_ACTIVE);
    2191             UPDATE_RC();
    2192         }
    21932156#endif
    21942157
     
    22092172            {
    22102173                /*
     2174                 * VMX NMI-window VM-exit.
     2175                 * Takes priority over non-maskable interrupts (NMIs).
     2176                 * Interrupt shadows block NMI-window VM-exits.
     2177                 * Any event that is already in TRPM (e.g. injected during VM-entry) takes priority.
     2178                 *
     2179                 * See Intel spec. 25.2 "Other Causes Of VM Exits".
     2180                 * See Intel spec. 26.7.6 "NMI-Window Exiting".
     2181                 */
     2182                if (    VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_NMI_WINDOW)
     2183                    && !CPUMIsGuestVmxVirtNmiBlocking(pVCpu, &pVCpu->cpum.GstCtx))
     2184                {
     2185                    Assert(CPUMIsGuestVmxProcCtlsSet(pVCpu, &pVCpu->cpum.GstCtx, VMX_PROC_CTLS_NMI_WINDOW_EXIT));
     2186                    rc2 = VBOXSTRICTRC_VAL(IEMExecVmxVmexit(pVCpu, VMX_EXIT_NMI_WINDOW, 0 /* uExitQual */));
     2187                    AssertMsg(   rc2 != VINF_VMX_INTERCEPT_NOT_ACTIVE
     2188                              && rc2 != VINF_PGM_CHANGE_MODE
     2189                              && rc2 != VINF_VMX_VMEXIT
     2190                              && rc2 != VINF_NO_CHANGE, ("%Rrc\n", rc2));
     2191                    UPDATE_RC();
     2192                }
     2193                /*
    22112194                 * NMIs (take priority over external interrupts).
    22122195                 */
    2213                 if (    VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_NMI)
    2214                     && !VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_BLOCK_NMIS))
     2196                else if (    VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_NMI)
     2197                         && !VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_BLOCK_NMIS))
    22152198                {
    22162199                    if (!CPUMIsGuestInNestedHwvirtMode(&pVCpu->cpum.GstCtx))
     
    22532236#endif
    22542237                }
     2238#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
     2239                /*
     2240                 * VMX Interrupt-window VM-exits.
     2241                 * Takes priority over external interrupts.
     2242                 */
     2243                else if (   VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_INT_WINDOW)
     2244                         && CPUMIsGuestVmxVirtIntrEnabled(pVCpu, &pVCpu->cpum.GstCtx))
     2245                {
     2246                    Assert(CPUMIsGuestVmxProcCtlsSet(pVCpu, &pVCpu->cpum.GstCtx, VMX_PROC_CTLS_INT_WINDOW_EXIT));
     2247                    rc2 = VBOXSTRICTRC_VAL(IEMExecVmxVmexit(pVCpu, VMX_EXIT_INT_WINDOW, 0 /* uExitQual */));
     2248                    AssertMsg(   rc2 != VINF_VMX_INTERCEPT_NOT_ACTIVE
     2249                              && rc2 != VINF_PGM_CHANGE_MODE
     2250                              && rc2 != VINF_VMX_VMEXIT
     2251                              && rc2 != VINF_NO_CHANGE, ("%Rrc\n", rc2));
     2252                    UPDATE_RC();
     2253                }
     2254#endif
     2255#ifdef VBOX_WITH_NESTED_HWVIRT_SVM
     2256                /** @todo NSTSVM: Handle this for SVM here too later not when an interrupt is
     2257                 *        actually pending like we currently do. */
     2258#endif
     2259                /*
     2260                 * External interrupts.
     2261                 */
    22552262                else
    22562263                {
    22572264                    /*
    2258                      * External Interrupts.
    2259                      *
    2260                      * With VMX, virtual interrupts takes priority over physical interrupts.
    2261                      * With SVM, physical interrupts takes priority over virtual interrupts.
     2265                     * VMX: virtual interrupts takes priority over physical interrupts.
     2266                     * SVM: physical interrupts takes priority over virtual interrupts.
    22622267                     */
    22632268                    if (   VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_NESTED_GUEST)
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