VirtualBox

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


Ignore:
Timestamp:
Oct 28, 2022 2:18:01 PM (2 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
154332
Message:

VMM/HMVMXR0: Address issues in vmxHCAdvanceGuestRipBy wrt CS segment wraparound and RF.

File:
1 edited

Legend:

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

    r97281 r97335  
    25882588        AssertMsg((pCtx->cs.u64Base == (uint64_t)pCtx->cs.Sel << 4), ("CS base %#x %#x\n", pCtx->cs.u64Base, pCtx->cs.Sel));
    25892589        Assert(pCtx->cs.u32Limit == 0xffff);
    2590         Assert(u32CSAttr == 0xf3);
     2590        AssertMsg(u32CSAttr == 0xf3, ("cs=%#x %#x ", pCtx->cs.Sel, u32CSAttr));
    25912591        /* SS */
    25922592        Assert(pCtx->ss.u64Base == (uint64_t)pCtx->ss.Sel << 4);
     
    61646164DECLINLINE(void) vmxHCAdvanceGuestRipBy(PVMCPUCC pVCpu, uint32_t cbInstr)
    61656165{
    6166     /* Advance the RIP. */
    6167     pVCpu->cpum.GstCtx.rip += cbInstr;
    6168     ASMAtomicUoOrU64(&VCPU_2_VMXSTATE(pVCpu).fCtxChanged, HM_CHANGED_GUEST_RIP);
    6169     CPUMClearInterruptShadow(&pVCpu->cpum.GstCtx);
    6170     /** @todo clear RF? */
     6166    CPUM_ASSERT_NOT_EXTRN(pVCpu, CPUMCTX_EXTRN_RIP | CPUMCTX_EXTRN_RFLAGS | CPUMCTX_EXTRN_INHIBIT_INT | CPUMCTX_EXTRN_INHIBIT_NMI);
     6167
     6168    /*
     6169     * Advance RIP.
     6170     *
     6171     * The upper 32 bits are only set when in 64-bit mode, so we have to detect
     6172     * when the addition causes a "carry" into the upper half and check whether
     6173     * we're in 64-bit and can go on with it or wether we should zap the top
     6174     * half. (Note! The 8086, 80186 and 80286 emulation is done exclusively in
     6175     * IEM, so we don't need to bother with pre-386 16-bit wraparound.)
     6176     *
     6177     * See PC wrap around tests in bs3-cpu-weird-1.
     6178     */
     6179    uint64_t const uRipPrev = pVCpu->cpum.GstCtx.rip;
     6180    uint64_t const uRipNext = uRipPrev + cbInstr;
     6181    if (RT_LIKELY(   !((uRipNext ^ uRipPrev) & RT_BIT_64(32))
     6182                  || CPUMIsGuestIn64BitCodeEx(&pVCpu->cpum.GstCtx)))
     6183        pVCpu->cpum.GstCtx.rip = uRipNext;
     6184    else
     6185        pVCpu->cpum.GstCtx.rip = (uint32_t)uRipNext;
     6186
     6187    /*
     6188     * Clear RF and interrupt shadowing.
     6189     */
     6190    if (RT_LIKELY(!(pVCpu->cpum.GstCtx.eflags.uBoth & (X86_EFL_RF | X86_EFL_TF))))
     6191        pVCpu->cpum.GstCtx.eflags.uBoth &= ~CPUMCTX_INHIBIT_SHADOW;
     6192    else
     6193    {
     6194        if ((pVCpu->cpum.GstCtx.eflags.uBoth & (X86_EFL_RF | X86_EFL_TF)) == X86_EFL_TF)
     6195        {
     6196            /** @todo \#DB - single step. */
     6197        }
     6198        pVCpu->cpum.GstCtx.eflags.uBoth &= ~(X86_EFL_RF | CPUMCTX_INHIBIT_SHADOW);
     6199    }
     6200    AssertCompile(CPUMCTX_INHIBIT_SHADOW < UINT32_MAX);
     6201
     6202    /* Mark both RIP and RFLAGS as updated. */
     6203    ASMAtomicUoOrU64(&VCPU_2_VMXSTATE(pVCpu).fCtxChanged, HM_CHANGED_GUEST_RIP | HM_CHANGED_GUEST_RFLAGS);
    61716204}
    61726205
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette