VirtualBox

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


Ignore:
Timestamp:
Dec 13, 2023 10:41:23 PM (15 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
160746
Message:

VMM/IEM: Native translation of Blt_CheckCsLim. bugref:10371

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

Legend:

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

    r102587 r102593  
    15861586 * Used by TB code when it wants to raise a \#GP(0).
    15871587 */
    1588 IEM_DECL_NATIVE_HLP_DEF(int, iemNativeHlpExecRaiseGp0,(PVMCPUCC pVCpu, uint8_t idxInstr))
    1589 {
    1590 #ifdef IEMNATIVE_WITH_INSTRUCTION_COUNTING
    1591     pVCpu->iem.s.idxTbCurInstr = idxInstr;
    1592 #else
    1593     RT_NOREF(idxInstr);
    1594 #endif
     1588IEM_DECL_NATIVE_HLP_DEF(int, iemNativeHlpExecRaiseGp0,(PVMCPUCC pVCpu))
     1589{
    15951590    iemRaiseGeneralProtectionFault0Jmp(pVCpu);
    15961591#ifndef _MSC_VER
     
    45014496iemNativeEmitCheckGprCanonicalMaybeRaiseGp0(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxAddrReg, uint8_t idxInstr)
    45024497{
    4503     RT_NOREF(idxInstr);
    4504 
    45054498    /*
    45064499     * Make sure we don't have any outstanding guest register writes as we may
     
    45084501     */
    45094502    off = iemNativeRegFlushPendingWrites(pReNative, off);
     4503
     4504#ifdef IEMNATIVE_WITH_INSTRUCTION_COUNTING
     4505    off = iemNativeEmitStoreImmToVCpuU8(pReNative, off, idxInstr, RT_UOFFSETOF(VMCPUCC, iem.s.idxTbCurInstr));
     4506#else
     4507    RT_NOREF(idxInstr);
     4508#endif
    45104509
    45114510#ifdef RT_ARCH_AMD64
     
    45214520    off = iemNativeEmitAddGpr32Imm(pReNative, off, iTmpReg, (int32_t)0x8000);
    45224521    off = iemNativeEmitShiftGprRight(pReNative, off, iTmpReg, 16);
    4523 
    4524 # ifndef IEMNATIVE_WITH_INSTRUCTION_COUNTING
    45254522    off = iemNativeEmitJnzToNewLabel(pReNative, off, kIemNativeLabelType_RaiseGp0);
    4526 # else
    4527     uint32_t const offFixup = off;
    4528     off = iemNativeEmitJzToFixed(pReNative, off, 0);
    4529     off = iemNativeEmitLoadGpr8Imm(pReNative, off, IEMNATIVE_CALL_ARG1_GREG, idxInstr);
    4530     off = iemNativeEmitJmpToNewLabel(pReNative, off, kIemNativeLabelType_RaiseGp0);
    4531     iemNativeFixupFixedJump(pReNative, offFixup, off /*offTarget*/);
    4532 # endif
    45334523
    45344524    iemNativeRegFreeTmp(pReNative, iTmpReg);
     
    45424532     *     add     x1, x0, x1
    45434533     *     cmp     xzr, x1, lsr 48
    4544      * and either:
    45454534     *     b.ne    .Lraisexcpt
    4546      * or:
    4547      *     b.eq    .Lnoexcept
    4548      *     movz    x1, #instruction-number
    4549      *     b       .Lraisexcpt
    4550      * .Lnoexcept:
    45514535     */
    45524536    uint8_t const iTmpReg = iemNativeRegAllocTmp(pReNative, &off);
     
    45554539    off = iemNativeEmitAddTwoGprs(pReNative, off, iTmpReg, idxAddrReg);
    45564540    off = iemNativeEmitCmpArm64(pReNative, off, ARMV8_A64_REG_XZR, idxAddrReg, true /*f64Bit*/, 48 /*cShift*/, kArmv8A64InstrShift_Lsr);
    4557 
    4558 # ifndef IEMNATIVE_WITH_INSTRUCTION_COUNTING
    45594541    off = iemNativeEmitJnzToNewLabel(pReNative, off, kIemNativeLabelType_RaiseGp0);
    4560 # else
    4561     uint32_t const offFixup = off;
    4562     off = iemNativeEmitJzToFixed(pReNative, off, 0);
    4563     off = iemNativeEmitLoadGpr8Imm(pReNative, off, IEMNATIVE_CALL_ARG1_GREG, idxInstr);
    4564     off = iemNativeEmitJmpToNewLabel(pReNative, off, kIemNativeLabelType_RaiseGp0);
    4565     iemNativeFixupFixedJump(pReNative, offFixup, off /*offTarget*/);
    4566 # endif
    45674542
    45684543    iemNativeRegFreeTmp(pReNative, iTmpReg);
     
    45984573    off = iemNativeRegFlushPendingWrites(pReNative, off);
    45994574
     4575#ifdef IEMNATIVE_WITH_INSTRUCTION_COUNTING
     4576    off = iemNativeEmitStoreImmToVCpuU8(pReNative, off, idxInstr, RT_UOFFSETOF(VMCPUCC, iem.s.idxTbCurInstr));
     4577#else
     4578    RT_NOREF(idxInstr);
     4579#endif
     4580
    46004581    /** @todo implement expand down/whatnot checking */
    46014582    AssertStmt(idxSegReg == X86_SREG_CS, IEMNATIVE_DO_LONGJMP(pReNative, VERR_IEM_EMIT_CASE_NOT_IMPLEMENTED_1));
     
    46064587
    46074588    off = iemNativeEmitCmpGpr32WithGpr(pReNative, off, idxAddrReg, iTmpLimReg);
    4608 
    4609 #ifndef IEMNATIVE_WITH_INSTRUCTION_COUNTING
    46104589    off = iemNativeEmitJaToNewLabel(pReNative, off, kIemNativeLabelType_RaiseGp0);
    4611     RT_NOREF(idxInstr);
    4612 #else
    4613     uint32_t const offFixup = off;
    4614     off = iemNativeEmitJbeToFixed(pReNative, off, 0);
    4615     off = iemNativeEmitLoadGpr8Imm(pReNative, off, IEMNATIVE_CALL_ARG1_GREG, idxInstr);
    4616     off = iemNativeEmitJmpToNewLabel(pReNative, off, kIemNativeLabelType_RaiseGp0);
    4617     iemNativeFixupFixedJump(pReNative, offFixup, off /*offTarget*/);
    4618 #endif
    46194590
    46204591    iemNativeRegFreeTmp(pReNative, iTmpLimReg);
     
    48084779        iemNativeLabelDefine(pReNative, idxLabel, off);
    48094780
    4810         /* iemNativeHlpExecRaiseGp0(PVMCPUCC pVCpu, uint8_t idxInstr) */
     4781        /* iemNativeHlpExecRaiseGp0(PVMCPUCC pVCpu) */
    48114782        off = iemNativeEmitLoadGprFromGpr(pReNative, off, IEMNATIVE_CALL_ARG0_GREG, IEMNATIVE_REG_FIXED_PVMCPU);
    4812 #ifndef IEMNATIVE_WITH_INSTRUCTION_COUNTING
    4813         off = iemNativeEmitLoadGpr8Imm(pReNative, off, IEMNATIVE_CALL_ARG1_GREG, 0);
    4814 #endif
    48154783        off = iemNativeEmitCallImm(pReNative, off, (uintptr_t)iemNativeHlpExecRaiseGp0);
    48164784
     
    1107611044
    1107711045
     11046/**
     11047 * Macro that emits the 16/32-bit CS.LIM check.
     11048 */
     11049#define BODY_CHECK_CS_LIM(a_cbInstr) \
     11050    off = iemNativeEmitBltInCheckCsLim(pReNative, off, (a_cbInstr), pCallEntry->idxInstr)
     11051
     11052DECL_FORCE_INLINE(uint32_t)
     11053iemNativeEmitBltInCheckCsLim(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t cbInstr, uint8_t idxInstr)
     11054{
     11055    Assert(cbInstr >  0);
     11056    Assert(cbInstr < 16);
     11057
     11058    /* Before we start, update the instruction number in case we raise an exception. */
     11059#ifdef IEMNATIVE_WITH_INSTRUCTION_COUNTING
     11060    off = iemNativeEmitStoreImmToVCpuU8(pReNative, off, idxInstr, RT_UOFFSETOF(VMCPUCC, iem.s.idxTbCurInstr));
     11061#else
     11062    RT_NOREF(idxInstr);
     11063#endif
     11064
     11065    /*
     11066     * We need CS.LIM and RIP here. When cbInstr is larger than 1, we also need
     11067     * a temporary register for calculating the last address of the instruction.
     11068     *
     11069     * The calculation and comparisons are 32-bit.  We ASSUME that the incoming
     11070     * RIP isn't totally invalid, i.e. that any jump/call/ret/iret instruction
     11071     * that last updated EIP here checked it already, and that we're therefore
     11072     * safe in the 32-bit wrap-around scenario to only check that the last byte
     11073     * is within CS.LIM.  In the case of instruction-by-instruction advancing
     11074     * up to a EIP wrap-around, we know that CS.LIM is 4G-1 because the limit
     11075     * must be using 4KB granularity and the previous instruction was fine.
     11076     */
     11077    uint8_t const  idxRegPc     = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_Pc,
     11078                                                                  kIemNativeGstRegUse_ReadOnly);
     11079    uint8_t const  idxRegCsLim  = iemNativeRegAllocTmpForGuestReg(pReNative, &off, IEMNATIVEGSTREG_SEG_LIMIT(X86_SREG_CS),
     11080                                                                  kIemNativeGstRegUse_ReadOnly);
     11081#ifdef RT_ARCH_AMD64
     11082    uint8_t * const pbCodeBuf   = iemNativeInstrBufEnsure(pReNative, off, 8+1);
     11083#elif defined(RT_ARCH_ARM64)
     11084    uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     11085#else
     11086# error "Port me"
     11087#endif
     11088
     11089    if (cbInstr != 1)
     11090    {
     11091        uint8_t const idxRegTmp = iemNativeRegAllocTmp(pReNative, &off);
     11092
     11093        /*
     11094         * 1. idxRegTmp = idxRegPc + cbInstr;
     11095         * 2. if idxRegTmp > idxRegCsLim then raise #GP(0).
     11096         */
     11097#ifdef RT_ARCH_AMD64
     11098        /* 1. lea tmp32, [Pc + cbInstr - 1] */
     11099        if (idxRegTmp >= 8 || idxRegPc >= 8)
     11100            pbCodeBuf[off++] = (idxRegTmp < 8 ? 0 : X86_OP_REX_R) | (idxRegPc < 8 ? 0 : X86_OP_REX_B);
     11101        pbCodeBuf[off++] = 0x8d;
     11102        pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_MEM1, idxRegTmp & 7, idxRegPc & 7);
     11103        if ((idxRegPc & 7) == X86_GREG_xSP)
     11104            pbCodeBuf[off++] = X86_SIB_MAKE(idxRegPc & 7, 4 /*no index*/, 0);
     11105        pbCodeBuf[off++] = cbInstr - 1;
     11106
     11107        /* 2. cmp tmp32(r), CsLim(r/m). */
     11108        if (idxRegTmp >= 8 || idxRegCsLim >= 8)
     11109            pbCodeBuf[off++] = (idxRegTmp < 8 ? 0 : X86_OP_REX_R) | (idxRegCsLim < 8 ? 0 : X86_OP_REX_B);
     11110        pbCodeBuf[off++] = 0x3b;
     11111        pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, idxRegTmp & 7, idxRegCsLim & 7);
     11112
     11113#elif defined(RT_ARCH_ARM64)
     11114        /* 1. add tmp32, Pc, #cbInstr-1 */
     11115        pu32CodeBuf[off++] = Armv8A64MkInstrAddSubUImm12(false /*fSub*/, idxRegTmp, idxRegPc, cbInstr - 1, false /*f64Bit*/);
     11116        /* 2. cmp tmp32, CsLim */
     11117        pu32CodeBuf[off++] = Armv8A64MkInstrAddSubReg(true /*fSub*/, ARMV8_A64_REG_XZR, idxRegTmp, idxRegCsLim,
     11118                                                      false /*f64Bit*/, true /*fSetFlags*/);
     11119
     11120#endif
     11121        iemNativeRegFreeTmp(pReNative, idxRegTmp);
     11122    }
     11123    else
     11124    {
     11125        /*
     11126         * Here we can skip step 1 and compare PC and CS.LIM directly.
     11127         */
     11128#ifdef RT_ARCH_AMD64
     11129        /* 2. cmp eip(r), CsLim(r/m). */
     11130        if (idxRegPc >= 8 || idxRegCsLim >= 8)
     11131            pbCodeBuf[off++] = (idxRegPc < 8 ? 0 : X86_OP_REX_R) | (idxRegCsLim < 8 ? 0 : X86_OP_REX_B);
     11132        pbCodeBuf[off++] = 0x3b;
     11133        pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, idxRegPc & 7, idxRegCsLim & 7);
     11134
     11135#elif defined(RT_ARCH_ARM64)
     11136        /* 2. cmp Pc, CsLim */
     11137        pu32CodeBuf[off++] = Armv8A64MkInstrAddSubReg(true /*fSub*/, ARMV8_A64_REG_XZR, idxRegPc, idxRegCsLim,
     11138                                                      false /*f64Bit*/, true /*fSetFlags*/);
     11139
     11140#endif
     11141    }
     11142
     11143    /* 3. Jump if greater. */
     11144    off = iemNativeEmitJaToNewLabel(pReNative, off, kIemNativeLabelType_RaiseGp0);
     11145
     11146    iemNativeRegFreeTmp(pReNative, idxRegCsLim);
     11147    iemNativeRegFreeTmp(pReNative, idxRegPc);
     11148    return off;
     11149}
     11150
     11151#ifdef BODY_CHECK_CS_LIM
     11152/**
     11153 * Built-in function that checks the EIP/IP + uParam0 is within CS.LIM,
     11154 * raising a \#GP(0) if this isn't the case.
     11155 */
     11156static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckCsLim)
     11157{
     11158    uint32_t const cbInstr = (uint32_t)pCallEntry->auParams[0];
     11159    BODY_CHECK_CS_LIM(cbInstr);
     11160    return off;
     11161}
     11162#endif
     11163
     11164
     11165#if defined(BODY_CHECK_OPCODES) && defined(BODY_CHECK_CS_LIM)
     11166/**
     11167 * Built-in function for re-checking opcodes and CS.LIM after an instruction
     11168 * that may have modified them.
     11169 */
     11170static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckCsLimAndOpcodes)
     11171{
     11172    PCIEMTB const  pTb      = pVCpu->iem.s.pCurTbR3;
     11173    uint32_t const cbInstr  = (uint32_t)pCallEntry->auParams[0];
     11174    uint32_t const idxRange = (uint32_t)pCallEntry->auParams[1];
     11175    uint32_t const offRange = (uint32_t)pCallEntry->auParams[2];
     11176    BODY_CHECK_CS_LIM(cbInstr);
     11177    BODY_CHECK_OPCODES(pTb, idxRange, offRange, cbInstr);
     11178    return off;
     11179}
     11180#endif
     11181
     11182
     11183#if defined(BODY_CHECK_OPCODES)
     11184/**
     11185 * Built-in function for re-checking opcodes after an instruction that may have
     11186 * modified them.
     11187 */
     11188static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckOpcodes)
     11189{
     11190    PCIEMTB const  pTb      = pReNative->pTbOrg;
     11191    uint32_t const cbInstr  = (uint32_t)pCallEntry->auParams[0];
     11192    uint32_t const idxRange = (uint32_t)pCallEntry->auParams[1];
     11193    uint32_t const offRange = (uint32_t)pCallEntry->auParams[2];
     11194    BODY_CHECK_OPCODES(pTb, idxRange, offRange, cbInstr);
     11195    return off;
     11196}
     11197#endif
     11198
     11199
     11200#if defined(BODY_CHECK_OPCODES) && defined(BODY_CONSIDER_CS_LIM_CHECKING)
     11201/**
     11202 * Built-in function for re-checking opcodes and considering the need for CS.LIM
     11203 * checking after an instruction that may have modified them.
     11204 */
     11205static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckOpcodesConsiderCsLim)
     11206{
     11207    PCIEMTB const  pTb      = pReNative->pTbOrg;
     11208    uint32_t const cbInstr  = (uint32_t)pCallEntry->auParams[0];
     11209    uint32_t const idxRange = (uint32_t)pCallEntry->auParams[1];
     11210    uint32_t const offRange = (uint32_t)pCallEntry->auParams[2];
     11211    BODY_CONSIDER_CS_LIM_CHECKING(pTb, cbInstr);
     11212    BODY_CHECK_OPCODES(pTb, idxRange, offRange, cbInstr);
     11213    return off;
     11214}
     11215#endif
     11216
     11217
     11218/*
     11219 * Post-branching checkers.
     11220 */
     11221
     11222#if defined(BODY_CHECK_OPCODES) && defined(BODY_CHECK_PC_AFTER_BRANCH) && defined(BODY_CHECK_CS_LIM)
     11223/**
     11224 * Built-in function for checking CS.LIM, checking the PC and checking opcodes
     11225 * after conditional branching within the same page.
     11226 *
     11227 * @see iemThreadedFunc_BltIn_CheckPcAndOpcodes
     11228 */
     11229static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckCsLimAndPcAndOpcodes)
     11230{
     11231    PCIEMTB const  pTb      = pReNative->pTbOrg;
     11232    uint32_t const cbInstr  = (uint32_t)pCallEntry->auParams[0];
     11233    uint32_t const idxRange = (uint32_t)pCallEntry->auParams[1];
     11234    uint32_t const offRange = (uint32_t)pCallEntry->auParams[2];
     11235    //LogFunc(("idxRange=%u @ %#x LB %#x: offPhysPage=%#x LB %#x\n", idxRange, offRange, cbInstr, pTb->aRanges[idxRange].offPhysPage, pTb->aRanges[idxRange].cbOpcodes));
     11236    BODY_CHECK_CS_LIM(cbInstr);
     11237    BODY_CHECK_PC_AFTER_BRANCH(pTb, idxRange, cbInstr);
     11238    BODY_CHECK_OPCODES(pTb, idxRange, offRange, cbInstr);
     11239    //LogFunc(("okay\n"));
     11240    return off;
     11241}
     11242#endif
     11243
     11244
     11245#if defined(BODY_CHECK_OPCODES) && defined(BODY_CHECK_PC_AFTER_BRANCH)
     11246/**
     11247 * Built-in function for checking the PC and checking opcodes after conditional
     11248 * branching within the same page.
     11249 *
     11250 * @see iemThreadedFunc_BltIn_CheckCsLimAndPcAndOpcodes
     11251 */
     11252static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckPcAndOpcodes)
     11253{
     11254    PCIEMTB const  pTb      = pReNative->pTbOrg;
     11255    uint32_t const cbInstr  = (uint32_t)pCallEntry->auParams[0];
     11256    uint32_t const idxRange = (uint32_t)pCallEntry->auParams[1];
     11257    uint32_t const offRange = (uint32_t)pCallEntry->auParams[2];
     11258    //LogFunc(("idxRange=%u @ %#x LB %#x: offPhysPage=%#x LB %#x\n", idxRange, offRange, cbInstr, pTb->aRanges[idxRange].offPhysPage, pTb->aRanges[idxRange].cbOpcodes));
     11259    BODY_CHECK_PC_AFTER_BRANCH(pTb, idxRange, cbInstr);
     11260    BODY_CHECK_OPCODES(pTb, idxRange, offRange, cbInstr);
     11261    //LogFunc(("okay\n"));
     11262    return off;
     11263}
     11264#endif
     11265
     11266
     11267#if defined(BODY_CHECK_OPCODES) && defined(BODY_CHECK_PC_AFTER_BRANCH) && defined(BODY_CONSIDER_CS_LIM_CHECKING)
     11268/**
     11269 * Built-in function for checking the PC and checking opcodes and considering
     11270 * the need for CS.LIM checking after conditional branching within the same
     11271 * page.
     11272 *
     11273 * @see iemThreadedFunc_BltIn_CheckCsLimAndPcAndOpcodes
     11274 */
     11275static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckPcAndOpcodesConsiderCsLim)
     11276{
     11277    PCIEMTB const  pTb      = pReNative->pTbOrg;
     11278    uint32_t const cbInstr  = (uint32_t)pCallEntry->auParams[0];
     11279    uint32_t const idxRange = (uint32_t)pCallEntry->auParams[1];
     11280    uint32_t const offRange = (uint32_t)pCallEntry->auParams[2];
     11281    //LogFunc(("idxRange=%u @ %#x LB %#x: offPhysPage=%#x LB %#x\n", idxRange, offRange, cbInstr, pTb->aRanges[idxRange].offPhysPage, pTb->aRanges[idxRange].cbOpcodes));
     11282    BODY_CONSIDER_CS_LIM_CHECKING(pTb, cbInstr);
     11283    BODY_CHECK_PC_AFTER_BRANCH(pTb, idxRange, cbInstr);
     11284    BODY_CHECK_OPCODES(pTb, idxRange, offRange, cbInstr);
     11285    //LogFunc(("okay\n"));
     11286    return off;
     11287}
     11288#endif
     11289
     11290
     11291#if defined(BODY_CHECK_OPCODES) && defined(BODY_LOAD_TLB_AFTER_BRANCH) && defined(BODY_CHECK_CS_LIM)
     11292/**
     11293 * Built-in function for checking CS.LIM, loading TLB and checking opcodes when
     11294 * transitioning to a different code page.
     11295 *
     11296 * The code page transition can either be natural over onto the next page (with
     11297 * the instruction starting at page offset zero) or by means of branching.
     11298 *
     11299 * @see iemThreadedFunc_BltIn_CheckOpcodesLoadingTlb
     11300 */
     11301static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckCsLimAndOpcodesLoadingTlb)
     11302{
     11303    PCIEMTB const  pTb      = pReNative->pTbOrg;
     11304    uint32_t const cbInstr  = (uint32_t)pCallEntry->auParams[0];
     11305    uint32_t const idxRange = (uint32_t)pCallEntry->auParams[1];
     11306    uint32_t const offRange = (uint32_t)pCallEntry->auParams[2];
     11307    //LogFunc(("idxRange=%u @ %#x LB %#x: offPhysPage=%#x LB %#x\n", idxRange, offRange, cbInstr, pTb->aRanges[idxRange].offPhysPage, pTb->aRanges[idxRange].cbOpcodes));
     11308    BODY_CHECK_CS_LIM(cbInstr);
     11309    BODY_LOAD_TLB_AFTER_BRANCH(pTb, idxRange, cbInstr);
     11310    BODY_CHECK_OPCODES(pTb, idxRange, offRange, cbInstr);
     11311    //LogFunc(("okay\n"));
     11312    return off;
     11313}
     11314#endif
     11315
     11316
     11317#if defined(BODY_CHECK_OPCODES) && defined(BODY_LOAD_TLB_AFTER_BRANCH)
     11318/**
     11319 * Built-in function for loading TLB and checking opcodes when transitioning to
     11320 * a different code page.
     11321 *
     11322 * The code page transition can either be natural over onto the next page (with
     11323 * the instruction starting at page offset zero) or by means of branching.
     11324 *
     11325 * @see iemThreadedFunc_BltIn_CheckCsLimAndOpcodesLoadingTlb
     11326 */
     11327static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckOpcodesLoadingTlb)
     11328{
     11329    PCIEMTB const  pTb      = pReNative->pTbOrg;
     11330    uint32_t const cbInstr  = (uint32_t)pCallEntry->auParams[0];
     11331    uint32_t const idxRange = (uint32_t)pCallEntry->auParams[1];
     11332    uint32_t const offRange = (uint32_t)pCallEntry->auParams[2];
     11333    //LogFunc(("idxRange=%u @ %#x LB %#x: offPhysPage=%#x LB %#x\n", idxRange, offRange, cbInstr, pTb->aRanges[idxRange].offPhysPage, pTb->aRanges[idxRange].cbOpcodes));
     11334    BODY_LOAD_TLB_AFTER_BRANCH(pTb, idxRange, cbInstr);
     11335    BODY_CHECK_OPCODES(pTb, idxRange, offRange, cbInstr);
     11336    //LogFunc(("okay\n"));
     11337    return off;
     11338}
     11339#endif
     11340
     11341
     11342#if defined(BODY_CHECK_OPCODES) && defined(BODY_LOAD_TLB_AFTER_BRANCH) && defined(BODY_CONSIDER_CS_LIM_CHECKING)
     11343/**
     11344 * Built-in function for loading TLB and checking opcodes and considering the
     11345 * need for CS.LIM checking when transitioning to a different code page.
     11346 *
     11347 * The code page transition can either be natural over onto the next page (with
     11348 * the instruction starting at page offset zero) or by means of branching.
     11349 *
     11350 * @see iemThreadedFunc_BltIn_CheckCsLimAndOpcodesLoadingTlb
     11351 */
     11352static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckOpcodesLoadingTlbConsiderCsLim)
     11353{
     11354    PCIEMTB const  pTb      = pReNative->pTbOrg;
     11355    uint32_t const cbInstr  = (uint32_t)pCallEntry->auParams[0];
     11356    uint32_t const idxRange = (uint32_t)pCallEntry->auParams[1];
     11357    uint32_t const offRange = (uint32_t)pCallEntry->auParams[2];
     11358    //LogFunc(("idxRange=%u @ %#x LB %#x: offPhysPage=%#x LB %#x\n", idxRange, offRange, cbInstr, pTb->aRanges[idxRange].offPhysPage, pTb->aRanges[idxRange].cbOpcodes));
     11359    BODY_CONSIDER_CS_LIM_CHECKING(pTb, cbInstr);
     11360    BODY_LOAD_TLB_AFTER_BRANCH(pTb, idxRange, cbInstr);
     11361    BODY_CHECK_OPCODES(pTb, idxRange, offRange, cbInstr);
     11362    //LogFunc(("okay\n"));
     11363    return off;
     11364}
     11365#endif
     11366
     11367
     11368
     11369/*
     11370 * Natural page crossing checkers.
     11371 */
     11372
     11373#if defined(BODY_CHECK_OPCODES) && defined(BODY_LOAD_TLB_FOR_NEW_PAGE) && defined(BODY_CHECK_CS_LIM)
     11374/**
     11375 * Built-in function for checking CS.LIM, loading TLB and checking opcodes on
     11376 * both pages when transitioning to a different code page.
     11377 *
     11378 * This is used when the previous instruction requires revalidation of opcodes
     11379 * bytes and the current instruction stries a page boundrary with opcode bytes
     11380 * in both the old and new page.
     11381 *
     11382 * @see iemThreadedFunc_BltIn_CheckOpcodesAcrossPageLoadingTlb
     11383 */
     11384static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckCsLimAndOpcodesAcrossPageLoadingTlb)
     11385{
     11386    PCIEMTB const  pTb         = pReNative->pTbOrg;
     11387    uint32_t const cbInstr     = (uint32_t)pCallEntry->auParams[0];
     11388    uint32_t const cbStartPage = (uint32_t)(pCallEntry->auParams[0] >> 32);
     11389    uint32_t const idxRange1   = (uint32_t)pCallEntry->auParams[1];
     11390    uint32_t const offRange1   = (uint32_t)pCallEntry->auParams[2];
     11391    uint32_t const idxRange2   = idxRange1 + 1;
     11392    BODY_CHECK_CS_LIM(cbInstr);
     11393    BODY_CHECK_OPCODES(pTb, idxRange1, offRange1, cbInstr);
     11394    BODY_LOAD_TLB_FOR_NEW_PAGE(pTb, cbStartPage, idxRange2, cbInstr);
     11395    BODY_CHECK_OPCODES(pTb, idxRange2, 0, cbInstr);
     11396    return off;
     11397}
     11398#endif
     11399
     11400
     11401#if defined(BODY_CHECK_OPCODES) && defined(BODY_LOAD_TLB_FOR_NEW_PAGE)
     11402/**
     11403 * Built-in function for loading TLB and checking opcodes on both pages when
     11404 * transitioning to a different code page.
     11405 *
     11406 * This is used when the previous instruction requires revalidation of opcodes
     11407 * bytes and the current instruction stries a page boundrary with opcode bytes
     11408 * in both the old and new page.
     11409 *
     11410 * @see iemThreadedFunc_BltIn_CheckCsLimAndOpcodesAcrossPageLoadingTlb
     11411 */
     11412static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckOpcodesAcrossPageLoadingTlb)
     11413{
     11414    PCIEMTB const  pTb         = pReNative->pTbOrg;
     11415    uint32_t const cbInstr     = (uint32_t)pCallEntry->auParams[0];
     11416    uint32_t const cbStartPage = (uint32_t)(pCallEntry->auParams[0] >> 32);
     11417    uint32_t const idxRange1   = (uint32_t)pCallEntry->auParams[1];
     11418    uint32_t const offRange1   = (uint32_t)pCallEntry->auParams[2];
     11419    uint32_t const idxRange2   = idxRange1 + 1;
     11420    BODY_CHECK_OPCODES(pTb, idxRange1, offRange1, cbInstr);
     11421    BODY_LOAD_TLB_FOR_NEW_PAGE(pTb, cbStartPage, idxRange2, cbInstr);
     11422    BODY_CHECK_OPCODES(pTb, idxRange2, 0, cbInstr);
     11423    return off;
     11424}
     11425#endif
     11426
     11427
     11428#if defined(BODY_CHECK_OPCODES) && defined(BODY_LOAD_TLB_FOR_NEW_PAGE) && defined(BODY_CONSIDER_CS_LIM_CHECKING)
     11429/**
     11430 * Built-in function for loading TLB and checking opcodes on both pages and
     11431 * considering the need for CS.LIM checking when transitioning to a different
     11432 * code page.
     11433 *
     11434 * This is used when the previous instruction requires revalidation of opcodes
     11435 * bytes and the current instruction stries a page boundrary with opcode bytes
     11436 * in both the old and new page.
     11437 *
     11438 * @see iemThreadedFunc_BltIn_CheckCsLimAndOpcodesAcrossPageLoadingTlb
     11439 */
     11440static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckOpcodesAcrossPageLoadingTlbConsiderCsLim)
     11441{
     11442    PCIEMTB const  pTb         = pReNative->pTbOrg;
     11443    uint32_t const cbInstr     = (uint32_t)pCallEntry->auParams[0];
     11444    uint32_t const cbStartPage = (uint32_t)(pCallEntry->auParams[0] >> 32);
     11445    uint32_t const idxRange1   = (uint32_t)pCallEntry->auParams[1];
     11446    uint32_t const offRange1   = (uint32_t)pCallEntry->auParams[2];
     11447    uint32_t const idxRange2   = idxRange1 + 1;
     11448    BODY_CONSIDER_CS_LIM_CHECKING(pTb, cbInstr);
     11449    BODY_CHECK_OPCODES(pTb, idxRange1, offRange1, cbInstr);
     11450    BODY_LOAD_TLB_FOR_NEW_PAGE(pTb, cbStartPage, idxRange2, cbInstr);
     11451    BODY_CHECK_OPCODES(pTb, idxRange2, 0, cbInstr);
     11452    return off;
     11453}
     11454#endif
     11455
     11456
     11457#if defined(BODY_CHECK_OPCODES) && defined(BODY_LOAD_TLB_FOR_NEW_PAGE) && defined(BODY_CHECK_CS_LIM)
     11458/**
     11459 * Built-in function for checking CS.LIM, loading TLB and checking opcodes when
     11460 * advancing naturally to a different code page.
     11461 *
     11462 * Only opcodes on the new page is checked.
     11463 *
     11464 * @see iemThreadedFunc_BltIn_CheckOpcodesOnNextPageLoadingTlb
     11465 */
     11466static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckCsLimAndOpcodesOnNextPageLoadingTlb)
     11467{
     11468    PCIEMTB const  pTb         = pReNative->pTbOrg;
     11469    uint32_t const cbInstr     = (uint32_t)pCallEntry->auParams[0];
     11470    uint32_t const cbStartPage = (uint32_t)(pCallEntry->auParams[0] >> 32);
     11471    uint32_t const idxRange1   = (uint32_t)pCallEntry->auParams[1];
     11472    //uint32_t const offRange1   = (uint32_t)uParam2;
     11473    uint32_t const idxRange2   = idxRange1 + 1;
     11474    BODY_CHECK_CS_LIM(cbInstr);
     11475    BODY_LOAD_TLB_FOR_NEW_PAGE(pTb, cbStartPage, idxRange2, cbInstr);
     11476    BODY_CHECK_OPCODES(pTb, idxRange2, 0, cbInstr);
     11477    return off;
     11478}
     11479#endif
     11480
     11481
     11482#if defined(BODY_CHECK_OPCODES) && defined(BODY_LOAD_TLB_FOR_NEW_PAGE)
     11483/**
     11484 * Built-in function for loading TLB and checking opcodes when advancing
     11485 * naturally to a different code page.
     11486 *
     11487 * Only opcodes on the new page is checked.
     11488 *
     11489 * @see iemThreadedFunc_BltIn_CheckCsLimAndOpcodesOnNextPageLoadingTlb
     11490 */
     11491static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckOpcodesOnNextPageLoadingTlb)
     11492{
     11493    PCIEMTB const  pTb         = pReNative->pTbOrg;
     11494    uint32_t const cbInstr     = (uint32_t)pCallEntry->auParams[0];
     11495    uint32_t const cbStartPage = (uint32_t)(pCallEntry->auParams[0] >> 32);
     11496    uint32_t const idxRange1   = (uint32_t)pCallEntry->auParams[1];
     11497    //uint32_t const offRange1   = (uint32_t)pCallEntry->auParams[2];
     11498    uint32_t const idxRange2   = idxRange1 + 1;
     11499    BODY_LOAD_TLB_FOR_NEW_PAGE(pTb, cbStartPage, idxRange2, cbInstr);
     11500    BODY_CHECK_OPCODES(pTb, idxRange2, 0, cbInstr);
     11501    return off;
     11502}
     11503#endif
     11504
     11505
     11506#if defined(BODY_CHECK_OPCODES) && defined(BODY_LOAD_TLB_FOR_NEW_PAGE) && defined(BODY_CONSIDER_CS_LIM_CHECKING)
     11507/**
     11508 * Built-in function for loading TLB and checking opcodes and considering the
     11509 * need for CS.LIM checking when advancing naturally to a different code page.
     11510 *
     11511 * Only opcodes on the new page is checked.
     11512 *
     11513 * @see iemThreadedFunc_BltIn_CheckCsLimAndOpcodesOnNextPageLoadingTlb
     11514 */
     11515static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckOpcodesOnNextPageLoadingTlbConsiderCsLim)
     11516{
     11517    PCIEMTB const  pTb         = pReNative->pTbOrg;
     11518    uint32_t const cbInstr     = (uint32_t)pCallEntry->auParams[0];
     11519    uint32_t const cbStartPage = (uint32_t)(pCallEntry->auParams[0] >> 32);
     11520    uint32_t const idxRange1   = (uint32_t)pCallEntry->auParams[1];
     11521    //uint32_t const offRange1   = (uint32_t)pCallEntry->auParams[2];
     11522    uint32_t const idxRange2   = idxRange1 + 1;
     11523    BODY_CONSIDER_CS_LIM_CHECKING(pTb, cbInstr);
     11524    BODY_LOAD_TLB_FOR_NEW_PAGE(pTb, cbStartPage, idxRange2, cbInstr);
     11525    BODY_CHECK_OPCODES(pTb, idxRange2, 0, cbInstr);
     11526    return off;
     11527}
     11528#endif
     11529
     11530
     11531#if defined(BODY_CHECK_OPCODES) && defined(BODY_LOAD_TLB_FOR_NEW_PAGE) && defined(BODY_CHECK_CS_LIM)
     11532/**
     11533 * Built-in function for checking CS.LIM, loading TLB and checking opcodes when
     11534 * advancing naturally to a different code page with first instr at byte 0.
     11535 *
     11536 * @see iemThreadedFunc_BltIn_CheckOpcodesOnNewPageLoadingTlb
     11537 */
     11538static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckCsLimAndOpcodesOnNewPageLoadingTlb)
     11539{
     11540    PCIEMTB const  pTb         = pReNative->pTbOrg;
     11541    uint32_t const cbInstr     = (uint32_t)pCallEntry->auParams[0];
     11542    uint32_t const idxRange    = (uint32_t)pCallEntry->auParams[1];
     11543    BODY_CHECK_CS_LIM(cbInstr);
     11544    BODY_LOAD_TLB_FOR_NEW_PAGE(pTb, 0, idxRange, cbInstr);
     11545    //Assert(pVCpu->iem.s.offCurInstrStart == 0);
     11546    BODY_CHECK_OPCODES(pTb, idxRange, 0, cbInstr);
     11547    return off;
     11548}
     11549#endif
     11550
     11551
     11552#if defined(BODY_CHECK_OPCODES) && defined(BODY_LOAD_TLB_FOR_NEW_PAGE)
     11553/**
     11554 * Built-in function for loading TLB and checking opcodes when advancing
     11555 * naturally to a different code page with first instr at byte 0.
     11556 *
     11557 * @see iemThreadedFunc_BltIn_CheckCsLimAndOpcodesOnNewPageLoadingTlb
     11558 */
     11559static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckOpcodesOnNewPageLoadingTlb)
     11560{
     11561    PCIEMTB const  pTb         = pReNative->pTbOrg;
     11562    uint32_t const cbInstr     = (uint32_t)pCallEntry->auParams[0];
     11563    uint32_t const idxRange    = (uint32_t)pCallEntry->auParams[1];
     11564    BODY_LOAD_TLB_FOR_NEW_PAGE(pTb, 0, idxRange, cbInstr);
     11565    //Assert(pVCpu->iem.s.offCurInstrStart == 0);
     11566    BODY_CHECK_OPCODES(pTb, idxRange, 0, cbInstr);
     11567    return off;
     11568}
     11569#endif
     11570
     11571
     11572#if defined(BODY_CHECK_OPCODES) && defined(BODY_LOAD_TLB_FOR_NEW_PAGE) && defined(BODY_CONSIDER_CS_LIM_CHECKING)
     11573/**
     11574 * Built-in function for loading TLB and checking opcodes and considering the
     11575 * need for CS.LIM checking when advancing naturally to a different code page
     11576 * with first instr at byte 0.
     11577 *
     11578 * @see iemThreadedFunc_BltIn_CheckCsLimAndOpcodesOnNewPageLoadingTlb
     11579 */
     11580static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckOpcodesOnNewPageLoadingTlbConsiderCsLim)
     11581{
     11582    PCIEMTB const  pTb         = pReNative->pTbOrg;
     11583    uint32_t const cbInstr     = (uint32_t)pCallEntry->auParams[0];
     11584    uint32_t const idxRange    = (uint32_t)pCallEntry->auParams[1];
     11585    BODY_CONSIDER_CS_LIM_CHECKING(pTb, cbInstr);
     11586    BODY_LOAD_TLB_FOR_NEW_PAGE(pTb, 0, idxRange, cbInstr);
     11587    //Assert(pVCpu->iem.s.offCurInstrStart == 0);
     11588    BODY_CHECK_OPCODES(pTb, idxRange, 0, cbInstr);
     11589    return off;
     11590}
     11591#endif
     11592
    1107811593
    1107911594/*********************************************************************************************************************************
     
    1142111936                                    break;
    1142211937                                case kIemNativeLabelType_TlbMiss:
    11423                                     pszName = "CheckIrq_TlbMiss";
     11938                                    pszName = "TlbMiss";
    1142411939                                    fNumbered = true;
    1142511940                                    break;
    1142611941                                case kIemNativeLabelType_TlbDone:
    11427                                     pszName = "CheckIrq_TlbDone";
     11942                                    pszName = "TlbDone";
    1142811943                                    fNumbered = true;
    1142911944                                    break;
  • trunk/src/VBox/VMM/VMMAll/IEMAllThrdPython.py

    r102585 r102593  
    19641964        ( 'CheckMode',                                          1, True  ),
    19651965        ( 'CheckHwInstrBps',                                    0, False ),
    1966         ( 'CheckCsLim',                                         1, False ),
     1966        ( 'CheckCsLim',                                         1, True ),
    19671967
    19681968        ( 'CheckCsLimAndOpcodes',                               3, False ),
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