VirtualBox

Changeset 75830 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Nov 30, 2018 9:30:58 AM (6 years ago)
Author:
vboxsync
Message:

VMM: Adjust CPUMGetGuestInterruptibility to include virtual interrupts. Adjusted vmmR0DoHalt accordingly. Reworked interrupt injection in emR3ForcedActions().

Location:
trunk/src/VBox/VMM
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp

    r75765 r75830  
    26492649
    26502650/**
    2651  * Gets whether the guest or nested-guest's are ready to receive physical
    2652  * interrupts.
    2653  *
    2654  * This function assumes there is no global
    2655  *
    2656  * @returns @c true if interrupts can be injected into the guest (or nested-guest),
    2657  *          @c false otherwise.
     2651 * Returns whether the guest has physical interrupts enabled.
     2652 *
     2653 * @returns @c true if interrupts are enabled, @c false otherwise.
    26582654 * @param   pVCpu       The cross context virtual CPU structure.
    2659  */
    2660 DECLINLINE(bool) CPUMIsGuestPhysIntrsEnabled(PVMCPU pVCpu)
    2661 {
    2662     Assert(pVCpu->cpum.s.Guest.hwvirt.fGif);
    2663     if (   !CPUMIsGuestInVmxNonRootMode(&pVCpu->cpum.s.Guest)
    2664         && !CPUMIsGuestInSvmNestedHwVirtMode(&pVCpu->cpum.s.Guest))
    2665         return RT_BOOL(pVCpu->cpum.s.Guest.rflags.Bits.u1IF);
     2655 *
     2656 * @remarks Warning! This function does -not- take into account the global-interrupt
     2657 *          flag (GIF).
     2658 */
     2659VMM_INT_DECL(bool) CPUMIsGuestPhysIntrEnabled(PVMCPU pVCpu)
     2660{
     2661    if (!CPUMIsGuestInNestedHwvirtMode(&pVCpu->cpum.s.Guest))
     2662    {
     2663#ifdef VBOX_WITH_RAW_MODE_NOT_R0
     2664        uint32_t const fEFlags = !pVCpu->cpum.s.fRawEntered ? pVCpu->cpum.s.Guest.eflags.u : CPUMRawGetEFlags(pVCpu);
     2665#else
     2666        uint32_t const fEFlags = pVCpu->cpum.s.Guest.eflags.u;
     2667#endif
     2668        return RT_BOOL(fEFlags & X86_EFL_IF);
     2669    }
    26662670
    26672671    if (CPUMIsGuestInVmxNonRootMode(&pVCpu->cpum.s.Guest))
    2668         return CPUMCanVmxNstGstTakePhysIntr(pVCpu, &pVCpu->cpum.s.Guest);
    2669 
    2670     return CPUMCanSvmNstGstTakePhysIntr(pVCpu, &pVCpu->cpum.s.Guest);
     2672        return CPUMIsGuestVmxPhysIntrEnabled(pVCpu, &pVCpu->cpum.s.Guest);
     2673
     2674    Assert(CPUMIsGuestInSvmNestedHwVirtMode(&pVCpu->cpum.s.Guest));
     2675    return CPUMIsGuestSvmPhysIntrEnabled(pVCpu, &pVCpu->cpum.s.Guest);
     2676}
     2677
     2678
     2679/**
     2680 * Returns whether the nested-guest has virtual interrupts enabled.
     2681 *
     2682 * @returns @c true if interrupts are enabled, @c false otherwise.
     2683 * @param   pVCpu       The cross context virtual CPU structure.
     2684 *
     2685 * @remarks Warning! This function does -not- take into account the global-interrupt
     2686 *          flag (GIF).
     2687 */
     2688VMM_INT_DECL(bool) CPUMIsGuestVirtIntrEnabled(PVMCPU pVCpu)
     2689{
     2690    Assert(CPUMIsGuestInNestedHwvirtMode(&pVCpu->cpum.s.Guest));
     2691
     2692    if (CPUMIsGuestInVmxNonRootMode(&pVCpu->cpum.s.Guest))
     2693        return CPUMIsGuestVmxVirtIntrEnabled(pVCpu, &pVCpu->cpum.s.Guest);
     2694
     2695    Assert(CPUMIsGuestInSvmNestedHwVirtMode(&pVCpu->cpum.s.Guest));
     2696    return CPUMIsGuestSvmVirtIntrEnabled(pVCpu, &pVCpu->cpum.s.Guest);
    26712697}
    26722698
     
    26812707{
    26822708#if 1
    2683     if (pVCpu->cpum.s.Guest.hwvirt.fGif)
     2709    /* Global-interrupt flag blocks pretty much everything we care about here. */
     2710    if (CPUMGetGuestGif(&pVCpu->cpum.s.Guest))
    26842711    {
    2685         /** @todo r=ramshankar: What about virtual-interrupt delivery to nested-guests? */
    2686         if (CPUMIsGuestPhysIntrsEnabled(pVCpu))
     2712        /*
     2713         * Physical interrupts are primarily blocked using EFLAGS. However, we cannot access
     2714         * it directly here. If and how EFLAGS are used depends on the context (nested-guest
     2715         * or raw-mode). Hence we use the function below which handles the details.
     2716         */
     2717        if (    CPUMIsGuestPhysIntrEnabled(pVCpu)
     2718            && !VMCPU_FF_IS_ANY_SET(pVCpu, VMCPU_FF_BLOCK_NMIS | VMCPU_FF_INHIBIT_INTERRUPTS))
    26872719        {
    2688             if (!VMCPU_FF_IS_ANY_SET(pVCpu, VMCPU_FF_BLOCK_NMIS | VMCPU_FF_INHIBIT_INTERRUPTS))
     2720            if (   !CPUMIsGuestInNestedHwvirtMode(&pVCpu->cpum.s.Guest)
     2721                ||  CPUMIsGuestVirtIntrEnabled(pVCpu))
    26892722                return CPUMINTERRUPTIBILITY_UNRESTRAINED;
    26902723
    2691             /** @todo does blocking NMIs mean interrupts are also inhibited? */
    2692             if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS))
    2693             {
    2694                 if (!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_BLOCK_NMIS))
    2695                     return CPUMINTERRUPTIBILITY_INT_INHIBITED;
    2696                 return CPUMINTERRUPTIBILITY_NMI_INHIBIT;
    2697             }
    2698             AssertFailed();
     2724            /* Physical interrupts are enabled, but nested-guest virtual interrupts are disabled. */
     2725            return CPUMINTERRUPTIBILITY_VIRT_INT_DISABLED;
     2726        }
     2727
     2728        /*
     2729         * Blocking the delivery of NMIs during an interrupt shadow is CPU implementation
     2730         * specific. Therefore, in practice, we can't deliver an NMI in an interrupt shadow.
     2731         * However, there is some uncertainity regarding the converse, i.e. whether
     2732         * NMI-blocking until IRET blocks delivery of physical interrupts.
     2733         *
     2734         * See Intel spec. 25.4.1 "Event Blocking".
     2735         */
     2736        if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_BLOCK_NMIS))
    26992737            return CPUMINTERRUPTIBILITY_NMI_INHIBIT;
    2700         }
    2701         else
    2702         {
    2703             if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_BLOCK_NMIS))
    2704                 return CPUMINTERRUPTIBILITY_NMI_INHIBIT;
    2705             return CPUMINTERRUPTIBILITY_INT_DISABLED;
    2706         }
     2738
     2739        if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS))
     2740            return CPUMINTERRUPTIBILITY_INT_INHIBITED;
     2741
     2742        return CPUMINTERRUPTIBILITY_INT_DISABLED;
    27072743    }
    27082744    return CPUMINTERRUPTIBILITY_GLOBAL_INHIBIT;
     
    27512787 * @param   pCtx    The guest-CPU context.
    27522788 */
    2753 VMM_INT_DECL(bool) CPUMCanVmxNstGstTakePhysIntr(PVMCPU pVCpu, PCCPUMCTX pCtx)
     2789VMM_INT_DECL(bool) CPUMIsGuestVmxPhysIntrEnabled(PVMCPU pVCpu, PCCPUMCTX pCtx)
    27542790{
    27552791#ifdef IN_RC
     
    27592795    RT_NOREF(pVCpu);
    27602796    Assert(CPUMIsGuestInVmxNonRootMode(pCtx));
    2761     Assert(pCtx->hwvirt.fGif);  /* Always true on Intel. */
    27622797
    27632798    return RT_BOOL(pCtx->eflags.u & X86_EFL_IF);
     
    27652800}
    27662801
     2802
    27672803/**
    27682804 * Checks whether the VMX nested-guest is in a state to receive virtual interrupts
    2769  * (those injected with the "virtual-interrupt delivery" feature).
     2805 * (those injected with the "virtual interrupt delivery" feature).
    27702806 *
    27712807 * @returns VBox status code.
     
    27752811 * @param   pCtx    The guest-CPU context.
    27762812 */
    2777 VMM_INT_DECL(bool) CPUMCanVmxNstGstTakeVirtIntr(PVMCPU pVCpu, PCCPUMCTX pCtx)
     2813VMM_INT_DECL(bool) CPUMIsGuestVmxVirtIntrEnabled(PVMCPU pVCpu, PCCPUMCTX pCtx)
    27782814{
    27792815#ifdef IN_RC
     
    27832819    RT_NOREF2(pVCpu, pCtx);
    27842820    Assert(CPUMIsGuestInVmxNonRootMode(pCtx));
    2785     Assert(pCtx->hwvirt.fGif);  /* Always true on Intel. */
    27862821
    27872822    if (   (pCtx->eflags.u & X86_EFL_IF)
     
    27942829
    27952830/**
    2796  * Checks whether the SVM nested-guest is in a state to receive physical (APIC)
    2797  * interrupts.
    2798  *
    2799  * @returns VBox status code.
    2800  * @retval  true if it's ready, false otherwise.
    2801  *
     2831 * Checks whether the SVM nested-guest has physical interrupts enabled.
     2832 *
     2833 * @returns true if interrupts are enabled, false otherwise.
    28022834 * @param   pVCpu   The cross context virtual CPU structure of the calling EMT.
    28032835 * @param   pCtx    The guest-CPU context.
    2804  */
    2805 VMM_INT_DECL(bool) CPUMCanSvmNstGstTakePhysIntr(PVMCPU pVCpu, PCCPUMCTX pCtx)
     2836 *
     2837 * @remarks This does -not- take into account the global-interrupt flag.
     2838 */
     2839VMM_INT_DECL(bool) CPUMIsGuestSvmPhysIntrEnabled(PVMCPU pVCpu, PCCPUMCTX pCtx)
    28062840{
    28072841    /** @todo Optimization: Avoid this function call and use a pointer to the
     
    28122846#else
    28132847    Assert(CPUMIsGuestInSvmNestedHwVirtMode(pCtx));
    2814     Assert(pCtx->hwvirt.fGif);
    28152848
    28162849    X86EFLAGS fEFlags;
     
    28352868 * @param   pCtx    The guest-CPU context.
    28362869 */
    2837 VMM_INT_DECL(bool) CPUMCanSvmNstGstTakeVirtIntr(PVMCPU pVCpu, PCCPUMCTX pCtx)
     2870VMM_INT_DECL(bool) CPUMIsGuestSvmVirtIntrEnabled(PVMCPU pVCpu, PCCPUMCTX pCtx)
    28382871{
    28392872#ifdef IN_RC
     
    28422875#else
    28432876    Assert(CPUMIsGuestInSvmNestedHwVirtMode(pCtx));
    2844     Assert(pCtx->hwvirt.fGif);
    28452877
    28462878    PCSVMVMCBCTRL pVmcbCtrl    = &pCtx->hwvirt.svm.CTX_SUFF(pVmcb)->ctrl;
     
    28632895
    28642896/**
    2865  * Gets the pending SVM nested-guest interrupt.
     2897 * Gets the pending SVM nested-guest interruptvector.
    28662898 *
    28672899 * @returns The nested-guest interrupt to inject.
    28682900 * @param   pCtx            The guest-CPU context.
    28692901 */
    2870 VMM_INT_DECL(uint8_t) CPUMGetSvmNstGstInterrupt(PCCPUMCTX pCtx)
     2902VMM_INT_DECL(uint8_t) CPUMGetGuestSvmVirtIntrVector(PCCPUMCTX pCtx)
    28712903{
    28722904#ifdef IN_RC
  • trunk/src/VBox/VMM/VMMAll/IEMAll.cpp

    r75683 r75830  
    1429214292    /** @todo Can we centralize this under CPUMCanInjectInterrupt()? */
    1429314293#if defined(VBOX_WITH_NESTED_HWVIRT_SVM)
    14294     bool fIntrEnabled = pVCpu->cpum.GstCtx.hwvirt.fGif;
     14294    bool fIntrEnabled = CPUMGetGuestGif(&pVCpu->cpum.GstCtx);
    1429514295    if (fIntrEnabled)
    1429614296    {
    1429714297        if (CPUMIsGuestInSvmNestedHwVirtMode(IEM_GET_CTX(pVCpu)))
    14298             fIntrEnabled = CPUMCanSvmNstGstTakePhysIntr(pVCpu, IEM_GET_CTX(pVCpu));
     14298            fIntrEnabled = CPUMIsGuestSvmPhysIntrEnabled(pVCpu, IEM_GET_CTX(pVCpu));
    1429914299        else
    1430014300            fIntrEnabled = pVCpu->cpum.GstCtx.eflags.Bits.u1IF;
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImplSvmInstr.cpp.h

    r75759 r75830  
    139139
    140140        /*
    141          * Disable the global interrupt flag to prevent interrupts during the 'atomic' world switch.
    142          */
    143         pVCpu->cpum.GstCtx.hwvirt.fGif = false;
     141         * Disable the global-interrupt flag to prevent interrupts during the 'atomic' world switch.
     142         */
     143        CPUMSetGuestGif(&pVCpu->cpum.GstCtx, false);
    144144
    145145        /*
     
    757757
    758758        /*
    759          * Clear global interrupt flags to allow interrupts in the guest.
    760          */
    761         pVCpu->cpum.GstCtx.hwvirt.fGif = true;
     759         * Set the global-interrupt flag to allow interrupts in the guest.
     760         */
     761        CPUMSetGuestGif(&pVCpu->cpum.GstCtx, true);
    762762
    763763        /*
     
    12421242    }
    12431243
    1244     pVCpu->cpum.GstCtx.hwvirt.fGif = false;
     1244    CPUMSetGuestGif(&pVCpu->cpum.GstCtx, false);
    12451245    iemRegAddToRipAndClearRF(pVCpu, cbInstr);
    12461246
     
    12711271    }
    12721272
    1273     pVCpu->cpum.GstCtx.hwvirt.fGif = true;
     1273    CPUMSetGuestGif(&pVCpu->cpum.GstCtx, true);
    12741274    iemRegAddToRipAndClearRF(pVCpu, cbInstr);
    12751275
  • trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp

    r75829 r75830  
    24572457        Assert(pVCpu->CTX_SUFF(pVM)->hm.s.svm.u32Features & X86_CPUID_SVM_FEATURE_EDX_VGIF);    /* Hardware supports it. */
    24582458        Assert(HMSvmIsVGifActive(pVCpu->CTX_SUFF(pVM)));                                        /* VM has configured it. */
    2459         pVmcb->ctrl.IntCtrl.n.u1VGif = pCtx->hwvirt.fGif;
     2459        pVmcb->ctrl.IntCtrl.n.u1VGif = CPUMGetGuestGif(pCtx);
    24602460    }
    24612461#endif
     
    28102810                Assert(!CPUMIsGuestInSvmNestedHwVirtMode(pCtx));    /* We don't yet support passing VGIF feature to the guest. */
    28112811                Assert(HMSvmIsVGifActive(pVCpu->CTX_SUFF(pVM)));    /* VM has configured it. */
    2812                 pCtx->hwvirt.fGif = pVmcbCtrl->IntCtrl.n.u1VGif;
     2812                CPUMSetGuestGif(pCtx, pVmcbCtrl->IntCtrl.n.u1VGif);
    28132813            }
    28142814        }
     
    37433743    Assert(pVmcb);
    37443744
    3745     bool const fGif        = pCtx->hwvirt.fGif;
     3745    bool const fGif        = CPUMGetGuestGif(pCtx);
    37463746    bool const fIntShadow  = hmR0SvmIsIntrShadowActive(pVCpu);
    37473747    bool const fBlockNmi   = VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_BLOCK_NMIS);
     
    38033803        if (    fGif
    38043804            && !fIntShadow
    3805             &&  CPUMCanSvmNstGstTakePhysIntr(pVCpu, pCtx))
     3805            &&  CPUMIsGuestSvmPhysIntrEnabled(pVCpu, pCtx))
    38063806        {
    38073807            if (CPUMIsGuestSvmCtrlInterceptSet(pVCpu, pCtx, SVM_CTRL_INTERCEPT_INTR))
     
    38633863    Assert(pVmcb);
    38643864
    3865 #ifdef VBOX_WITH_NESTED_HWVIRT_SVM
    3866     bool const fGif       = pCtx->hwvirt.fGif;
    3867 #else
    3868     bool const fGif       = true;
    3869 #endif
     3865    bool const fGif       = CPUMGetGuestGif(pCtx);
    38703866    bool const fIntShadow = hmR0SvmIsIntrShadowActive(pVCpu);
    38713867    bool const fBlockInt  = !(pCtx->eflags.u32 & X86_EFL_IF);
     
    39743970         */
    39753971        if (CPUMIsGuestInSvmNestedHwVirtMode(pCtx))
    3976             fAllowInt = CPUMCanSvmNstGstTakePhysIntr(pVCpu, pCtx) || CPUMCanSvmNstGstTakeVirtIntr(pVCpu, pCtx);
     3972            fAllowInt = CPUMIsGuestSvmPhysIntrEnabled(pVCpu, pCtx) || CPUMIsGuestSvmVirtIntrEnabled(pVCpu, pCtx);
    39773973        else
    39783974            fAllowInt = RT_BOOL(pCtx->eflags.u32 & X86_EFL_IF);
  • trunk/src/VBox/VMM/VMMR0/VMMR0.cpp

    r75649 r75830  
    618618{
    619619    Assert(!TRPMHasTrap(pVCpu));
     620    Assert(   enmInterruptibility > CPUMINTERRUPTIBILITY_INVALID
     621           && enmInterruptibility < CPUMINTERRUPTIBILITY_END);
    620622
    621623    /*
     
    625627        && !VMCPU_FF_IS_ANY_SET(pVCpu, VMCPU_FF_INTERRUPT_SMI  | VMCPU_FF_INTERRUPT_NMI))
    626628    {
    627         if (enmInterruptibility <= CPUMINTERRUPTIBILITY_INT_INHIBITED)
     629        if (enmInterruptibility <= CPUMINTERRUPTIBILITY_UNRESTRAINED)
    628630        {
    629631            uint8_t u8Interrupt = 0;
     
    659661        }
    660662    }
     663    /*
     664     * Nested-guest virtual interrupt.
     665     */
     666    else if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_NESTED_GUEST))
     667    {
     668        if (enmInterruptibility < CPUMINTERRUPTIBILITY_VIRT_INT_DISABLED)
     669        {
     670            /** @todo NSTVMX: NSTSVM: Remember, we might have to check and perform VM-exits
     671             *        here before injecting the virtual interrupt. See emR3ForcedActions
     672             *        for details. */
     673            return VINF_EM_HALT;
     674        }
     675    }
    661676
    662677    if (VMCPU_FF_TEST_AND_CLEAR(pVCpu, VMCPU_FF_UNHALT))
     
    730745                           | VMCPU_FF_REQUEST                 | VMCPU_FF_DBGF                 | VMCPU_FF_HM_UPDATE_CR3
    731746                           | VMCPU_FF_HM_UPDATE_PAE_PDPES     | VMCPU_FF_PGM_SYNC_CR3         | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL
    732                            | VMCPU_FF_TO_R3                   | VMCPU_FF_IOM                  | VMCPU_FF_INTERRUPT_NESTED_GUEST /*?*/
    733                            | VMCPU_FF_VMX_PREEMPT_TIMER /*?*/ | VMCPU_FF_VMX_APIC_WRITE /*?*/ | VMCPU_FF_VMX_MTF /*?*/
     747                           | VMCPU_FF_TO_R3                   | VMCPU_FF_IOM
    734748#ifdef VBOX_WITH_RAW_MODE
    735749                           | VMCPU_FF_TRPM_SYNC_IDT           | VMCPU_FF_SELM_SYNC_TSS        | VMCPU_FF_SELM_SYNC_GDT
     
    746760    if (   pVCpu->vmm.s.fMayHaltInRing0
    747761        && !TRPMHasTrap(pVCpu)
    748         && (   enmInterruptibility <= CPUMINTERRUPTIBILITY_INT_INHIBITED
     762        && (   enmInterruptibility == CPUMINTERRUPTIBILITY_UNRESTRAINED
    749763            || uMWait > 1))
    750764    {
     
    758772                APICUpdatePendingInterrupts(pVCpu);
    759773
    760             if (VMCPU_FF_IS_ANY_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC
    761                                          | VMCPU_FF_INTERRUPT_NMI  | VMCPU_FF_INTERRUPT_SMI | VMCPU_FF_UNHALT))
     774            /*
     775             * Flags that wake up from the halted state.
     776             */
     777            uint64_t const fIntMask = VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_INTERRUPT_NESTED_GUEST
     778                                    | VMCPU_FF_INTERRUPT_NMI  | VMCPU_FF_INTERRUPT_SMI | VMCPU_FF_UNHALT;
     779
     780            if (VMCPU_FF_IS_ANY_SET(pVCpu, fIntMask))
    762781                return vmmR0DoHaltInterrupt(pVCpu, uMWait, enmInterruptibility);
    763782            ASMNopPause();
     
    775794                    APICUpdatePendingInterrupts(pVCpu);
    776795
    777                 if (VMCPU_FF_IS_ANY_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC
    778                                              | VMCPU_FF_INTERRUPT_NMI  | VMCPU_FF_INTERRUPT_SMI | VMCPU_FF_UNHALT))
     796                if (VMCPU_FF_IS_ANY_SET(pVCpu, fIntMask))
    779797                    return vmmR0DoHaltInterrupt(pVCpu, uMWait, enmInterruptibility);
    780798
     
    813831                            }
    814832                            ASMNopPause();
    815                             if (VMCPU_FF_IS_ANY_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC
    816                                                     | VMCPU_FF_INTERRUPT_NMI  | VMCPU_FF_INTERRUPT_SMI | VMCPU_FF_UNHALT))
     833                            if (VMCPU_FF_IS_ANY_SET(pVCpu, fIntMask))
    817834                            {
    818835                                STAM_REL_COUNTER_INC(&pVCpu->vmm.s.StatR0HaltExecFromSpin);
     
    853870                            if (VMCPU_FF_TEST_AND_CLEAR(pVCpu, VMCPU_FF_UPDATE_APIC))
    854871                                APICUpdatePendingInterrupts(pVCpu);
    855                             if (VMCPU_FF_IS_ANY_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC
    856                                                          | VMCPU_FF_INTERRUPT_NMI  | VMCPU_FF_INTERRUPT_SMI | VMCPU_FF_UNHALT))
     872                            if (VMCPU_FF_IS_ANY_SET(pVCpu, fIntMask))
    857873                            {
    858874                                STAM_REL_COUNTER_INC(&pVCpu->vmm.s.StatR0HaltExecFromBlock);
  • trunk/src/VBox/VMM/VMMR3/CPUM.cpp

    r75611 r75830  
    19551955     * Hardware virtualization state.
    19561956     */
    1957     pCtx->hwvirt.fGif = true;
     1957    CPUMSetGuestGif(pCtx, true);
    19581958    Assert(!pVM->cpum.ro.GuestFeatures.fVmx || !pVM->cpum.ro.GuestFeatures.fSvm);   /* Paranoia. */
    19591959    if (pVM->cpum.ro.GuestFeatures.fVmx)
  • trunk/src/VBox/VMM/VMMR3/EM.cpp

    r75759 r75830  
    17121712
    17131713/**
    1714  * Helper for emR3ForcedActions() for injecting interrupts into the
    1715  * guest.
     1714 * Helper for emR3ForcedActions() for VMX interrupt-window VM-exits.
    17161715 *
    17171716 * @returns VBox status code.
    1718  * @param   pVCpu               The cross context virtual CPU structure.
    1719  * @param   pfWakeupPending     Where to store whether a wake up from HLT state is
    1720  *                              pending.
    1721  * @param   pfInjected          Where to store whether an interrupt was injected.
    1722  */
    1723 DECLINLINE(int) emR3GstInjectIntr(PVMCPU pVCpu, bool *pfWakeupPending, bool *pfInjected)
    1724 {
    1725     CPUM_ASSERT_NOT_EXTRN(pVCpu, CPUMCTX_EXTRN_RFLAGS);
    1726     *pfWakeupPending = false;
    1727     *pfInjected      = false;
    1728 
    1729     if (   VMCPU_FF_IS_ANY_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC)
     1717 * @param   pVCpu       The cross context virtual CPU structure.
     1718 */
     1719static int emR3VmxNstGstIntrWindowExit(PVMCPU pVCpu)
     1720{
     1721#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
     1722    Assert(CPUMIsGuestInVmxNonRootMode(&pVCpu->cpum.GstCtx));
     1723    if (CPUMIsGuestVmxProcCtlsSet(pVCpu, &pVCpu->cpum.GstCtx, VMX_PROC_CTLS_INT_WINDOW_EXIT))
     1724    {
     1725        CPUM_IMPORT_EXTRN_RET(pVCpu, IEM_CPUMCTX_EXTRN_VMX_VMEXIT_MASK);
     1726        VBOXSTRICTRC rcStrict = IEMExecVmxVmexitIntWindow(pVCpu);
     1727        if (RT_SUCCESS(rcStrict))
     1728        {
     1729            Assert(rcStrict != VINF_PGM_CHANGE_MODE);
     1730            Assert(rcStrict != VINF_VMX_VMEXIT);
     1731            return VBOXSTRICTRC_VAL(rcStrict);
     1732        }
     1733        AssertMsgFailed(("Interrupt-window Vm-exit failed! rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
     1734        return VINF_EM_TRIPLE_FAULT;
     1735    }
     1736#else
     1737    RT_NOREF(pVCpu);
     1738#endif
     1739    return VINF_NO_CHANGE;
     1740}
     1741
     1742
     1743/**
     1744 * Helper for emR3ForcedActions() for SVM interrupt intercept.
     1745 *
     1746 * @returns VBox status code.
     1747 * @param   pVCpu       The cross context virtual CPU structure.
     1748 */
     1749static int emR3SvmNstGstIntrIntercept(PVMCPU pVCpu)
     1750{
    17301751#ifdef VBOX_WITH_NESTED_HWVIRT_SVM
    1731         && pVCpu->cpum.GstCtx.hwvirt.fGif
    1732 #endif
    1733 #ifdef VBOX_WITH_RAW_MODE
    1734         && !PATMIsPatchGCAddr(pVCpu->CTX_SUFF(pVM), pVCpu->cpum.GstCtx.eip)
    1735 #endif
    1736         && pVCpu->cpum.GstCtx.eflags.Bits.u1IF)
    1737     {
    1738         Assert(pVCpu->em.s.enmState != EMSTATE_WAIT_SIPI);
    1739         /* Note: it's important to make sure the return code from TRPMR3InjectEvent isn't ignored! */
    1740         /** @todo this really isn't nice, should properly handle this */
    1741         CPUM_IMPORT_EXTRN_RET(pVCpu, IEM_CPUMCTX_EXTRN_XCPT_MASK);
    1742         int rc2 = TRPMR3InjectEvent(pVCpu->CTX_SUFF(pVM), pVCpu, TRPM_HARDWARE_INT);
    1743         Assert(rc2 != VINF_VMX_VMEXIT && rc2 != VINF_SVM_VMEXIT);
    1744         Log(("EM: TRPMR3InjectEvent -> %d\n", rc2));
    1745         *pfWakeupPending = true;
    1746         *pfInjected      = true;
    1747         return rc2;
    1748     }
    1749 
     1752    Assert(CPUMIsGuestInSvmNestedHwVirtMode(&pVCpu->cpum.GstCtx));
     1753    if (CPUMIsGuestSvmCtrlInterceptSet(pVCpu, &pVCpu->cpum.GstCtx, SVM_CTRL_INTERCEPT_INTR))
     1754    {
     1755        CPUM_IMPORT_EXTRN_RET(pVCpu, IEM_CPUMCTX_EXTRN_SVM_VMEXIT_MASK);
     1756        VBOXSTRICTRC rcStrict = IEMExecSvmVmexit(pVCpu, SVM_EXIT_INTR, 0, 0);
     1757        if (RT_SUCCESS(rcStrict))
     1758        {
     1759            Assert(rcStrict != VINF_PGM_CHANGE_MODE);
     1760            Assert(rcStrict != VINF_SVM_VMEXIT);
     1761            return VBOXSTRICTRC_VAL(rcStrict);
     1762        }
     1763        AssertMsgFailed(("INTR #VMEXIT failed! rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
     1764        return VINF_EM_TRIPLE_FAULT;
     1765    }
     1766#else
     1767    NOREF(pVCpu);
     1768#endif
    17501769    return VINF_NO_CHANGE;
    17511770}
    17521771
    17531772
    1754 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX
    1755 /**
    1756  * Helper for emR3ForcedActions() for injecting interrupts into the
    1757  * VMX nested-guest.
     1773/**
     1774 * Helper for emR3ForcedActions() for SVM virtual interrupt intercept.
    17581775 *
    17591776 * @returns VBox status code.
    1760  * @param   pVCpu               The cross context virtual CPU structure.
    1761  * @param   pfWakeupPending     Where to store whether a wake up from HLT state is
    1762  *                              pending.
    1763  * @param   pfInjected          Where to store whether an interrrupt was injected.
    1764  */
    1765 static int emR3VmxNstGstInjectIntr(PVMCPU pVCpu, bool *pfWakeupPending, bool *pfInjected)
    1766 {
    1767     Assert(CPUMIsGuestInVmxNonRootMode(&pVCpu->cpum.GstCtx));
    1768     *pfWakeupPending = false;
    1769     *pfInjected      = false;
    1770 
    1771     /** @todo NSTVMX: Interrupt-window VM-exits currently only trigger when an
    1772      *        interrupt is pending but in reality it should happen as soon as the
    1773      *        guest is ready to receive interrupts even if no interrupt is pending.
    1774      *        Doing it before checking the VMCPU_FF_INTERRUPT_APIC or
    1775      *        VMCPU_FF_INTERRUPT_PIC here doesn't help as the caller already checks for
    1776      *        it earlier as part of the high-priority pre-mask anyway. */
    1777     if (   VMCPU_FF_IS_ANY_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC)
    1778         && CPUMCanVmxNstGstTakePhysIntr(pVCpu, &pVCpu->cpum.GstCtx))
    1779     {
    1780         Assert(pVCpu->em.s.enmState != EMSTATE_WAIT_SIPI);
    1781         Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS));
    1782         if (CPUMIsGuestVmxProcCtlsSet(pVCpu, &pVCpu->cpum.GstCtx, VMX_PROC_CTLS_INT_WINDOW_EXIT))
    1783         {
    1784             CPUM_IMPORT_EXTRN_RET(pVCpu, IEM_CPUMCTX_EXTRN_VMX_VMEXIT_MASK);
    1785             VBOXSTRICTRC rcStrict = IEMExecVmxVmexitIntWindow(pVCpu);
    1786             if (RT_SUCCESS(rcStrict))
    1787             {
    1788                 *pfWakeupPending = true;
    1789                 Assert(rcStrict != VINF_PGM_CHANGE_MODE);
    1790                 if (rcStrict == VINF_VMX_VMEXIT)
    1791                     return VINF_SUCCESS;
    1792                 return VBOXSTRICTRC_VAL(rcStrict);
    1793             }
    1794             AssertMsgFailed(("Interrupt-window Vm-exit failed! rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    1795             return VINF_EM_TRIPLE_FAULT;
    1796         }
    1797 
    1798         int rc = emR3GstInjectIntr(pVCpu, pfWakeupPending, pfInjected);
    1799         if (rc == VINF_VMX_VMEXIT)
    1800             rc = VINF_SUCCESS;
    1801         return rc;
    1802     }
    1803 
    1804     /** @todo NSTVMX: Virtual interrupt injection, virtual-interrupt delivery. */
    1805 
     1777 * @param   pVCpu       The cross context virtual CPU structure.
     1778 */
     1779static int emR3SvmNstGstVirtIntrIntercept(PVMCPU pVCpu)
     1780{
     1781#ifdef VBOX_WITH_NESTED_HWVIRT_SVM
     1782    if (CPUMIsGuestSvmCtrlInterceptSet(pVCpu, &pVCpu->cpum.GstCtx, SVM_CTRL_INTERCEPT_VINTR))
     1783    {
     1784        CPUM_IMPORT_EXTRN_RET(pVCpu, IEM_CPUMCTX_EXTRN_SVM_VMEXIT_MASK);
     1785        VBOXSTRICTRC rcStrict = IEMExecSvmVmexit(pVCpu, SVM_EXIT_VINTR, 0, 0);
     1786        if (RT_SUCCESS(rcStrict))
     1787        {
     1788            Assert(rcStrict != VINF_PGM_CHANGE_MODE);
     1789            Assert(rcStrict != VINF_SVM_VMEXIT);
     1790            return VBOXSTRICTRC_VAL(rcStrict);
     1791        }
     1792        AssertMsgFailed(("VINTR #VMEXIT failed! rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
     1793        return VINF_EM_TRIPLE_FAULT;
     1794    }
     1795#else
     1796    NOREF(pVCpu);
     1797#endif
    18061798    return VINF_NO_CHANGE;
    18071799}
    1808 #endif /* VBOX_WITH_NESTED_HWVIRT_VMX */
    1809 
    1810 #ifdef VBOX_WITH_NESTED_HWVIRT_SVM
    1811 /**
    1812  * Helper for emR3ForcedActions() for injecting interrupts into the
    1813  * SVM nested-guest.
    1814  *
    1815  * @returns VBox status code.
    1816  * @param   pVCpu               The cross context virtual CPU structure.
    1817  * @param   pfWakeupPending     Where to store whether a wake up from HLT state is
    1818  *                              pending.
    1819  * @param   pfInjected          Where to store whether an interrupt was injected.
    1820  */
    1821 static int emR3SvmNstGstInjectIntr(PVMCPU pVCpu, bool *pfWakeupPending, bool *pfInjected)
    1822 {
    1823     Assert(CPUMIsGuestInSvmNestedHwVirtMode(&pVCpu->cpum.GstCtx));
    1824     *pfWakeupPending = false;
    1825     *pfInjected      = false;
    1826 
    1827     PVM  pVM  = pVCpu->CTX_SUFF(pVM);
    1828     bool fGif = pVCpu->cpum.GstCtx.hwvirt.fGif;
    1829 #ifdef VBOX_WITH_RAW_MODE
    1830     fGif &= !PATMIsPatchGCAddr(pVM, pVCpu->cpum.GstCtx.eip);
    1831 #endif
    1832     if (fGif)
    1833     {
    1834         if (CPUMCanSvmNstGstTakePhysIntr(pVCpu, &pVCpu->cpum.GstCtx))
    1835         {
    1836             Assert(pVCpu->em.s.enmState != EMSTATE_WAIT_SIPI);
    1837             if (VMCPU_FF_IS_ANY_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC))
    1838             {
    1839                 if (CPUMIsGuestSvmCtrlInterceptSet(pVCpu, &pVCpu->cpum.GstCtx, SVM_CTRL_INTERCEPT_INTR))
    1840                 {
    1841                     CPUM_IMPORT_EXTRN_RET(pVCpu, IEM_CPUMCTX_EXTRN_SVM_VMEXIT_MASK);
    1842                     VBOXSTRICTRC rcStrict = IEMExecSvmVmexit(pVCpu, SVM_EXIT_INTR, 0, 0);
    1843                     if (RT_SUCCESS(rcStrict))
    1844                     {
    1845                         /** @todo r=ramshankar: Do we need to signal a wakeup here? If a nested-guest
    1846                          *        doesn't intercept HLT but intercepts INTR? */
    1847                         Assert(rcStrict != VINF_PGM_CHANGE_MODE);
    1848                         if (rcStrict == VINF_SVM_VMEXIT)
    1849                             rcStrict = VINF_SUCCESS;
    1850                         *pfWakeupPending = true;
    1851                         return VBOXSTRICTRC_VAL(rcStrict);
    1852                     }
    1853 
    1854                     AssertMsgFailed(("INTR #VMEXIT failed! rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    1855                     return VINF_EM_TRIPLE_FAULT;
    1856                 }
    1857 
    1858                 CPUM_IMPORT_EXTRN_RET(pVCpu, IEM_CPUMCTX_EXTRN_XCPT_MASK);
    1859                 /** @todo this really isn't nice, should properly handle this */
    1860                 int rc = TRPMR3InjectEvent(pVM, pVCpu, TRPM_HARDWARE_INT);
    1861                 Assert(rc != VINF_PGM_CHANGE_MODE);
    1862                 if (rc == VINF_SVM_VMEXIT)
    1863                     rc = VINF_SUCCESS;
    1864                 *pfWakeupPending = true;
    1865                 *pfInjected      = true;
    1866                 return rc;
    1867             }
    1868         }
    1869 
    1870         if (   VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_NESTED_GUEST)
    1871             && CPUMCanSvmNstGstTakeVirtIntr(pVCpu, &pVCpu->cpum.GstCtx))
    1872         {
    1873             if (CPUMIsGuestSvmCtrlInterceptSet(pVCpu, &pVCpu->cpum.GstCtx, SVM_CTRL_INTERCEPT_VINTR))
    1874             {
    1875                 CPUM_IMPORT_EXTRN_RET(pVCpu, IEM_CPUMCTX_EXTRN_SVM_VMEXIT_MASK);
    1876                 VBOXSTRICTRC rcStrict = IEMExecSvmVmexit(pVCpu, SVM_EXIT_VINTR, 0, 0);
    1877                 if (RT_SUCCESS(rcStrict))
    1878                 {
    1879                     /** @todo r=ramshankar: Do we need to signal a wakeup here? If a nested-guest
    1880                      *        doesn't intercept HLT but intercepts VINTR? */
    1881                     Assert(rcStrict != VINF_PGM_CHANGE_MODE);
    1882                     if (rcStrict == VINF_SVM_VMEXIT)
    1883                         rcStrict = VINF_SUCCESS;
    1884                     *pfWakeupPending = true;
    1885                     return VBOXSTRICTRC_VAL(rcStrict);
    1886                 }
    1887 
    1888                 AssertMsgFailed(("VINTR #VMEXIT failed! rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    1889                 return VINF_EM_TRIPLE_FAULT;
    1890             }
    1891 
    1892             VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_NESTED_GUEST);
    1893             uint8_t const uNstGstVector = CPUMGetSvmNstGstInterrupt(&pVCpu->cpum.GstCtx);
    1894             AssertMsg(uNstGstVector > 0 && uNstGstVector <= X86_XCPT_LAST, ("Invalid VINTR vector %#x\n", uNstGstVector));
    1895             TRPMAssertTrap(pVCpu, uNstGstVector, TRPM_HARDWARE_INT);
    1896             Log(("EM: Asserting nested-guest virt. hardware intr: %#x\n", uNstGstVector));
    1897 
    1898             *pfWakeupPending = true;
    1899             *pfInjected      = true;
    1900             return VINF_EM_RESCHEDULE;
    1901         }
    1902     }
    1903 
    1904     return VINF_SUCCESS;
    1905 }
    1906 #endif  /* VBOX_WITH_NESTED_HWVIRT_SVM */
     1800
    19071801
    19081802/**
     
    22272121        {
    22282122            Assert(!HMR3IsEventPending(pVCpu));
    2229 
    2230             bool fInjected;
    2231 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX
    2232             if (CPUMIsGuestInVmxNonRootMode(&pVCpu->cpum.GstCtx))
    2233                 rc2 = emR3VmxNstGstInjectIntr(pVCpu, &fWakeupPending, &fInjected);
    2234             else
    2235 #endif
    2236 #ifdef VBOX_WITH_NESTED_HWVIRT_SVM
    2237             if (CPUMIsGuestInSvmNestedHwVirtMode(&pVCpu->cpum.GstCtx))
    2238                 rc2 = emR3SvmNstGstInjectIntr(pVCpu, &fWakeupPending, &fInjected);
    2239             else
    2240 #endif
     2123            bool fGif = CPUMGetGuestGif(&pVCpu->cpum.GstCtx);
     2124#ifdef VBOX_WITH_RAW_MODE
     2125            fGif &= !PATMIsPatchGCAddr(pVM, pVCpu->cpum.GstCtx.eip);
     2126#endif
     2127            if (fGif)
    22412128            {
    2242                 rc2 = emR3GstInjectIntr(pVCpu, &fWakeupPending, &fInjected);
    2243             }
    2244             if (rc2 != VINF_NO_CHANGE)
    2245             {
    2246                 if (   pVM->em.s.fIemExecutesAll
    2247                     && (   rc2 == VINF_EM_RESCHEDULE_REM
    2248                         || rc2 == VINF_EM_RESCHEDULE_HM
    2249                         || rc2 == VINF_EM_RESCHEDULE_RAW))
     2129                /* In VMX, virtual interrupt takes priority over physical interrupts. */
     2130                if (   VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_NESTED_GUEST)
     2131                    && CPUMIsGuestInVmxNonRootMode(&pVCpu->cpum.GstCtx)
     2132                    && CPUMIsGuestVmxVirtIntrEnabled(pVCpu, &pVCpu->cpum.GstCtx))
    22502133                {
    2251                     rc2 = VINF_EM_RESCHEDULE;
     2134                    /** @todo NSTVMX: virtual interrupt delivery. */
     2135                    rc2 = VINF_NO_CHANGE;
    22522136                }
     2137                /* In SVM, physical interrupts take priority over virtual interrupts. */
     2138                else if (   VMCPU_FF_IS_ANY_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC)
     2139                         && CPUMIsGuestPhysIntrEnabled(pVCpu))
     2140                {
     2141                    bool fInjected = false;
     2142                    Assert(pVCpu->em.s.enmState != EMSTATE_WAIT_SIPI);
     2143
     2144                    if (CPUMIsGuestInVmxNonRootMode(&pVCpu->cpum.GstCtx))
     2145                        rc2 = emR3VmxNstGstIntrWindowExit(pVCpu);
     2146                    else if (CPUMIsGuestInSvmNestedHwVirtMode(&pVCpu->cpum.GstCtx))
     2147                        rc2 = emR3SvmNstGstIntrIntercept(pVCpu);
     2148                    else
     2149                        rc2 = VINF_NO_CHANGE;
     2150
     2151                    if (rc2 == VINF_NO_CHANGE)
     2152                    {
     2153                        CPUM_IMPORT_EXTRN_RET(pVCpu, IEM_CPUMCTX_EXTRN_XCPT_MASK);
     2154                        /** @todo this really isn't nice, should properly handle this */
     2155                        rc2 = TRPMR3InjectEvent(pVM, pVCpu, TRPM_HARDWARE_INT, &fInjected);
     2156                        fWakeupPending = true;
     2157                        if (   pVM->em.s.fIemExecutesAll
     2158                            && (   rc2 == VINF_EM_RESCHEDULE_REM
     2159                                || rc2 == VINF_EM_RESCHEDULE_HM
     2160                                || rc2 == VINF_EM_RESCHEDULE_RAW))
     2161                        {
     2162                            rc2 = VINF_EM_RESCHEDULE;
     2163                        }
     2164                    }
    22532165#ifdef VBOX_STRICT
    2254                 if (fInjected)
    2255                     rcIrq = rc2;
    2256 #endif
    2257                 UPDATE_RC();
     2166                    if (fInjected)
     2167                        rcIrq = rc2;
     2168#endif
     2169                    UPDATE_RC();
     2170                }
     2171                else if (   VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_NESTED_GUEST)
     2172                         && CPUMIsGuestInSvmNestedHwVirtMode(&pVCpu->cpum.GstCtx)
     2173                         && CPUMIsGuestSvmVirtIntrEnabled(pVCpu,  &pVCpu->cpum.GstCtx))
     2174                {
     2175                    rc2 = emR3SvmNstGstVirtIntrIntercept(pVCpu);
     2176                    if (rc2 == VINF_NO_CHANGE)
     2177                    {
     2178                        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_NESTED_GUEST);
     2179                        uint8_t const uNstGstVector = CPUMGetGuestSvmVirtIntrVector(&pVCpu->cpum.GstCtx);
     2180                        AssertMsg(uNstGstVector > 0 && uNstGstVector <= X86_XCPT_LAST, ("Invalid VINTR %#x\n", uNstGstVector));
     2181                        TRPMAssertTrap(pVCpu, uNstGstVector, TRPM_HARDWARE_INT);
     2182                        Log(("EM: Asserting nested-guest virt. hardware intr: %#x\n", uNstGstVector));
     2183                        rc2 = VINF_EM_RESCHEDULE;
     2184                        rcIrq = rc2;
     2185                    }
     2186                    UPDATE_RC();
     2187                }
    22582188            }
    22592189        }
  • trunk/src/VBox/VMM/VMMR3/TRPM.cpp

    r75767 r75830  
    14891489
    14901490/**
    1491  * Inject event (such as external irq or trap)
     1491 * Inject event (such as external irq or trap).
    14921492 *
    14931493 * @returns VBox status code.
     
    14951495 * @param   pVCpu       The cross context virtual CPU structure.
    14961496 * @param   enmEvent    Trpm event type
    1497  */
    1498 VMMR3DECL(int) TRPMR3InjectEvent(PVM pVM, PVMCPU pVCpu, TRPMEVENT enmEvent)
     1497 * @param   pfInjected  Where to store whether the event was injected or not.
     1498 */
     1499VMMR3DECL(int) TRPMR3InjectEvent(PVM pVM, PVMCPU pVCpu, TRPMEVENT enmEvent, bool *pfInjected)
    14991500{
    15001501#ifdef VBOX_WITH_RAW_MODE
     
    15031504#endif
    15041505    Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS));
     1506    Assert(pfInjected);
     1507    *pfInjected = false;
    15051508
    15061509    /* Currently only useful for external hardware interrupts. */
     
    16021605        }
    16031606#endif
     1607        *pfInjected = true;
    16041608        if (!VM_IS_NEM_ENABLED(pVM))
    16051609        {
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