VirtualBox

Changeset 97289 in vbox for trunk/src/VBox/VMM/VMMAll


Ignore:
Timestamp:
Oct 25, 2022 7:56:51 AM (2 years ago)
Author:
vboxsync
Message:

IEM: Clear interrupt shadow flags together with RF.

Location:
trunk/src/VBox/VMM/VMMAll
Files:
2 edited

Legend:

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

    r97221 r97289  
    99299929     * See if there is an interrupt pending in TRPM, inject it if we can.
    99309930     */
    9931     /** @todo Can we centralize this under CPUMCanInjectInterrupt()? */
    9932 #if defined(VBOX_WITH_NESTED_HWVIRT_SVM) || defined(VBOX_WITH_NESTED_HWVIRT_VMX)
    9933     bool fIntrEnabled = CPUMGetGuestGif(&pVCpu->cpum.GstCtx);
    9934     if (fIntrEnabled)
    9935     {
    9936         if (!CPUMIsGuestInNestedHwvirtMode(IEM_GET_CTX(pVCpu)))
    9937             fIntrEnabled = pVCpu->cpum.GstCtx.eflags.Bits.u1IF;
    9938         else if (CPUMIsGuestInVmxNonRootMode(IEM_GET_CTX(pVCpu)))
    9939             fIntrEnabled = CPUMIsGuestVmxPhysIntrEnabled(IEM_GET_CTX(pVCpu));
    9940         else
    9941         {
    9942             Assert(CPUMIsGuestInSvmNestedHwVirtMode(IEM_GET_CTX(pVCpu)));
    9943             fIntrEnabled = CPUMIsGuestSvmPhysIntrEnabled(pVCpu, IEM_GET_CTX(pVCpu));
    9944         }
    9945     }
    9946 #else
    9947     bool fIntrEnabled = pVCpu->cpum.GstCtx.eflags.Bits.u1IF;
    9948 #endif
    9949 
    99509931    /** @todo What if we are injecting an exception and not an interrupt? Is that
    99519932     *        possible here? For now we assert it is indeed only an interrupt. */
    9952     if (   fIntrEnabled
    9953         && TRPMHasTrap(pVCpu)
    9954         && !CPUMIsInInterruptShadow(&pVCpu->cpum.GstCtx))
    9955     {
    9956         uint8_t     u8TrapNo;
    9957         TRPMEVENT   enmType;
    9958         uint32_t    uErrCode;
    9959         RTGCPTR     uCr2;
    9960         int rc2 = TRPMQueryTrapAll(pVCpu, &u8TrapNo, &enmType, &uErrCode, &uCr2, NULL /* pu8InstLen */, NULL /* fIcebp */);
    9961         AssertRC(rc2);
    9962         Assert(enmType == TRPM_HARDWARE_INT);
    9963         VBOXSTRICTRC rcStrict = IEMInjectTrap(pVCpu, u8TrapNo, enmType, (uint16_t)uErrCode, uCr2, 0 /* cbInstr */);
    9964         TRPMResetTrap(pVCpu);
     9933    if (!TRPMHasTrap(pVCpu))
     9934    { /* likely */ }
     9935    else
     9936    {
     9937        if (   !CPUMIsInInterruptShadow(&pVCpu->cpum.GstCtx)
     9938            && !CPUMAreInterruptsInhibitedByNmi(&pVCpu->cpum.GstCtx))
     9939        {
     9940            /** @todo Can we centralize this under CPUMCanInjectInterrupt()? */
    99659941#if defined(VBOX_WITH_NESTED_HWVIRT_SVM) || defined(VBOX_WITH_NESTED_HWVIRT_VMX)
    9966         /* Injecting an event may cause a VM-exit. */
    9967         if (   rcStrict != VINF_SUCCESS
    9968             && rcStrict != VINF_IEM_RAISED_XCPT)
    9969             return iemExecStatusCodeFiddling(pVCpu, rcStrict);
     9942            bool fIntrEnabled = CPUMGetGuestGif(&pVCpu->cpum.GstCtx);
     9943            if (fIntrEnabled)
     9944            {
     9945                if (!CPUMIsGuestInNestedHwvirtMode(IEM_GET_CTX(pVCpu)))
     9946                    fIntrEnabled = pVCpu->cpum.GstCtx.eflags.Bits.u1IF;
     9947                else if (CPUMIsGuestInVmxNonRootMode(IEM_GET_CTX(pVCpu)))
     9948                    fIntrEnabled = CPUMIsGuestVmxPhysIntrEnabled(IEM_GET_CTX(pVCpu));
     9949                else
     9950                {
     9951                    Assert(CPUMIsGuestInSvmNestedHwVirtMode(IEM_GET_CTX(pVCpu)));
     9952                    fIntrEnabled = CPUMIsGuestSvmPhysIntrEnabled(pVCpu, IEM_GET_CTX(pVCpu));
     9953                }
     9954            }
    99709955#else
    9971         NOREF(rcStrict);
     9956            bool fIntrEnabled = pVCpu->cpum.GstCtx.eflags.Bits.u1IF;
    99729957#endif
     9958            if (fIntrEnabled)
     9959            {
     9960                uint8_t     u8TrapNo;
     9961                TRPMEVENT   enmType;
     9962                uint32_t    uErrCode;
     9963                RTGCPTR     uCr2;
     9964                int rc2 = TRPMQueryTrapAll(pVCpu, &u8TrapNo, &enmType, &uErrCode, &uCr2, NULL /*pu8InstLen*/, NULL /*fIcebp*/);
     9965                AssertRC(rc2);
     9966                Assert(enmType == TRPM_HARDWARE_INT);
     9967                VBOXSTRICTRC rcStrict = IEMInjectTrap(pVCpu, u8TrapNo, enmType, (uint16_t)uErrCode, uCr2, 0 /*cbInstr*/);
     9968
     9969                TRPMResetTrap(pVCpu);
     9970
     9971#if defined(VBOX_WITH_NESTED_HWVIRT_SVM) || defined(VBOX_WITH_NESTED_HWVIRT_VMX)
     9972                /* Injecting an event may cause a VM-exit. */
     9973                if (   rcStrict != VINF_SUCCESS
     9974                    && rcStrict != VINF_IEM_RAISED_XCPT)
     9975                    return iemExecStatusCodeFiddling(pVCpu, rcStrict);
     9976#else
     9977                NOREF(rcStrict);
     9978#endif
     9979            }
     9980        }
    99739981    }
    99749982
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp

    r97231 r97289  
    47024702IEM_CIMPL_DEF_2(iemCImpl_load_SReg, uint8_t, iSegReg, uint16_t, uSel)
    47034703{
     4704    if (iSegReg != X86_SREG_SS)
     4705        return IEM_CIMPL_CALL_2(iemCImpl_LoadSReg, iSegReg, uSel);
     4706    /** @todo only set it the shadow flag if it was clear before? */
    47044707    VBOXSTRICTRC rcStrict = IEM_CIMPL_CALL_2(iemCImpl_LoadSReg, iSegReg, uSel);
    4705     if (iSegReg == X86_SREG_SS && rcStrict == VINF_SUCCESS)
     4708    if (rcStrict == VINF_SUCCESS)
    47064709        CPUMSetInInterruptShadowSs(&pVCpu->cpum.GstCtx);
    47074710    return rcStrict;
     
    47564759
    47574760    /*
    4758      * Commit the stack on success.
     4761     * Commit the stack on success and set interrupt shadow flag if appropriate
     4762     * (the latter must be done after updating RIP).
    47594763     */
    47604764    if (rcStrict == VINF_SUCCESS)
     
    47624766        pVCpu->cpum.GstCtx.rsp = TmpRsp.u;
    47634767        if (iSegReg == X86_SREG_SS)
     4768        {
     4769            /** @todo only set it the shadow flag if it was clear before? */
    47644770            CPUMSetInInterruptShadowSs(&pVCpu->cpum.GstCtx);
     4771        }
    47654772    }
    47664773    return rcStrict;
     
    75087515        fEfl |= X86_EFL_IF;
    75097516
    7510     /* Commit. */
     7517    /*
     7518     * Commit.
     7519     *
     7520     * Note! Setting the shadow interrupt flag must be done after RIP updating.
     7521     */
    75117522    IEMMISC_SET_EFL(pVCpu, fEfl);
    75127523    iemRegAddToRipAndClearRF(pVCpu, cbInstr);
    75137524    if (!(fEflOld & X86_EFL_IF) && (fEfl & X86_EFL_IF))
     7525    {
     7526        /** @todo only set it the shadow flag if it was clear before? */
    75147527        CPUMSetInInterruptShadowSti(&pVCpu->cpum.GstCtx);
     7528    }
    75157529    Log2(("STI: %#x -> %#x\n", fEflOld, fEfl));
    75167530    return VINF_SUCCESS;
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