VirtualBox

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


Ignore:
Timestamp:
Jun 3, 2019 8:46:09 AM (6 years ago)
Author:
vboxsync
Message:

VMM/EM: Nested VMX: bugref:9180 Nested SVM: bugref:7243 NMIs are subject to GIF. Add NMI exiting for VMX and SVM while injecting NMIs through EM.

File:
1 edited

Legend:

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

    r78918 r78922  
    22022202            && !TRPMHasTrap(pVCpu))                                  /* An event could already be scheduled for dispatching. */
    22032203        {
    2204             /*
    2205              * NMIs (take priority over external interrupts).
    2206              */
    2207             if (    VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_NMI)
    2208                 && !VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_BLOCK_NMIS))
    2209             {
    2210                 rc2 = TRPMAssertTrap(pVCpu, X86_XCPT_NMI, TRPM_TRAP);
    2211                 if (rc2 == VINF_SUCCESS)
    2212                 {
    2213                     VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_NMI);
    2214                     fWakeupPending = true;
    2215                     if (pVM->em.s.fIemExecutesAll)
    2216                         rc2 = VINF_EM_RESCHEDULE;
    2217                     else
    2218                     {
    2219                         rc2 = HMR3IsActive(pVCpu)    ? VINF_EM_RESCHEDULE_HM
    2220                             : VM_IS_NEM_ENABLED(pVM) ? VINF_EM_RESCHEDULE
    2221                             :                          VINF_EM_RESCHEDULE_REM;
    2222                     }
    2223                 }
    2224                 UPDATE_RC();
    2225             }
    2226             else
     2204            bool fGif = CPUMGetGuestGif(&pVCpu->cpum.GstCtx);
     2205#ifdef VBOX_WITH_RAW_MODE
     2206            fGif &= !PATMIsPatchGCAddr(pVM, pVCpu->cpum.GstCtx.eip);
     2207#endif
     2208            if (fGif)
    22272209            {
    22282210                /*
    2229                  * External Interrupts.
     2211                 * NMIs (take priority over external interrupts).
    22302212                 */
    2231                 bool fGif = CPUMGetGuestGif(&pVCpu->cpum.GstCtx);
    2232 #ifdef VBOX_WITH_RAW_MODE
    2233                 fGif &= !PATMIsPatchGCAddr(pVM, pVCpu->cpum.GstCtx.eip);
    2234 #endif
    2235                 if (fGif)
     2213                if (    VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_NMI)
     2214                    && !VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_BLOCK_NMIS))
     2215                {
     2216                    if (!CPUMIsGuestInNestedHwvirtMode(&pVCpu->cpum.GstCtx))
     2217                    {
     2218                        rc2 = TRPMAssertTrap(pVCpu, X86_XCPT_NMI, TRPM_TRAP);
     2219                        if (rc2 == VINF_SUCCESS)
     2220                        {
     2221                            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_NMI);
     2222                            fWakeupPending = true;
     2223                            if (pVM->em.s.fIemExecutesAll)
     2224                                rc2 = VINF_EM_RESCHEDULE;
     2225                            else
     2226                            {
     2227                                rc2 = HMR3IsActive(pVCpu)    ? VINF_EM_RESCHEDULE_HM
     2228                                    : VM_IS_NEM_ENABLED(pVM) ? VINF_EM_RESCHEDULE
     2229                                    :                          VINF_EM_RESCHEDULE_REM;
     2230                            }
     2231                        }
     2232                    }
     2233#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
     2234                    else if (   CPUMIsGuestInVmxNonRootMode(&pVCpu->cpum.GstCtx)
     2235                             && CPUMIsGuestVmxPinCtlsSet(pVCpu, &pVCpu->cpum.GstCtx, VMX_PIN_CTLS_NMI_EXIT))
     2236                    {
     2237                        rc2 = VBOXSTRICTRC_VAL(IEMExecVmxVmexitNmi(pVCpu));
     2238                        Assert(rc2 != VINF_VMX_INTERCEPT_NOT_ACTIVE);
     2239                    }
     2240#endif
     2241#ifdef VBOX_WITH_NESTED_HWVIRT_SVM
     2242                    else if (   CPUMIsGuestInSvmNestedHwVirtMode(&pVCpu->cpum.GstCtx)
     2243                             && CPUMIsGuestSvmCtrlInterceptSet(pVCpu, &pVCpu->cpum.GstCtx, SVM_CTRL_INTERCEPT_NMI))
     2244                    {
     2245                        rc2 = VBOXSTRICTRC_VAL(IEMExecSvmVmexit(pVCpu, SVM_EXIT_NMI, 0 /* uExitInfo1 */,  0 /* uExitInfo2 */));
     2246                        AssertMsg(   rc2 != VINF_PGM_CHANGE_MODE
     2247                                  && rc2 != VINF_SVM_VMEXIT
     2248                                  && rc2 != VINF_NO_CHANGE, ("%Rrc\n", rc2));
     2249                    }
     2250#endif
     2251                    UPDATE_RC();
     2252                }
     2253                else
    22362254                {
    22372255                    /*
     2256                     * External Interrupts.
     2257                     *
    22382258                     * With VMX, virtual interrupts takes priority over physical interrupts.
    22392259                     * With SVM, physical interrupts takes priority over virtual interrupts.
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