VirtualBox

Changeset 70379 in vbox for trunk/src


Ignore:
Timestamp:
Dec 29, 2017 9:53:09 AM (7 years ago)
Author:
vboxsync
Message:

VMM/HMSVMR0: Nested Hw.virt: Fix a bug that caused an event to be injected twice.

File:
1 edited

Legend:

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

    r70359 r70379  
    30173017    NOREF(pVCpu); NOREF(pCtx);
    30183018
     3019    Assert(!pVmcb->ctrl.EventInject.n.u1Valid);
    30193020    pVmcb->ctrl.EventInject.u = pEvent->u;
    30203021    STAM_COUNTER_INC(&pVCpu->hm.s.paStatInjectedIrqsR0[pEvent->n.u8Vector & MASK_INJECT_IRQ_STAT]);
     
    34933494    Assert(!VMMRZCallRing3IsEnabled(pVCpu));
    34943495
    3495     bool const fIntShadow = hmR0SvmIsIntrShadowActive(pVCpu, pCtx);
    3496 
    3497     /*
    3498      * When executing the nested-guest, we avoid assertions on whether the
    3499      * event injection is valid purely based on EFLAGS, as V_INTR_MASKING
    3500      * affects the interpretation of interruptibility (see CPUMCanSvmNstGstTakePhysIntr).
    3501      */
    3502 #ifndef VBOX_WITH_NESTED_HWVIRT
    3503     bool const fBlockInt  = !(pCtx->eflags.u32 & X86_EFL_IF);
    3504 #endif
    3505 
    3506     if (pVCpu->hm.s.Event.fPending)                                /* First, inject any pending HM events. */
     3496    bool const fIsNestedGuest = CPUMIsGuestInSvmNestedHwVirtMode(pCtx);
     3497    bool const fIntShadow     = hmR0SvmIsIntrShadowActive(pVCpu, pCtx);
     3498    bool const fBlockInt      = !fIsNestedGuest ? !(pCtx->eflags.u32 & X86_EFL_IF) : CPUMCanSvmNstGstTakePhysIntr(pVCpu, pCtx);
     3499
     3500    if (pVCpu->hm.s.Event.fPending)
    35073501    {
    35083502        SVMEVENT Event;
     
    35103504        Assert(Event.n.u1Valid);
    35113505
    3512 #ifndef VBOX_WITH_NESTED_HWVIRT
     3506        /*
     3507         * Validate event injection pre-conditions.
     3508         */
    35133509        if (Event.n.u3Type == SVM_EVENT_EXTERNAL_IRQ)
    35143510        {
     
    35193515            Assert(!fIntShadow);
    35203516        NOREF(fBlockInt);
    3521 #else
    3522         Assert(!pVmcb->ctrl.EventInject.n.u1Valid);
    3523 #endif
    3524 
     3517
     3518        /*
     3519         * Inject it (update VMCB for injection by the hardware).
     3520         */
    35253521        Log4(("Injecting pending HM event\n"));
    35263522        hmR0SvmInjectEventVmcb(pVCpu, pVmcb, pCtx, &Event);
    35273523        pVCpu->hm.s.Event.fPending = false;
    35283524
    3529 #ifdef VBOX_WITH_STATISTICS
    35303525        if (Event.n.u3Type == SVM_EVENT_EXTERNAL_IRQ)
    35313526            STAM_COUNTER_INC(&pVCpu->hm.s.StatInjectInterrupt);
    35323527        else
    35333528            STAM_COUNTER_INC(&pVCpu->hm.s.StatInjectXcpt);
     3529    }
     3530    else
     3531    {
     3532#ifdef VBOX_WITH_NESTED_HWVIRT
     3533        /*
     3534         * If IEM emulated VMRUN and injected an event it would not clear the EVENTINJ::Valid bit
     3535         * as a physical CPU clears it as part of the #VMEXIT. However, now we are continuing
     3536         * nested-guest execution using hardware-assisted SVM, so we need to clear this field
     3537         * otherwise we will inject the event twice, see @bugref{7243#78}.
     3538         */
     3539        if (CPUMIsGuestInSvmNestedHwVirtMode(pCtx))
     3540            pVmcb->ctrl.EventInject.n.u1Valid = 0;
    35343541#endif
     3542        Assert(pVmcb->ctrl.EventInject.n.u1Valid == 0);
    35353543    }
    35363544
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