VirtualBox

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


Ignore:
Timestamp:
Jan 22, 2018 9:22:35 AM (7 years ago)
Author:
vboxsync
Message:

VMM/EM: Nested Hw.virt: Fix SVM nested-guest virtual-interrupt delivery.

File:
1 edited

Legend:

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

    r70000 r70672  
    19591959                && !TRPMHasTrap(pVCpu)) /* an interrupt could already be scheduled for dispatching in the recompiler. */
    19601960            {
    1961                 bool     fIntrEnabled;
    19621961                PCPUMCTX pCtx = pVCpu->em.s.pCtx;
     1962                bool fGif     = pCtx->hwvirt.svm.fGif;
    19631963#ifdef VBOX_WITH_RAW_MODE
    19641964                /* We cannot just inspect EFLAGS when nested hw.virt is enabled (see e.g. CPUMCanSvmNstGstTakePhysIntr). */
    1965                 fIntrEnabled = !PATMIsPatchGCAddr(pVM, pCtx->eip);
    1966 #else
    1967                 fIntrEnabled = true;
    1968 #endif
    1969                 /** @todo Can we centralize this under CPUMCanInjectInterrupt()? */
     1965                fGif &= !PATMIsPatchGCAddr(pVM, pCtx->eip);
     1966#endif
     1967                if (fGif)
     1968                {
     1969                    bool fIntrEnabled;
    19701970#ifdef VBOX_WITH_NESTED_HWVIRT
    1971                 fIntrEnabled &= pCtx->hwvirt.svm.fGif;
    1972                 if (fIntrEnabled)
    1973                 {
    19741971                    if (CPUMIsGuestInSvmNestedHwVirtMode(pCtx))
    19751972                        fIntrEnabled = CPUMCanSvmNstGstTakePhysIntr(pVCpu, pCtx);
    19761973                    else
    19771974                        fIntrEnabled = pCtx->eflags.Bits.u1IF;
    1978                 }
    19791975#else
    1980                 fIntrEnabled &= pCtx->eflags.Bits.u1IF;
    1981 #endif
    1982                 if (fIntrEnabled)
    1983                 {
     1976                    fIntrEnabled = pCtx->eflags.Bits.u1IF;
     1977#endif
    19841978                    Assert(!HMR3IsEventPending(pVCpu));
    19851979                    Assert(pVCpu->em.s.enmState != EMSTATE_WAIT_SIPI);
    1986                     if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC))
     1980                    if (   VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC)
     1981                        && fIntrEnabled)
    19871982                    {
    19881983#ifdef VBOX_WITH_NESTED_HWVIRT
     
    20202015                    }
    20212016#ifdef VBOX_WITH_NESTED_HWVIRT
    2022                     else if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INTERRUPT_NESTED_GUEST))
     2017                    /*
     2018                     * Check nested-guest virtual interrupts.
     2019                     */
     2020                    else if (   VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INTERRUPT_NESTED_GUEST)
     2021                             && CPUMCanSvmNstGstTakeVirtIntr(pCtx))
    20232022                    {
    2024                         /*
    2025                          * Check nested-guest virtual interrupts.
    2026                          */
    2027                         if (CPUMCanSvmNstGstTakeVirtIntr(pCtx))
     2023                        if (CPUMIsGuestSvmCtrlInterceptSet(pVCpu, pCtx, SVM_CTRL_INTERCEPT_VINTR))
    20282024                        {
    2029                             if (CPUMIsGuestSvmCtrlInterceptSet(pVCpu, pCtx, SVM_CTRL_INTERCEPT_VINTR))
    2030                             {
    2031                                 VBOXSTRICTRC rcStrict = IEMExecSvmVmexit(pVCpu, SVM_EXIT_VINTR, 0, 0);
    2032                                 if (RT_SUCCESS(rcStrict))
    2033                                     rc2 = VINF_EM_RESCHEDULE;
    2034                                 else
    2035                                 {
    2036                                     AssertMsgFailed(("VINTR #VMEXIT failed! rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    2037                                     Log(("EM: SVM Nested-guest VINTR #VMEXIT failed! rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    2038                                     /** @todo should we call iemInitiateCpuShutdown? Should this
    2039                                      *        result in trapping triple-fault intercepts? */
    2040                                     rc2 = VINF_EM_TRIPLE_FAULT;
    2041                                 }
    2042                             }
     2025                            VBOXSTRICTRC rcStrict = IEMExecSvmVmexit(pVCpu, SVM_EXIT_VINTR, 0, 0);
     2026                            if (RT_SUCCESS(rcStrict))
     2027                                rc2 = VINF_EM_RESCHEDULE;
    20432028                            else
    20442029                            {
    2045                                 /*
    2046                                  * Prepare the nested-guest interrupt for injection.
    2047                                  */
    2048                                 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_NESTED_GUEST);
    2049                                 uint8_t uNstGstVector = CPUMGetSvmNstGstInterrupt(pCtx);
    2050                                 TRPMAssertTrap(pVCpu, uNstGstVector, TRPM_HARDWARE_INT);
    2051                                 Log(("EM: Asserting nested-guest virt. hardware intr: %#x\n", uNstGstVector));
    2052                                 /** @todo reschedule to HM/REM later, when the HMR0 nested-guest execution is
    2053                                  *  done. For now just reschedule to IEM. */
    2054                                 rc2 = VINF_EM_RESCHEDULE;
     2030                                AssertMsgFailed(("VINTR #VMEXIT failed! rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
     2031                                Log(("EM: SVM Nested-guest VINTR #VMEXIT failed! rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
     2032                                /** @todo should we call iemInitiateCpuShutdown? Should this
     2033                                 *        result in trapping triple-fault intercepts? */
     2034                                rc2 = VINF_EM_TRIPLE_FAULT;
    20552035                            }
    2056                             UPDATE_RC();
    2057                             /* Reschedule required: We must not miss the wakeup below! */
    2058                             fWakeupPending = true;
    20592036                        }
     2037                        else
     2038                        {
     2039                            /*
     2040                             * Prepare the nested-guest interrupt for injection.
     2041                             */
     2042                            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_NESTED_GUEST);
     2043                            uint8_t uNstGstVector = CPUMGetSvmNstGstInterrupt(pCtx);
     2044                            TRPMAssertTrap(pVCpu, uNstGstVector, TRPM_HARDWARE_INT);
     2045                            Log(("EM: Asserting nested-guest virt. hardware intr: %#x\n", uNstGstVector));
     2046                            /** @todo reschedule to HM/REM later, when the HMR0 nested-guest execution is
     2047                             *  done. For now just reschedule to IEM. */
     2048                            rc2 = VINF_EM_RESCHEDULE;
     2049                        }
     2050                        UPDATE_RC();
     2051                        /* Reschedule required: We must not miss the wakeup below! */
     2052                        fWakeupPending = true;
    20602053                    }
    20612054#endif  /* VBOX_WITH_NESTED_HWVIRT */
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