VirtualBox

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


Ignore:
Timestamp:
Dec 22, 2023 10:15:28 PM (14 months ago)
Author:
vboxsync
Message:

VMM/IEM: Native translation of BODY_LOAD_TLB_FOR_NEW_PAGE (minus TLB lookup). bugref:10371

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

Legend:

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

    r102685 r102695  
    3131*********************************************************************************************************************************/
    3232#define LOG_GROUP LOG_GROUP_IEM_RE_NATIVE
    33 #define IEM_WITH_OPAQUE_DECODER_STATE
     33//#define IEM_WITH_OPAQUE_DECODER_STATE - need offCurInstrStart access for iemNativeHlpMemCodeNewPageTlbMiss and friends.
    3434#define VMCPU_INCL_CPUM_GST_CTX
    3535#define VMM_INCLUDED_SRC_include_IEMMc_h /* block IEMMc.h inclusion. */
     
    6565#endif
    6666
     67
     68/**
     69 * Used by TB code to deal with a TLB miss for a new page.
     70 */
     71IEM_DECL_NATIVE_HLP_DEF(RTGCPHYS, iemNativeHlpMemCodeNewPageTlbMiss,(PVMCPUCC pVCpu, uint8_t offInstr))
     72{
     73    pVCpu->iem.s.pbInstrBuf       = NULL;
     74    pVCpu->iem.s.offCurInstrStart = GUEST_PAGE_SIZE - offInstr;
     75    pVCpu->iem.s.offInstrNextByte = GUEST_PAGE_SIZE;
     76    iemOpcodeFetchBytesJmp(pVCpu, 0, NULL);
     77    return pVCpu->iem.s.pbInstrBuf ? pVCpu->iem.s.GCPhysInstrBuf : NIL_RTGCPHYS;
     78}
    6779
    6880
     
    247259
    248260/**
    249  * Sets idxTbCurInstr in preparation of raising an exception.
     261 * Sets idxTbCurInstr in preparation of raising an exception or aborting the TB.
    250262 */
    251263/** @todo Optimize this, so we don't set the same value more than once.  Just
     
    257269# define BODY_SET_CUR_INSTR() ((void)0)
    258270#endif
     271
     272/**
     273 * Flushes pending writes in preparation of raising an exception or aborting the TB.
     274 */
     275#define BODY_FLUSH_PENDING_WRITES() \
     276    off = iemNativeRegFlushPendingWrites(pReNative, off);
    259277
    260278
     
    11311149
    11321150
     1151/**
     1152 * Macro that implements TLB loading and updating pbInstrBuf updating for an
     1153 * instruction crossing into a new page.
     1154 *
     1155 * This may long jump if we're raising a \#PF, \#GP or similar trouble.
     1156 */
     1157#define BODY_LOAD_TLB_FOR_NEW_PAGE(a_pTb, a_offInstr, a_idxRange, a_cbInstr) \
     1158    RT_NOREF(a_cbInstr); \
     1159    off = iemNativeEmitBltLoadTlbForNewPage(pReNative, off, pTb, a_idxRange, a_offInstr)
     1160
     1161DECL_FORCE_INLINE(uint32_t)
     1162iemNativeEmitBltLoadTlbForNewPage(PIEMRECOMPILERSTATE pReNative, uint32_t off, PCIEMTB pTb, uint8_t idxRange, uint8_t offInstr)
     1163{
     1164#ifdef VBOX_STRICT
     1165    off = iemNativeEmitMarker(pReNative, off, 0x80000005);
     1166#endif
     1167
     1168    /*
     1169     * Move/spill/flush stuff out of call-volatile registers.
     1170     * This is the easy way out. We could contain this to the tlb-miss branch
     1171     * by saving and restoring active stuff here.
     1172     */
     1173    /** @todo save+restore active registers and maybe guest shadows in tlb-miss.  */
     1174    off = iemNativeRegMoveAndFreeAndFlushAtCall(pReNative, off, 0 /* vacate all non-volatile regs */);
     1175
     1176    /*
     1177     * Define labels and allocate the register for holding the GCPhys of the new page.
     1178     */
     1179    uint16_t const uTlbSeqNo        = pReNative->uTlbSeqNo++;
     1180    uint32_t const idxLabelTlbMiss  = iemNativeLabelCreate(pReNative, kIemNativeLabelType_TlbMiss, UINT32_MAX, uTlbSeqNo);
     1181    uint32_t const idxLabelTlbDone  = iemNativeLabelCreate(pReNative, kIemNativeLabelType_TlbDone, UINT32_MAX, uTlbSeqNo);
     1182    uint32_t const idxRegGCPhys     = iemNativeRegAllocTmp(pReNative, &off);
     1183
     1184    /*
     1185     * First we try to go via the TLB.
     1186     */
     1187    /** @todo  */
     1188
     1189    /*
     1190     * TLB miss: Call iemNativeHlpMemCodeNewPageTlbMiss to do the work.
     1191     */
     1192    iemNativeLabelDefine(pReNative, idxLabelTlbMiss, off);
     1193
     1194    /* IEMNATIVE_CALL_ARG1_GREG = offInstr */
     1195    off = iemNativeEmitLoadGpr8Imm(pReNative, off, IEMNATIVE_CALL_ARG1_GREG, offInstr);
     1196
     1197    /* IEMNATIVE_CALL_ARG0_GREG = pVCpu */
     1198    off = iemNativeEmitLoadGprFromGpr(pReNative, off, IEMNATIVE_CALL_ARG0_GREG, IEMNATIVE_REG_FIXED_PVMCPU);
     1199
     1200    /* Done setting up parameters, make the call. */
     1201    off = iemNativeEmitCallImm(pReNative, off, (uintptr_t)iemNativeHlpMemCodeNewPageTlbMiss);
     1202
     1203    /* Move the result to the right register. */
     1204    if (idxRegGCPhys != IEMNATIVE_CALL_RET_GREG)
     1205        off = iemNativeEmitLoadGprFromGpr(pReNative, off, idxRegGCPhys, IEMNATIVE_CALL_RET_GREG);
     1206
     1207    iemNativeLabelDefine(pReNative, idxLabelTlbDone, off);
     1208
     1209    /*
     1210     * Now check the physical address of the page matches the expected one.
     1211     */
     1212    RTGCPHYS const GCPhysNewPage = iemTbGetRangePhysPageAddr(pTb, idxRange);
     1213    off = iemNativeEmitTestIfGprNotEqualImmAndJmpToNewLabel(pReNative, off, idxRegGCPhys, GCPhysNewPage,
     1214                                                            kIemNativeLabelType_ObsoleteTb);
     1215
     1216    iemNativeRegFreeTmp(pReNative, idxRegGCPhys);
     1217    return off;
     1218}
     1219
     1220
    11331221#ifdef BODY_CHECK_CS_LIM
    11341222/**
     
    11401228    uint32_t const cbInstr = (uint32_t)pCallEntry->auParams[0];
    11411229    BODY_SET_CUR_INSTR();
     1230    BODY_FLUSH_PENDING_WRITES();
    11421231    BODY_CHECK_CS_LIM(cbInstr);
    11431232    return off;
     
    11581247    uint32_t const offRange = (uint32_t)pCallEntry->auParams[2];
    11591248    BODY_SET_CUR_INSTR();
     1249    BODY_FLUSH_PENDING_WRITES();
    11601250    BODY_CHECK_CS_LIM(cbInstr);
    11611251    BODY_CHECK_OPCODES(pTb, idxRange, offRange, cbInstr);
     
    11771267    uint32_t const offRange = (uint32_t)pCallEntry->auParams[2];
    11781268    BODY_SET_CUR_INSTR();
     1269    BODY_FLUSH_PENDING_WRITES();
    11791270    BODY_CHECK_OPCODES(pTb, idxRange, offRange, cbInstr);
    11801271    return off;
     
    11951286    uint32_t const offRange = (uint32_t)pCallEntry->auParams[2];
    11961287    BODY_SET_CUR_INSTR();
     1288    BODY_FLUSH_PENDING_WRITES();
    11971289    BODY_CONSIDER_CS_LIM_CHECKING(pTb, cbInstr);
    11981290    BODY_CHECK_OPCODES(pTb, idxRange, offRange, cbInstr);
     
    12211313    //LogFunc(("idxRange=%u @ %#x LB %#x: offPhysPage=%#x LB %#x\n", idxRange, offRange, cbInstr, pTb->aRanges[idxRange].offPhysPage, pTb->aRanges[idxRange].cbOpcodes));
    12221314    BODY_SET_CUR_INSTR();
     1315    BODY_FLUSH_PENDING_WRITES();
    12231316    BODY_CHECK_CS_LIM(cbInstr);
    12241317    BODY_CHECK_PC_AFTER_BRANCH(pTb, idxRange, offRange, cbInstr);
     
    12451338    //LogFunc(("idxRange=%u @ %#x LB %#x: offPhysPage=%#x LB %#x\n", idxRange, offRange, cbInstr, pTb->aRanges[idxRange].offPhysPage, pTb->aRanges[idxRange].cbOpcodes));
    12461339    BODY_SET_CUR_INSTR();
     1340    BODY_FLUSH_PENDING_WRITES();
    12471341    BODY_CHECK_PC_AFTER_BRANCH(pTb, idxRange, offRange, cbInstr);
    12481342    BODY_CHECK_OPCODES(pTb, idxRange, offRange, cbInstr);
     
    12691363    //LogFunc(("idxRange=%u @ %#x LB %#x: offPhysPage=%#x LB %#x\n", idxRange, offRange, cbInstr, pTb->aRanges[idxRange].offPhysPage, pTb->aRanges[idxRange].cbOpcodes));
    12701364    BODY_SET_CUR_INSTR();
     1365    BODY_FLUSH_PENDING_WRITES();
    12711366    BODY_CONSIDER_CS_LIM_CHECKING(pTb, cbInstr);
    12721367    BODY_CHECK_PC_AFTER_BRANCH(pTb, idxRange, offRange, cbInstr);
     
    12961391    //LogFunc(("idxRange=%u @ %#x LB %#x: offPhysPage=%#x LB %#x\n", idxRange, offRange, cbInstr, pTb->aRanges[idxRange].offPhysPage, pTb->aRanges[idxRange].cbOpcodes));
    12971392    BODY_SET_CUR_INSTR();
     1393    BODY_FLUSH_PENDING_WRITES();
    12981394    BODY_CHECK_CS_LIM(cbInstr);
    12991395    BODY_LOAD_TLB_AFTER_BRANCH(pTb, idxRange, cbInstr);
     
    13231419    //LogFunc(("idxRange=%u @ %#x LB %#x: offPhysPage=%#x LB %#x\n", idxRange, offRange, cbInstr, pTb->aRanges[idxRange].offPhysPage, pTb->aRanges[idxRange].cbOpcodes));
    13241420    BODY_SET_CUR_INSTR();
     1421    BODY_FLUSH_PENDING_WRITES();
    13251422    BODY_LOAD_TLB_AFTER_BRANCH(pTb, idxRange, cbInstr);
    13261423    BODY_CHECK_OPCODES(pTb, idxRange, offRange, cbInstr);
     
    13491446    //LogFunc(("idxRange=%u @ %#x LB %#x: offPhysPage=%#x LB %#x\n", idxRange, offRange, cbInstr, pTb->aRanges[idxRange].offPhysPage, pTb->aRanges[idxRange].cbOpcodes));
    13501447    BODY_SET_CUR_INSTR();
     1448    BODY_FLUSH_PENDING_WRITES();
    13511449    BODY_CONSIDER_CS_LIM_CHECKING(pTb, cbInstr);
    13521450    BODY_LOAD_TLB_AFTER_BRANCH(pTb, idxRange, cbInstr);
     
    13831481    uint32_t const idxRange2   = idxRange1 + 1;
    13841482    BODY_SET_CUR_INSTR();
     1483    BODY_FLUSH_PENDING_WRITES();
    13851484    BODY_CHECK_CS_LIM(cbInstr);
    13861485    BODY_CHECK_OPCODES(pTb, idxRange1, offRange1, cbInstr);
     
    14121511    uint32_t const idxRange2   = idxRange1 + 1;
    14131512    BODY_SET_CUR_INSTR();
     1513    BODY_FLUSH_PENDING_WRITES();
    14141514    BODY_CHECK_OPCODES(pTb, idxRange1, offRange1, cbInstr);
    14151515    BODY_LOAD_TLB_FOR_NEW_PAGE(pTb, cbStartPage, idxRange2, cbInstr);
     
    14411541    uint32_t const idxRange2   = idxRange1 + 1;
    14421542    BODY_SET_CUR_INSTR();
     1543    BODY_FLUSH_PENDING_WRITES();
    14431544    BODY_CONSIDER_CS_LIM_CHECKING(pTb, cbInstr);
    14441545    BODY_CHECK_OPCODES(pTb, idxRange1, offRange1, cbInstr);
     
    14681569    uint32_t const idxRange2   = idxRange1 + 1;
    14691570    BODY_SET_CUR_INSTR();
     1571    BODY_FLUSH_PENDING_WRITES();
    14701572    BODY_CHECK_CS_LIM(cbInstr);
    14711573    BODY_LOAD_TLB_FOR_NEW_PAGE(pTb, cbStartPage, idxRange2, cbInstr);
     
    14941596    uint32_t const idxRange2   = idxRange1 + 1;
    14951597    BODY_SET_CUR_INSTR();
     1598    BODY_FLUSH_PENDING_WRITES();
    14961599    BODY_LOAD_TLB_FOR_NEW_PAGE(pTb, cbStartPage, idxRange2, cbInstr);
    14971600    BODY_CHECK_OPCODES(pTb, idxRange2, 0, cbInstr);
     
    15191622    uint32_t const idxRange2   = idxRange1 + 1;
    15201623    BODY_SET_CUR_INSTR();
     1624    BODY_FLUSH_PENDING_WRITES();
    15211625    BODY_CONSIDER_CS_LIM_CHECKING(pTb, cbInstr);
    15221626    BODY_LOAD_TLB_FOR_NEW_PAGE(pTb, cbStartPage, idxRange2, cbInstr);
     
    15401644    uint32_t const idxRange    = (uint32_t)pCallEntry->auParams[1];
    15411645    BODY_SET_CUR_INSTR();
     1646    BODY_FLUSH_PENDING_WRITES();
    15421647    BODY_CHECK_CS_LIM(cbInstr);
    15431648    BODY_LOAD_TLB_FOR_NEW_PAGE(pTb, 0, idxRange, cbInstr);
     
    15621667    uint32_t const idxRange    = (uint32_t)pCallEntry->auParams[1];
    15631668    BODY_SET_CUR_INSTR();
     1669    BODY_FLUSH_PENDING_WRITES();
    15641670    BODY_LOAD_TLB_FOR_NEW_PAGE(pTb, 0, idxRange, cbInstr);
    15651671    //Assert(pVCpu->iem.s.offCurInstrStart == 0);
     
    15841690    uint32_t const idxRange    = (uint32_t)pCallEntry->auParams[1];
    15851691    BODY_SET_CUR_INSTR();
     1692    BODY_FLUSH_PENDING_WRITES();
    15861693    BODY_CONSIDER_CS_LIM_CHECKING(pTb, cbInstr);
    15871694    BODY_LOAD_TLB_FOR_NEW_PAGE(pTb, 0, idxRange, cbInstr);
  • trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp

    r102687 r102695  
    1121011210    static const char * const a_apszMarkers[] =
    1121111211    {
    11212         "unknown0", "CheckCsLim", "ConsiderLimChecking", "CheckOpcodes", "PcAfterBranch",
     11212        "unknown0", "CheckCsLim", "ConsiderLimChecking", "CheckOpcodes", "PcAfterBranch", "LoadTlbForNewPage"
    1121311213    };
    1121411214#endif
  • trunk/src/VBox/VMM/VMMAll/IEMAllThrdPython.py

    r102663 r102695  
    19771977        ( 'CheckPcAndOpcodesConsiderCsLim',                     3, True  ),
    19781978
    1979         ( 'CheckCsLimAndOpcodesAcrossPageLoadingTlb',           3, False ),
    1980         ( 'CheckOpcodesAcrossPageLoadingTlb',                   3, False ),
    1981         ( 'CheckOpcodesAcrossPageLoadingTlbConsiderCsLim',      2, False ),
     1979        ( 'CheckCsLimAndOpcodesAcrossPageLoadingTlb',           3, True ),
     1980        ( 'CheckOpcodesAcrossPageLoadingTlb',                   3, True ),
     1981        ( 'CheckOpcodesAcrossPageLoadingTlbConsiderCsLim',      2, True ),
    19821982
    19831983        ( 'CheckCsLimAndOpcodesLoadingTlb',                     3, False ),
     
    19851985        ( 'CheckOpcodesLoadingTlbConsiderCsLim',                3, False ),
    19861986
    1987         ( 'CheckCsLimAndOpcodesOnNextPageLoadingTlb',           2, False ),
    1988         ( 'CheckOpcodesOnNextPageLoadingTlb',                   2, False ),
    1989         ( 'CheckOpcodesOnNextPageLoadingTlbConsiderCsLim',      2, False ),
    1990 
    1991         ( 'CheckCsLimAndOpcodesOnNewPageLoadingTlb',            2, False ),
    1992         ( 'CheckOpcodesOnNewPageLoadingTlb',                    2, False ),
    1993         ( 'CheckOpcodesOnNewPageLoadingTlbConsiderCsLim',       2, False ),
     1987        ( 'CheckCsLimAndOpcodesOnNextPageLoadingTlb',           2, True ),
     1988        ( 'CheckOpcodesOnNextPageLoadingTlb',                   2, True ),
     1989        ( 'CheckOpcodesOnNextPageLoadingTlbConsiderCsLim',      2, True ),
     1990
     1991        ( 'CheckCsLimAndOpcodesOnNewPageLoadingTlb',            2, True ),
     1992        ( 'CheckOpcodesOnNewPageLoadingTlb',                    2, True ),
     1993        ( 'CheckOpcodesOnNewPageLoadingTlbConsiderCsLim',       2, True ),
    19941994    );
    19951995
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