VirtualBox

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


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

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

Location:
trunk/src/VBox/VMM
Files:
4 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
  • trunk/src/VBox/VMM/VMMAll/IEMAllThrdPython.py

    r100788 r100801  
    13841384        'CheckMode',
    13851385        'CheckCsLim',
     1386
    13861387        'CheckCsLimAndOpcodes',
    13871388        'CheckOpcodes',
     1389        'CheckOpcodesConsiderCsLim',
     1390
    13881391        'CheckCsLimAndPcAndOpcodes',
    13891392        'CheckPcAndOpcodes',
     1393        'CheckPcAndOpcodesConsiderCsLim',
     1394
    13901395        'CheckCsLimAndOpcodesAcrossPageLoadingTlb',
    13911396        'CheckOpcodesAcrossPageLoadingTlb',
     1397        'CheckOpcodesAcrossPageLoadingTlbConsiderCsLim',
     1398
    13921399        'CheckCsLimAndOpcodesLoadingTlb',
    13931400        'CheckOpcodesLoadingTlb',
     1401        'CheckOpcodesLoadingTlbConsiderCsLim',
     1402
    13941403        'CheckCsLimAndOpcodesOnNextPageLoadingTlb',
    13951404        'CheckOpcodesOnNextPageLoadingTlb',
     1405        'CheckOpcodesOnNextPageLoadingTlbConsiderCsLim',
     1406
    13961407        'CheckCsLimAndOpcodesOnNewPageLoadingTlb',
    13971408        'CheckOpcodesOnNewPageLoadingTlb',
     1409        'CheckOpcodesOnNewPageLoadingTlbConsiderCsLim',
    13981410    );
    13991411
  • trunk/src/VBox/VMM/VMMAll/IEMAllThrdRecompiler.cpp

    r100792 r100801  
    865865 *
    866866 * @returns true if everything went well, false if we're out of space in the TB
    867  *          (e.g. opcode ranges).
     867 *          (e.g. opcode ranges) or needs to start doing CS.LIM checks.
    868868 * @param   pVCpu       The cross context virtual CPU structure of the calling
    869869 *                      thread.
     
    877877        RTLogChangeFlags(NULL, 0, RTLOGFLAGS_DISABLED);
    878878#endif
     879
     880    /*
     881     * If we're not in 64-bit mode and not already checking CS.LIM we need to
     882     * see if it's needed to start checking.
     883     */
     884    bool           fConsiderCsLimChecking;
     885    uint32_t const fMode = pVCpu->iem.s.fExec & IEM_F_MODE_MASK;
     886    if (   fMode == IEM_F_MODE_X86_64BIT
     887        || (pTb->fFlags & IEMTB_F_CS_LIM_CHECKS)
     888        || fMode == IEM_F_MODE_X86_32BIT_PROT_FLAT
     889        || fMode == IEM_F_MODE_X86_32BIT_FLAT)
     890        fConsiderCsLimChecking = false; /* already enabled or not needed */
     891    else
     892    {
     893        int64_t const offFromLim = (int64_t)pVCpu->cpum.GstCtx.cs.u32Limit - (int64_t)pVCpu->cpum.GstCtx.eip;
     894        if (offFromLim >= GUEST_PAGE_SIZE + 16 - (int32_t)(pVCpu->cpum.GstCtx.cs.u64Base & GUEST_PAGE_OFFSET_MASK))
     895            fConsiderCsLimChecking = true; /* likely */
     896        else
     897        {
     898            Log8(("%04x:%08RX64: Needs CS.LIM checks (%#RX64)\n", pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, offFromLim));
     899            return false;
     900        }
     901    }
    879902
    880903    /*
     
    10001023                pCall->enmFunction = pTb->fFlags & IEMTB_F_CS_LIM_CHECKS
    10011024                                   ? kIemThreadedFunc_BltIn_CheckCsLimAndOpcodesLoadingTlb
    1002                                    : kIemThreadedFunc_BltIn_CheckOpcodesLoadingTlb;
     1025                                   : !fConsiderCsLimChecking
     1026                                   ? kIemThreadedFunc_BltIn_CheckOpcodesLoadingTlb
     1027                                   : kIemThreadedFunc_BltIn_CheckOpcodesLoadingTlbConsiderCsLim;
    10031028            else if (pVCpu->iem.s.fTbBranched & (IEMBRANCHED_F_CONDITIONAL | /* paranoia: */ IEMBRANCHED_F_DIRECT))
    10041029                pCall->enmFunction = pTb->fFlags & IEMTB_F_CS_LIM_CHECKS
    10051030                                   ? kIemThreadedFunc_BltIn_CheckCsLimAndPcAndOpcodes
    1006                                    : kIemThreadedFunc_BltIn_CheckPcAndOpcodes;
     1031                                   : !fConsiderCsLimChecking
     1032                                   ? kIemThreadedFunc_BltIn_CheckPcAndOpcodes
     1033                                   : kIemThreadedFunc_BltIn_CheckPcAndOpcodesConsiderCsLim;
    10071034            else
    10081035            {
     
    10101037                pCall->enmFunction = pTb->fFlags & IEMTB_F_CS_LIM_CHECKS
    10111038                                   ? kIemThreadedFunc_BltIn_CheckCsLimAndOpcodes
    1012                                    : kIemThreadedFunc_BltIn_CheckOpcodes;
     1039                                   : !fConsiderCsLimChecking
     1040                                   ? kIemThreadedFunc_BltIn_CheckOpcodes
     1041                                   : kIemThreadedFunc_BltIn_CheckOpcodesConsiderCsLim;
    10131042            }
    10141043        }
     
    11121141            pCall->enmFunction = pTb->fFlags & IEMTB_F_CS_LIM_CHECKS
    11131142                               ? kIemThreadedFunc_BltIn_CheckCsLimAndOpcodesOnNewPageLoadingTlb
    1114                                : kIemThreadedFunc_BltIn_CheckOpcodesOnNewPageLoadingTlb;
     1143                               : !fConsiderCsLimChecking
     1144                               ? kIemThreadedFunc_BltIn_CheckOpcodesOnNewPageLoadingTlb
     1145                               : kIemThreadedFunc_BltIn_CheckOpcodesOnNewPageLoadingTlbConsiderCsLim;
    11151146        }
    11161147        else
     
    11341165                pCall->enmFunction = pTb->fFlags & IEMTB_F_CS_LIM_CHECKS
    11351166                                   ? kIemThreadedFunc_BltIn_CheckCsLimAndOpcodesAcrossPageLoadingTlb
    1136                                    : kIemThreadedFunc_BltIn_CheckOpcodesAcrossPageLoadingTlb;
     1167                                   : !fConsiderCsLimChecking
     1168                                   ? kIemThreadedFunc_BltIn_CheckOpcodesAcrossPageLoadingTlb
     1169                                   : kIemThreadedFunc_BltIn_CheckOpcodesAcrossPageLoadingTlbConsiderCsLim;
    11371170            else
    11381171                pCall->enmFunction = pTb->fFlags & IEMTB_F_CS_LIM_CHECKS
    11391172                                   ? kIemThreadedFunc_BltIn_CheckCsLimAndOpcodesOnNextPageLoadingTlb
    1140                                    : kIemThreadedFunc_BltIn_CheckOpcodesOnNextPageLoadingTlb;
     1173                                   : !fConsiderCsLimChecking
     1174                                   ? kIemThreadedFunc_BltIn_CheckOpcodesOnNextPageLoadingTlb
     1175                                   : kIemThreadedFunc_BltIn_CheckOpcodesOnNextPageLoadingTlbConsiderCsLim;
    11411176        }
    11421177    }
     
    15691604     */
    15701605    if (IEM_IS_64BIT_CODE(pVCpu))
    1571     { /* done */ }
    1572     else if (RT_LIKELY(   pVCpu->cpum.GstCtx.eip < pVCpu->cpum.GstCtx.cs.u32Limit
    1573                        && pVCpu->cpum.GstCtx.cs.u32Limit - pVCpu->cpum.GstCtx.eip >= X86_PAGE_SIZE))
    1574     { /* done */ }
    1575     else
    1576         fRet |= IEMTB_F_CS_LIM_CHECKS;
    1577     return fRet;
     1606        return fRet;
     1607
     1608    int64_t const offFromLim = (int64_t)pVCpu->cpum.GstCtx.cs.u32Limit - (int64_t)pVCpu->cpum.GstCtx.eip;
     1609    if (offFromLim >= X86_PAGE_SIZE + 16 - (int32_t)(pVCpu->cpum.GstCtx.cs.u64Base & GUEST_PAGE_OFFSET_MASK))
     1610        return fRet;
     1611    return fRet | IEMTB_F_CS_LIM_CHECKS;
    15781612}
    15791613
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r100792 r100801  
    50145014IEM_DECL_IEMTHREADEDFUNC_PROTO(iemThreadedFunc_BltIn_CheckCsLimAndOpcodes);
    50155015IEM_DECL_IEMTHREADEDFUNC_PROTO(iemThreadedFunc_BltIn_CheckOpcodes);
     5016IEM_DECL_IEMTHREADEDFUNC_PROTO(iemThreadedFunc_BltIn_CheckOpcodesConsiderCsLim);
    50165017
    50175018/* Branching: */
    50185019IEM_DECL_IEMTHREADEDFUNC_PROTO(iemThreadedFunc_BltIn_CheckCsLimAndPcAndOpcodes);
    50195020IEM_DECL_IEMTHREADEDFUNC_PROTO(iemThreadedFunc_BltIn_CheckPcAndOpcodes);
     5021IEM_DECL_IEMTHREADEDFUNC_PROTO(iemThreadedFunc_BltIn_CheckPcAndOpcodesConsiderCsLim);
    50205022
    50215023IEM_DECL_IEMTHREADEDFUNC_PROTO(iemThreadedFunc_BltIn_CheckCsLimAndOpcodesLoadingTlb);
    50225024IEM_DECL_IEMTHREADEDFUNC_PROTO(iemThreadedFunc_BltIn_CheckOpcodesLoadingTlb);
     5025IEM_DECL_IEMTHREADEDFUNC_PROTO(iemThreadedFunc_BltIn_CheckOpcodesLoadingTlbConsiderCsLim);
    50235026
    50245027/* Natural page crossing: */
    50255028IEM_DECL_IEMTHREADEDFUNC_PROTO(iemThreadedFunc_BltIn_CheckCsLimAndOpcodesAcrossPageLoadingTlb);
    50265029IEM_DECL_IEMTHREADEDFUNC_PROTO(iemThreadedFunc_BltIn_CheckOpcodesAcrossPageLoadingTlb);
     5030IEM_DECL_IEMTHREADEDFUNC_PROTO(iemThreadedFunc_BltIn_CheckOpcodesAcrossPageLoadingTlbConsiderCsLim);
    50275031
    50285032IEM_DECL_IEMTHREADEDFUNC_PROTO(iemThreadedFunc_BltIn_CheckCsLimAndOpcodesOnNextPageLoadingTlb);
    50295033IEM_DECL_IEMTHREADEDFUNC_PROTO(iemThreadedFunc_BltIn_CheckOpcodesOnNextPageLoadingTlb);
     5034IEM_DECL_IEMTHREADEDFUNC_PROTO(iemThreadedFunc_BltIn_CheckOpcodesOnNextPageLoadingTlbConsiderCsLim);
    50305035
    50315036IEM_DECL_IEMTHREADEDFUNC_PROTO(iemThreadedFunc_BltIn_CheckCsLimAndOpcodesOnNewPageLoadingTlb);
    50325037IEM_DECL_IEMTHREADEDFUNC_PROTO(iemThreadedFunc_BltIn_CheckOpcodesOnNewPageLoadingTlb);
     5038IEM_DECL_IEMTHREADEDFUNC_PROTO(iemThreadedFunc_BltIn_CheckOpcodesOnNewPageLoadingTlbConsiderCsLim);
    50335039
    50345040bool iemThreadedCompileEmitIrqCheckBefore(PVMCPUCC pVCpu, PIEMTB pTb);
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