VirtualBox

Ignore:
Timestamp:
Aug 4, 2023 9:16:51 PM (19 months ago)
Author:
vboxsync
Message:

VMM/IEM: More complete CS.LIM checking, now considering it on branching and page crossings. bugref:10369

File:
1 edited

Legend:

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

    r100791 r100801  
    315315    } while(0)
    316316
     317/**
     318 * Macro that considers whether we need CS.LIM checking after a branch or
     319 * crossing over to a new page.
     320 *
     321 * This may long jump if we're raising a \#PF, \#GP or similar trouble.
     322 */
     323#define BODY_CONSIDER_CS_LIM_CHECKING(a_pTb, a_cbInstr) do { \
     324        int64_t const offFromLim = (int64_t)pVCpu->cpum.GstCtx.cs.u32Limit - (int64_t)pVCpu->cpum.GstCtx.eip; \
     325        if (offFromLim >= GUEST_PAGE_SIZE + 16 - (int32_t)(pVCpu->cpum.GstCtx.cs.u64Base & GUEST_PAGE_OFFSET_MASK)) \
     326        { /* likely */ } \
     327        else \
     328        { \
     329            Log7(("TB need CS.LIM: %p at %04x:%08RX64 LB %u; #%u offFromLim=%#RX64 CS.LIM=%#RX32 CS.BASE=%#RX64\n", \
     330                  (a_pTb), pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, (a_cbInstr), offFromLim, \
     331                  pVCpu->cpum.GstCtx.cs.u32Limit, pVCpu->cpum.GstCtx.cs.u64Base, __LINE__)); \
     332            RT_NOREF(a_pTb, a_cbInstr); \
     333            return iemThreadeFuncWorkerObsoleteTb(pVCpu); \
     334        } \
     335    } while(0)
     336
     337
    317338
    318339/**
     
    360381
    361382
     383/**
     384 * Built-in function for re-checking opcodes and considering the need for CS.LIM
     385 * checking after an instruction that may have modified them.
     386 */
     387IEM_DECL_IEMTHREADEDFUNC_DEF(iemThreadedFunc_BltIn_CheckOpcodesConsiderCsLim)
     388{
     389    PCIEMTB const  pTb      = pVCpu->iem.s.pCurTbR3;
     390    uint32_t const cbInstr  = (uint32_t)uParam0;
     391    uint32_t const idxRange = (uint32_t)uParam1;
     392    uint32_t const offRange = (uint32_t)uParam2;
     393    BODY_CONSIDER_CS_LIM_CHECKING(pTb, cbInstr);
     394    BODY_CHECK_OPCODES(pTb, idxRange, offRange, cbInstr);
     395    return VINF_SUCCESS;
     396}
     397
     398
    362399/*
    363400 * Post-branching checkers.
     
    406443
    407444/**
     445 * Built-in function for checking the PC and checking opcodes and considering
     446 * the need for CS.LIM checking after conditional branching within the same
     447 * page.
     448 *
     449 * @see iemThreadedFunc_BltIn_CheckCsLimAndPcAndOpcodes
     450 */
     451IEM_DECL_IEMTHREADEDFUNC_DEF(iemThreadedFunc_BltIn_CheckPcAndOpcodesConsiderCsLim)
     452{
     453    PCIEMTB const  pTb      = pVCpu->iem.s.pCurTbR3;
     454    uint32_t const cbInstr  = (uint32_t)uParam0;
     455    uint32_t const idxRange = (uint32_t)uParam1;
     456    uint32_t const offRange = (uint32_t)uParam2;
     457    //LogFunc(("idxRange=%u @ %#x LB %#x: offPhysPage=%#x LB %#x\n", idxRange, offRange, cbInstr, pTb->aRanges[idxRange].offPhysPage, pTb->aRanges[idxRange].cbOpcodes));
     458    BODY_CONSIDER_CS_LIM_CHECKING(pTb, cbInstr);
     459    BODY_CHECK_PC_AFTER_BRANCH(pTb, idxRange, cbInstr);
     460    BODY_CHECK_OPCODES(pTb, idxRange, offRange, cbInstr);
     461    //LogFunc(("okay\n"));
     462    return VINF_SUCCESS;
     463}
     464
     465
     466/**
    408467 * Built-in function for checking CS.LIM, loading TLB and checking opcodes when
    409468 * transitioning to a different code page.
     
    445504    uint32_t const offRange = (uint32_t)uParam2;
    446505    //LogFunc(("idxRange=%u @ %#x LB %#x: offPhysPage=%#x LB %#x\n", idxRange, offRange, cbInstr, pTb->aRanges[idxRange].offPhysPage, pTb->aRanges[idxRange].cbOpcodes));
     506    BODY_LOAD_TLB_AFTER_BRANCH(pTb, idxRange, cbInstr);
     507    BODY_CHECK_OPCODES(pTb, idxRange, offRange, cbInstr);
     508    //LogFunc(("okay\n"));
     509    return VINF_SUCCESS;
     510}
     511
     512
     513/**
     514 * Built-in function for loading TLB and checking opcodes and considering the
     515 * need for CS.LIM checking when transitioning to a different code page.
     516 *
     517 * The code page transition can either be natural over onto the next page (with
     518 * the instruction starting at page offset zero) or by means of branching.
     519 *
     520 * @see iemThreadedFunc_BltIn_CheckCsLimAndOpcodesLoadingTlb
     521 */
     522IEM_DECL_IEMTHREADEDFUNC_DEF(iemThreadedFunc_BltIn_CheckOpcodesLoadingTlbConsiderCsLim)
     523{
     524    PCIEMTB const  pTb      = pVCpu->iem.s.pCurTbR3;
     525    uint32_t const cbInstr  = (uint32_t)uParam0;
     526    uint32_t const idxRange = (uint32_t)uParam1;
     527    uint32_t const offRange = (uint32_t)uParam2;
     528    //LogFunc(("idxRange=%u @ %#x LB %#x: offPhysPage=%#x LB %#x\n", idxRange, offRange, cbInstr, pTb->aRanges[idxRange].offPhysPage, pTb->aRanges[idxRange].cbOpcodes));
     529    BODY_CONSIDER_CS_LIM_CHECKING(pTb, cbInstr);
    447530    BODY_LOAD_TLB_AFTER_BRANCH(pTb, idxRange, cbInstr);
    448531    BODY_CHECK_OPCODES(pTb, idxRange, offRange, cbInstr);
     
    509592
    510593/**
     594 * Built-in function for loading TLB and checking opcodes on both pages and
     595 * considering the need for CS.LIM checking when transitioning to a different
     596 * code page.
     597 *
     598 * This is used when the previous instruction requires revalidation of opcodes
     599 * bytes and the current instruction stries a page boundrary with opcode bytes
     600 * in both the old and new page.
     601 *
     602 * @see iemThreadedFunc_BltIn_CheckCsLimAndOpcodesAcrossPageLoadingTlb
     603 */
     604IEM_DECL_IEMTHREADEDFUNC_DEF(iemThreadedFunc_BltIn_CheckOpcodesAcrossPageLoadingTlbConsiderCsLim)
     605{
     606    PCIEMTB const  pTb         = pVCpu->iem.s.pCurTbR3;
     607    uint32_t const cbInstr     = (uint32_t)uParam0;
     608    uint32_t const cbStartPage = (uint32_t)(uParam0 >> 32);
     609    uint32_t const idxRange1   = (uint32_t)uParam1;
     610    uint32_t const offRange1   = (uint32_t)uParam2;
     611    uint32_t const idxRange2   = idxRange1 + 1;
     612    BODY_CONSIDER_CS_LIM_CHECKING(pTb, cbInstr);
     613    BODY_CHECK_OPCODES(pTb, idxRange1, offRange1, cbInstr);
     614    BODY_LOAD_TLB_FOR_NEW_PAGE(pTb, cbStartPage, idxRange2, cbInstr);
     615    BODY_CHECK_OPCODES(pTb, idxRange2, 0, cbInstr);
     616    return VINF_SUCCESS;
     617}
     618
     619
     620/**
    511621 * Built-in function for checking CS.LIM, loading TLB and checking opcodes when
    512622 * advancing naturally to a different code page.
     
    556666
    557667/**
     668 * Built-in function for loading TLB and checking opcodes and considering the
     669 * need for CS.LIM checking when advancing naturally to a different code page.
     670 *
     671 * Only opcodes on the new page is checked.
     672 *
     673 * @see iemThreadedFunc_BltIn_CheckCsLimAndOpcodesOnNextPageLoadingTlb
     674 */
     675IEM_DECL_IEMTHREADEDFUNC_DEF(iemThreadedFunc_BltIn_CheckOpcodesOnNextPageLoadingTlbConsiderCsLim)
     676{
     677    PCIEMTB const  pTb         = pVCpu->iem.s.pCurTbR3;
     678    uint32_t const cbInstr     = (uint32_t)uParam0;
     679    uint32_t const cbStartPage = (uint32_t)(uParam0 >> 32);
     680    uint32_t const idxRange1   = (uint32_t)uParam1;
     681    //uint32_t const offRange1   = (uint32_t)uParam2;
     682    uint32_t const idxRange2   = idxRange1 + 1;
     683    BODY_CONSIDER_CS_LIM_CHECKING(pTb, cbInstr);
     684    BODY_LOAD_TLB_FOR_NEW_PAGE(pTb, cbStartPage, idxRange2, cbInstr);
     685    BODY_CHECK_OPCODES(pTb, idxRange2, 0, cbInstr);
     686    RT_NOREF(uParam2);
     687    return VINF_SUCCESS;
     688}
     689
     690
     691/**
    558692 * Built-in function for checking CS.LIM, loading TLB and checking opcodes when
    559693 * advancing naturally to a different code page with first instr at byte 0.
     
    593727}
    594728
     729
     730/**
     731 * Built-in function for loading TLB and checking opcodes and considering the
     732 * need for CS.LIM checking when advancing naturally to a different code page
     733 * with first instr at byte 0.
     734 *
     735 * @see iemThreadedFunc_BltIn_CheckCsLimAndOpcodesOnNewPageLoadingTlb
     736 */
     737IEM_DECL_IEMTHREADEDFUNC_DEF(iemThreadedFunc_BltIn_CheckOpcodesOnNewPageLoadingTlbConsiderCsLim)
     738{
     739    PCIEMTB const  pTb         = pVCpu->iem.s.pCurTbR3;
     740    uint32_t const cbInstr     = (uint32_t)uParam0;
     741    uint32_t const idxRange    = (uint32_t)uParam1;
     742    Assert(uParam2 == 0 /*offRange*/); RT_NOREF(uParam2);
     743    BODY_CONSIDER_CS_LIM_CHECKING(pTb, cbInstr);
     744    BODY_LOAD_TLB_FOR_NEW_PAGE(pTb, 0, idxRange, cbInstr);
     745    Assert(pVCpu->iem.s.offCurInstrStart == 0);
     746    BODY_CHECK_OPCODES(pTb, idxRange, 0, cbInstr);
     747    return VINF_SUCCESS;
     748}
     749
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