VirtualBox

Changeset 105036 in vbox


Ignore:
Timestamp:
Jun 26, 2024 10:33:48 PM (9 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
163654
Message:

VMM/IEM: Split the TLB into non-global (even) and global (odd) entries, doubling it in size. In native code the global entries are only checked for ring-0 TBs, as checking both entries is slower than just the even one. bugref:10687

Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/vm.h

    r104947 r105036  
    159159        struct IEMCPU       s;
    160160#endif
    161         uint8_t             padding[131136]; /* multiple of 64 */
     161        uint8_t             padding[146240]; /* multiple of 64 */
    162162    } iem;
    163163
     
    316316
    317317    /** Align the following members on page boundary. */
    318     uint8_t                 abAlignment2[696];
     318    uint8_t                 abAlignment2[1976];
    319319
    320320    /** PGM part. */
     
    350350        uint8_t             padding[40960];     /* multiple of 4096 */
    351351    } em;
    352 
    353352    uint8_t abPadding[12288];
    354353} VMCPU;
  • trunk/include/VBox/vmm/vm.mac

    r104931 r105036  
    5858
    5959    alignb 64
    60     .iem                    resb 131136
     60    .iem                    resb 146240
    6161
    6262    alignb 64
  • trunk/src/VBox/VMM/VMMAll/IEMAll.cpp

    r104990 r105036  
    606606
    607607
     608#if defined(IEM_WITH_CODE_TLB) || defined(IEM_WITH_DATA_TLB)
     609/**
     610 * Worker for iemTlbInvalidateAll.
     611 */
     612template<bool a_fGlobal>
     613DECL_FORCE_INLINE(void) iemTlbInvalidateOne(IEMTLB *pTlb)
     614{
     615    if (!a_fGlobal)
     616        pTlb->cTlsFlushes++;
     617    else
     618        pTlb->cTlsGlobalFlushes++;
     619
     620    pTlb->uTlbRevision += IEMTLB_REVISION_INCR;
     621    if (RT_LIKELY(pTlb->uTlbRevision != 0))
     622    { /* very likely */ }
     623    else
     624    {
     625        pTlb->uTlbRevision = IEMTLB_REVISION_INCR;
     626        pTlb->cTlbRevisionRollovers++;
     627        unsigned i = RT_ELEMENTS(pTlb->aEntries) / 2;
     628        while (i-- > 0)
     629            pTlb->aEntries[i * 2].uTag = 0;
     630    }
     631    if (a_fGlobal)
     632    {
     633        pTlb->uTlbRevisionGlobal += IEMTLB_REVISION_INCR;
     634        if (RT_LIKELY(pTlb->uTlbRevisionGlobal != 0))
     635        { /* very likely */ }
     636        else
     637        {
     638            pTlb->uTlbRevisionGlobal = IEMTLB_REVISION_INCR;
     639            pTlb->cTlbRevisionRollovers++;
     640            unsigned i = RT_ELEMENTS(pTlb->aEntries) / 2;
     641            while (i-- > 0)
     642                pTlb->aEntries[i * 2 + 1].uTag = 0;
     643        }
     644    }
     645}
     646#endif
     647
     648
    608649/**
    609650 * Worker for IEMTlbInvalidateAll and IEMTlbInvalidateAllGlobal.
     
    614655#if defined(IEM_WITH_CODE_TLB) || defined(IEM_WITH_DATA_TLB)
    615656    Log10(("IEMTlbInvalidateAll\n"));
     657
    616658# ifdef IEM_WITH_CODE_TLB
    617659    pVCpu->iem.s.cbInstrBufTotal = 0;
    618     if (!a_fGlobal)
    619         pVCpu->iem.s.CodeTlb.cTlsFlushes++;
    620     else
    621         pVCpu->iem.s.CodeTlb.cTlsGlobalFlushes++;
    622     pVCpu->iem.s.CodeTlb.uTlbRevision += IEMTLB_REVISION_INCR;
    623     if (RT_LIKELY(pVCpu->iem.s.CodeTlb.uTlbRevision != 0))
    624     { /* very likely */ }
    625     else
    626     {
    627         pVCpu->iem.s.CodeTlb.uTlbRevision = IEMTLB_REVISION_INCR;
    628         pVCpu->iem.s.CodeTlb.cTlbRevisionRollovers++;
    629         unsigned i = RT_ELEMENTS(pVCpu->iem.s.CodeTlb.aEntries);
    630         while (i-- > 0)
    631             pVCpu->iem.s.CodeTlb.aEntries[i].uTag = 0;
    632     }
     660    iemTlbInvalidateOne<a_fGlobal>(&pVCpu->iem.s.CodeTlb);
    633661# endif
    634662
    635663# ifdef IEM_WITH_DATA_TLB
    636     if (!a_fGlobal)
    637         pVCpu->iem.s.DataTlb.cTlsFlushes++;
    638     else
    639         pVCpu->iem.s.DataTlb.cTlsGlobalFlushes++;
    640     pVCpu->iem.s.DataTlb.uTlbRevision += IEMTLB_REVISION_INCR;
    641     if (pVCpu->iem.s.DataTlb.uTlbRevision != 0)
    642     { /* very likely */ }
    643     else
    644     {
    645         pVCpu->iem.s.DataTlb.uTlbRevision = IEMTLB_REVISION_INCR;
    646         pVCpu->iem.s.DataTlb.cTlbRevisionRollovers++;
    647         unsigned i = RT_ELEMENTS(pVCpu->iem.s.DataTlb.aEntries);
    648         while (i-- > 0)
    649             pVCpu->iem.s.DataTlb.aEntries[i].uTag = 0;
    650     }
     664    iemTlbInvalidateOne<a_fGlobal>(&pVCpu->iem.s.DataTlb);
    651665# endif
    652666#else
     
    698712    GCPtr = IEMTLB_CALC_TAG_NO_REV(GCPtr);
    699713    Assert(!(GCPtr >> (48 - X86_PAGE_SHIFT)));
    700     uintptr_t const idx = IEMTLB_TAG_TO_INDEX(GCPtr);
     714    uintptr_t const idxEven = IEMTLB_TAG_TO_EVEN_INDEX(GCPtr);
    701715
    702716# ifdef IEM_WITH_CODE_TLB
    703     if (pVCpu->iem.s.CodeTlb.aEntries[idx].uTag == (GCPtr | pVCpu->iem.s.CodeTlb.uTlbRevision))
    704     {
    705         pVCpu->iem.s.CodeTlb.aEntries[idx].uTag = 0;
     717    if (pVCpu->iem.s.CodeTlb.aEntries[idxEven].uTag == (GCPtr | pVCpu->iem.s.CodeTlb.uTlbRevision))
     718    {
     719        pVCpu->iem.s.CodeTlb.aEntries[idxEven].uTag = 0;
    706720        if (GCPtr == IEMTLB_CALC_TAG_NO_REV(pVCpu->iem.s.uInstrBufPc))
    707721            pVCpu->iem.s.cbInstrBufTotal = 0;
    708722    }
     723    if (pVCpu->iem.s.CodeTlb.aEntries[idxEven + 1].uTag == (GCPtr | pVCpu->iem.s.CodeTlb.uTlbRevisionGlobal))
     724    {
     725        pVCpu->iem.s.CodeTlb.aEntries[idxEven + 1].uTag = 0;
     726        if (GCPtr == IEMTLB_CALC_TAG_NO_REV(pVCpu->iem.s.uInstrBufPc))
     727            pVCpu->iem.s.cbInstrBufTotal = 0;
     728    }
    709729# endif
    710730
    711731# ifdef IEM_WITH_DATA_TLB
    712     if (pVCpu->iem.s.DataTlb.aEntries[idx].uTag == (GCPtr | pVCpu->iem.s.DataTlb.uTlbRevision))
    713         pVCpu->iem.s.DataTlb.aEntries[idx].uTag = 0;
     732    if (pVCpu->iem.s.DataTlb.aEntries[idxEven].uTag == (GCPtr | pVCpu->iem.s.DataTlb.uTlbRevision))
     733        pVCpu->iem.s.DataTlb.aEntries[idxEven].uTag = 0;
     734    if (pVCpu->iem.s.DataTlb.aEntries[idxEven + 1].uTag == (GCPtr | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal))
     735        pVCpu->iem.s.DataTlb.aEntries[idxEven + 1].uTag = 0;
    714736# endif
    715737#else
     
    974996         * Get the TLB entry for this piece of code.
    975997         */
    976         uint64_t const     uTag  = IEMTLB_CALC_TAG(    &pVCpu->iem.s.CodeTlb, GCPtrFirst);
    977         PIEMTLBENTRY const pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.CodeTlb, uTag);
    978         if (pTlbe->uTag == uTag)
     998        uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrFirst);
     999        PIEMTLBENTRY   pTlbe     = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.CodeTlb, uTagNoRev);
     1000        if (   pTlbe->uTag               == (uTagNoRev | pVCpu->iem.s.CodeTlb.uTlbRevision)
     1001            || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.CodeTlb.uTlbRevisionGlobal))
    9791002        {
    9801003            /* likely when executing lots of code, otherwise unlikely */
     
    10381061
    10391062            AssertCompile(IEMTLBE_F_PT_NO_EXEC == 1);
    1040             pTlbe->uTag             = uTag;
     1063            if (   !(WalkFast.fEffective & PGM_PTATTRS_G_MASK)
     1064                || IEM_GET_CPL(pVCpu) != 0) /* optimization: Only use the PTE.G=1 entries in ring-0. */
     1065            {
     1066                pTlbe--;
     1067                pTlbe->uTag         = uTagNoRev | pVCpu->iem.s.CodeTlb.uTlbRevision;
     1068            }
     1069            else
     1070            {
     1071                pVCpu->iem.s.CodeTlb.cTlbCoreGlobalLoads++;
     1072                pTlbe->uTag         = uTagNoRev | pVCpu->iem.s.CodeTlb.uTlbRevisionGlobal;
     1073            }
    10411074            pTlbe->fFlagsAndPhysRev = (~WalkFast.fEffective & (X86_PTE_US | X86_PTE_RW | X86_PTE_D | X86_PTE_A))
    10421075                                    | (WalkFast.fEffective >> X86_PTE_PAE_BIT_NX) /*IEMTLBE_F_PT_NO_EXEC*/;
     
    63816414     * should in theory always be set).
    63826415     */
    6383     uint8_t           *pbMem = NULL;
    6384     uint64_t const     uTag  = IEMTLB_CALC_TAG(    &pVCpu->iem.s.DataTlb, GCPtrMem);
    6385     PIEMTLBENTRY const pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag);
    6386     if (   pTlbe->uTag == uTag
    6387         && !(pTlbe->fFlagsAndPhysRev & (IEMTLBE_F_PT_NO_ACCESSED | (fAccess & IEM_ACCESS_TYPE_WRITE ? IEMTLBE_F_PT_NO_DIRTY : 0))) )
     6416    uint8_t           *pbMem     = NULL;
     6417    uint64_t const     uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrMem);
     6418    PIEMTLBENTRY       pTlbe     = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev);
     6419    uint64_t const     fTlbeAD   = IEMTLBE_F_PT_NO_ACCESSED | (fAccess & IEM_ACCESS_TYPE_WRITE ? IEMTLBE_F_PT_NO_DIRTY : 0);
     6420    if (   (   pTlbe->uTag               == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision)
     6421            && !(pTlbe->fFlagsAndPhysRev & fTlbeAD) )
     6422        || (   (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal)
     6423            && !(pTlbe->fFlagsAndPhysRev & fTlbeAD) ) )
    63886424    {
    63896425# ifdef IEM_WITH_TLB_STATISTICS
     
    64686504        }
    64696505
    6470         pTlbe->uTag             = uTag;
     6506        if (   !(WalkFast.fEffective & PGM_PTATTRS_G_MASK)
     6507            || IEM_GET_CPL(pVCpu) != 0) /* optimization: Only use the PTE.G=1 entries in ring-0. */
     6508        {
     6509            pTlbe--;
     6510            pTlbe->uTag         = uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision;
     6511        }
     6512        else
     6513        {
     6514            pVCpu->iem.s.DataTlb.cTlbCoreGlobalLoads++;
     6515            pTlbe->uTag         = uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal;
     6516        }
    64716517        pTlbe->fFlagsAndPhysRev = ~WalkFast.fEffective & (X86_PTE_US | X86_PTE_RW | X86_PTE_D | X86_PTE_A); /* skipping NX */
    64726518        RTGCPHYS const GCPhysPg = WalkFast.GCPhys & ~(RTGCPHYS)GUEST_PAGE_OFFSET_MASK;
     
    67856831                                        : 0;
    67866832    uint64_t const     fNoRead          = fAccess & IEM_ACCESS_TYPE_READ ? IEMTLBE_F_PG_NO_READ : 0;
    6787 
    6788     uint64_t const     uTag  = IEMTLB_CALC_TAG(    &pVCpu->iem.s.DataTlb, GCPtrMem);
    6789     PIEMTLBENTRY const pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag);
    6790     if (   pTlbe->uTag == uTag
    6791         && !(pTlbe->fFlagsAndPhysRev & (IEMTLBE_F_PT_NO_ACCESSED | (fNoWriteNoDirty & IEMTLBE_F_PT_NO_DIRTY))) )
     6833    uint64_t const     uTagNoRev        = IEMTLB_CALC_TAG_NO_REV(GCPtrMem);
     6834    PIEMTLBENTRY       pTlbe            = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev);
     6835    uint64_t const     fTlbeAD          = IEMTLBE_F_PT_NO_ACCESSED | (fNoWriteNoDirty & IEMTLBE_F_PT_NO_DIRTY);
     6836    if (   (   pTlbe->uTag               == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision)
     6837            && !(pTlbe->fFlagsAndPhysRev & fTlbeAD) )
     6838        || (   (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal)
     6839            && !(pTlbe->fFlagsAndPhysRev & fTlbeAD) ) )
    67926840    {
    67936841# ifdef IEM_WITH_TLB_STATISTICS
     
    68316879        }
    68326880
    6833         pTlbe->uTag             = uTag;
     6881        if (   !(WalkFast.fEffective & PGM_PTATTRS_G_MASK)
     6882            || IEM_GET_CPL(pVCpu) != 0) /* optimization: Only use the PTE.G=1 entries in ring-0. */
     6883        {
     6884            pTlbe--;
     6885            pTlbe->uTag         = uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision;
     6886        }
     6887        else
     6888        {
     6889            if (a_fSafeCall)
     6890                pVCpu->iem.s.DataTlb.cTlbSafeGlobalLoads++;
     6891            else
     6892                pVCpu->iem.s.DataTlb.cTlbCoreGlobalLoads++;
     6893            pTlbe->uTag         = uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal;
     6894        }
    68346895        pTlbe->fFlagsAndPhysRev = ~WalkFast.fEffective & (X86_PTE_US | X86_PTE_RW | X86_PTE_D | X86_PTE_A); /* skipping NX */
    68356896        RTGCPHYS const GCPhysPg = WalkFast.GCPhys & ~(RTGCPHYS)GUEST_PAGE_OFFSET_MASK;
  • trunk/src/VBox/VMM/VMMAll/IEMAllMemRWTmplInline.cpp.h

    r104956 r105036  
    111111         * TLB lookup.
    112112         */
    113         uint64_t const uTag  = IEMTLB_CALC_TAG(    &pVCpu->iem.s.DataTlb, GCPtrEff);
    114         PIEMTLBENTRY   pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag);
    115         if (RT_LIKELY(pTlbe->uTag == uTag))
     113        uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrEff);
     114        PCIEMTLBENTRY  pTlbe     = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev);
     115        if (RT_LIKELY(   pTlbe->uTag               == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision)
     116                      || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal)))
    116117        {
    117118            /*
     
    184185         * TLB lookup.
    185186         */
    186         uint64_t const uTag  = IEMTLB_CALC_TAG(    &pVCpu->iem.s.DataTlb, GCPtrMem);
    187         PIEMTLBENTRY   pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag);
    188         if (RT_LIKELY(pTlbe->uTag == uTag))
     187        uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrMem);
     188        PCIEMTLBENTRY  pTlbe     = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev);
     189        if (RT_LIKELY(   pTlbe->uTag               == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision)
     190                      || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal)))
    189191        {
    190192            /*
     
    261263         * TLB lookup.
    262264         */
    263         uint64_t const uTag  = IEMTLB_CALC_TAG(    &pVCpu->iem.s.DataTlb, GCPtrEff);
    264         PIEMTLBENTRY   pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag);
    265         if (RT_LIKELY(pTlbe->uTag == uTag))
     265        uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrEff);
     266        PCIEMTLBENTRY  pTlbe     = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev);
     267        if (RT_LIKELY(   pTlbe->uTag               == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision)
     268                      || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal)))
    266269        {
    267270            /*
     
    334337         * TLB lookup.
    335338         */
    336         uint64_t const uTag  = IEMTLB_CALC_TAG(    &pVCpu->iem.s.DataTlb, GCPtrMem);
    337         PIEMTLBENTRY   pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag);
    338         if (RT_LIKELY(pTlbe->uTag == uTag))
     339        uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrMem);
     340        PCIEMTLBENTRY  pTlbe     = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev);
     341        if (RT_LIKELY(   pTlbe->uTag               == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision)
     342                      || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal)))
    339343        {
    340344            /*
     
    409413         * TLB lookup.
    410414         */
    411         uint64_t const uTag  = IEMTLB_CALC_TAG(    &pVCpu->iem.s.DataTlb, GCPtrEff);
    412         PIEMTLBENTRY   pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag);
    413         if (RT_LIKELY(pTlbe->uTag == uTag))
     415        uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrEff);
     416        PCIEMTLBENTRY  pTlbe     = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev);
     417        if (RT_LIKELY(   pTlbe->uTag               == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision)
     418                      || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal)))
    414419        {
    415420            /*
     
    468473         * TLB lookup.
    469474         */
    470         uint64_t const uTag  = IEMTLB_CALC_TAG(    &pVCpu->iem.s.DataTlb, GCPtrMem);
    471         PIEMTLBENTRY   pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag);
    472         if (RT_LIKELY(pTlbe->uTag == uTag))
     475        uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrMem);
     476        PCIEMTLBENTRY  pTlbe     = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev);
     477        if (RT_LIKELY(   pTlbe->uTag               == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision)
     478                      || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal)))
    473479        {
    474480            /*
     
    529535         * TLB lookup.
    530536         */
    531         uint64_t const uTag  = IEMTLB_CALC_TAG(    &pVCpu->iem.s.DataTlb, GCPtrEff);
    532         PIEMTLBENTRY   pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag);
    533         if (RT_LIKELY(pTlbe->uTag == uTag))
     537        uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrEff);
     538        PCIEMTLBENTRY  pTlbe     = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev);
     539        if (RT_LIKELY(   pTlbe->uTag               == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision)
     540                      || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal)))
    534541        {
    535542            /*
     
    588595         * TLB lookup.
    589596         */
    590         uint64_t const uTag  = IEMTLB_CALC_TAG(    &pVCpu->iem.s.DataTlb, GCPtrMem);
    591         PIEMTLBENTRY   pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag);
    592         if (RT_LIKELY(pTlbe->uTag == uTag))
     597        uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrMem);
     598        PCIEMTLBENTRY  pTlbe     = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev);
     599        if (RT_LIKELY(   pTlbe->uTag               == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision)
     600                      || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal)))
    593601        {
    594602            /*
     
    647655         * TLB lookup.
    648656         */
    649         uint64_t const uTag  = IEMTLB_CALC_TAG(    &pVCpu->iem.s.DataTlb, GCPtrEff);
    650         PIEMTLBENTRY   pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag);
    651         if (RT_LIKELY(pTlbe->uTag == uTag))
     657        uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrEff);
     658        PCIEMTLBENTRY  pTlbe     = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev);
     659        if (RT_LIKELY(   pTlbe->uTag               == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision)
     660                      || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal)))
    652661        {
    653662            /*
     
    704713         * TLB lookup.
    705714         */
    706         uint64_t const uTag  = IEMTLB_CALC_TAG(    &pVCpu->iem.s.DataTlb, GCPtrMem);
    707         PIEMTLBENTRY   pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag);
    708         if (RT_LIKELY(pTlbe->uTag == uTag))
     715        uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrMem);
     716        PCIEMTLBENTRY  pTlbe     = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev);
     717        if (RT_LIKELY(   pTlbe->uTag               == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision)
     718                      || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal)))
    709719        {
    710720            /*
     
    762772         * TLB lookup.
    763773         */
    764         uint64_t const uTag  = IEMTLB_CALC_TAG(    &pVCpu->iem.s.DataTlb, GCPtrEff);
    765         PIEMTLBENTRY   pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag);
    766         if (RT_LIKELY(pTlbe->uTag == uTag))
     774        uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrEff);
     775        PCIEMTLBENTRY  pTlbe     = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev);
     776        if (RT_LIKELY(   pTlbe->uTag               == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision)
     777                      || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal)))
    767778        {
    768779            /*
     
    818829         * TLB lookup.
    819830         */
    820         uint64_t const uTag  = IEMTLB_CALC_TAG(    &pVCpu->iem.s.DataTlb, GCPtrMem);
    821         PIEMTLBENTRY   pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag);
    822         if (RT_LIKELY(pTlbe->uTag == uTag))
     831        uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrMem);
     832        PCIEMTLBENTRY  pTlbe     = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev);
     833        if (RT_LIKELY(   pTlbe->uTag               == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision)
     834                      || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal)))
    823835        {
    824836            /*
     
    888900         * TLB lookup.
    889901         */
    890         uint64_t const uTag  = IEMTLB_CALC_TAG(    &pVCpu->iem.s.DataTlb, GCPtrEff);
    891         PIEMTLBENTRY   pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag);
    892         if (RT_LIKELY(pTlbe->uTag == uTag))
     902        uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrEff);
     903        PCIEMTLBENTRY  pTlbe     = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev);
     904        if (RT_LIKELY(   pTlbe->uTag               == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision)
     905                      || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal)))
    893906        {
    894907            /*
     
    951964         * TLB lookup.
    952965         */
    953         uint64_t const uTag  = IEMTLB_CALC_TAG(    &pVCpu->iem.s.DataTlb, GCPtrEff);
    954         PIEMTLBENTRY   pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag);
    955         if (RT_LIKELY(pTlbe->uTag == uTag))
     966        uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrEff);
     967        PCIEMTLBENTRY  pTlbe     = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev);
     968        if (RT_LIKELY(   pTlbe->uTag               == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision)
     969                      || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal)))
    956970        {
    957971            /*
     
    10141028         * TLB lookup.
    10151029         */
    1016         uint64_t const uTag  = IEMTLB_CALC_TAG(    &pVCpu->iem.s.DataTlb, GCPtrMem);
    1017         PIEMTLBENTRY   pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag);
    1018         if (RT_LIKELY(pTlbe->uTag == uTag))
     1030        uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrMem);
     1031        PCIEMTLBENTRY  pTlbe     = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev);
     1032        if (RT_LIKELY(   pTlbe->uTag               == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision)
     1033                      || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal)))
    10191034        {
    10201035            /*
     
    10731088         * TLB lookup.
    10741089         */
    1075         uint64_t const uTag  = IEMTLB_CALC_TAG(    &pVCpu->iem.s.DataTlb, GCPtrMem);
    1076         PIEMTLBENTRY   pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag);
    1077         if (RT_LIKELY(pTlbe->uTag == uTag))
     1090        uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrMem);
     1091        PCIEMTLBENTRY  pTlbe     = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev);
     1092        if (RT_LIKELY(   pTlbe->uTag               == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision)
     1093                      || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal)))
    10781094        {
    10791095            /*
     
    11321148         * TLB lookup.
    11331149         */
    1134         uint64_t const uTag  = IEMTLB_CALC_TAG(    &pVCpu->iem.s.DataTlb, GCPtrEff);
    1135         PIEMTLBENTRY   pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag);
    1136         if (RT_LIKELY(pTlbe->uTag == uTag))
     1150        uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrEff);
     1151        PCIEMTLBENTRY  pTlbe     = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev);
     1152        if (RT_LIKELY(   pTlbe->uTag               == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision)
     1153                      || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal)))
    11371154        {
    11381155            /*
     
    11861203         * TLB lookup.
    11871204         */
    1188         uint64_t const uTag  = IEMTLB_CALC_TAG(    &pVCpu->iem.s.DataTlb, GCPtrMem);
    1189         PIEMTLBENTRY   pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag);
    1190         if (RT_LIKELY(pTlbe->uTag == uTag))
     1205        uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrMem);
     1206        PCIEMTLBENTRY  pTlbe     = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev);
     1207        if (RT_LIKELY(   pTlbe->uTag               == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision)
     1208                      || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal)))
    11911209        {
    11921210            /*
     
    12441262         * TLB lookup.
    12451263         */
    1246         uint64_t const uTag  = IEMTLB_CALC_TAG(    &pVCpu->iem.s.DataTlb, GCPtrEff);
    1247         PIEMTLBENTRY   pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag);
    1248         if (RT_LIKELY(pTlbe->uTag == uTag))
     1264        uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrEff);
     1265        PCIEMTLBENTRY  pTlbe     = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev);
     1266        if (RT_LIKELY(   pTlbe->uTag               == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision)
     1267                      || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal)))
    12491268        {
    12501269            /*
     
    13071326         * TLB lookup.
    13081327         */
    1309         uint64_t const uTag  = IEMTLB_CALC_TAG(    &pVCpu->iem.s.DataTlb, GCPtrEff);
    1310         PIEMTLBENTRY   pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag);
    1311         if (RT_LIKELY(pTlbe->uTag == uTag))
     1328        uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrEff);
     1329        PCIEMTLBENTRY  pTlbe     = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev);
     1330        if (RT_LIKELY(   pTlbe->uTag               == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision)
     1331                      || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal)))
    13121332        {
    13131333            /*
     
    13841404         * TLB lookup.
    13851405         */
    1386         uint64_t const uTag  = IEMTLB_CALC_TAG(    &pVCpu->iem.s.DataTlb, GCPtrEff);
    1387         PIEMTLBENTRY   pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag);
    1388         if (RT_LIKELY(pTlbe->uTag == uTag))
     1406        uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrEff);
     1407        PCIEMTLBENTRY  pTlbe     = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev);
     1408        if (RT_LIKELY(   pTlbe->uTag               == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision)
     1409                      || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal)))
    13891410        {
    13901411            /*
     
    14661487         * TLB lookup.
    14671488         */
    1468         uint64_t const uTag  = IEMTLB_CALC_TAG(    &pVCpu->iem.s.DataTlb, (RTGCPTR)uNewEsp); /* Doesn't work w/o casting to RTGCPTR (win /3 hangs). */
    1469         PIEMTLBENTRY   pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag);
    1470         if (RT_LIKELY(pTlbe->uTag == uTag))
     1489        uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV((RTGCPTR)uNewEsp); /* Doesn't work w/o casting to RTGCPTR (win /3 hangs). */
     1490        PCIEMTLBENTRY  pTlbe     = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev);
     1491        if (RT_LIKELY(   pTlbe->uTag               == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision)
     1492                      || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal)))
    14711493        {
    14721494            /*
     
    15251547         * TLB lookup.
    15261548         */
    1527         uint64_t const uTag  = IEMTLB_CALC_TAG(    &pVCpu->iem.s.DataTlb, (RTGCPTR)uOldEsp); /* Cast is required! 2023-08-11 */
    1528         PIEMTLBENTRY   pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag);
    1529         if (RT_LIKELY(pTlbe->uTag == uTag))
     1549        uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV((RTGCPTR)uOldEsp); /* Cast is required! 2023-08-11 */
     1550        PCIEMTLBENTRY  pTlbe     = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev);
     1551        if (RT_LIKELY(   pTlbe->uTag               == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision)
     1552                      || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal)))
    15301553        {
    15311554            /*
     
    15991622         * TLB lookup.
    16001623         */
    1601         uint64_t const uTag  = IEMTLB_CALC_TAG(    &pVCpu->iem.s.DataTlb, (RTGCPTR)uNewEsp); /* Doesn't work w/o casting to RTGCPTR (win /3 hangs). */
    1602         PIEMTLBENTRY   pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag);
    1603         if (RT_LIKELY(pTlbe->uTag == uTag))
     1624        uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV((RTGCPTR)uNewEsp); /* Doesn't work w/o casting to RTGCPTR (win /3 hangs). */
     1625        PCIEMTLBENTRY  pTlbe     = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev);
     1626        if (RT_LIKELY(   pTlbe->uTag               == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision)
     1627                      || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal)))
    16041628        {
    16051629            /*
     
    16771701         * TLB lookup.
    16781702         */
    1679         uint64_t const uTag  = IEMTLB_CALC_TAG(    &pVCpu->iem.s.DataTlb, uNewRsp);
    1680         PIEMTLBENTRY   pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag);
    1681         if (RT_LIKELY(pTlbe->uTag == uTag))
     1703        uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(uNewRsp);
     1704        PCIEMTLBENTRY  pTlbe     = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev);
     1705        if (RT_LIKELY(   pTlbe->uTag               == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision)
     1706                      || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal)))
    16821707        {
    16831708            /*
     
    17361761         * TLB lookup.
    17371762         */
    1738         uint64_t const uTag  = IEMTLB_CALC_TAG(    &pVCpu->iem.s.DataTlb, uOldRsp);
    1739         PIEMTLBENTRY   pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag);
    1740         if (RT_LIKELY(pTlbe->uTag == uTag))
     1763        uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(uOldRsp);
     1764        PCIEMTLBENTRY  pTlbe     = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev);
     1765        if (RT_LIKELY(   pTlbe->uTag               == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision)
     1766                      || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal)))
    17411767        {
    17421768            /*
  • trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp

    r105035 r105036  
    85338533    /* Do the lookup manually. */
    85348534    RTGCPTR const      GCPtrFlat = iSegReg == UINT8_MAX ? GCPtr : GCPtr + pVCpu->cpum.GstCtx.aSRegs[iSegReg].u64Base;
    8535     uint64_t const     uTag      = IEMTLB_CALC_TAG(    &pVCpu->iem.s.DataTlb, GCPtrFlat);
    8536     PIEMTLBENTRY const pTlbe     = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag);
    8537     if (RT_LIKELY(pTlbe->uTag == uTag))
     8535    uint64_t const     uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrFlat);
     8536    PCIEMTLBENTRY      pTlbe     = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev);
     8537    if (RT_LIKELY(   pTlbe->uTag               == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision)
     8538                  || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal)))
    85388539    {
    85398540        /*
  • trunk/src/VBox/VMM/VMMR3/IEMR3.cpp

    r104990 r105036  
    201201        AssertCompile(sizeof(pVCpu->iem.s) <= sizeof(pVCpu->iem.padding)); /* (tstVMStruct can't do it's job w/o instruction stats) */
    202202
    203         pVCpu->iem.s.CodeTlb.uTlbRevision = pVCpu->iem.s.DataTlb.uTlbRevision = uInitialTlbRevision;
    204         pVCpu->iem.s.CodeTlb.uTlbPhysRev  = pVCpu->iem.s.DataTlb.uTlbPhysRev  = uInitialTlbPhysRev;
     203        pVCpu->iem.s.CodeTlb.uTlbRevision       = pVCpu->iem.s.DataTlb.uTlbRevision       = uInitialTlbRevision;
     204#ifndef VBOX_VMM_TARGET_ARMV8
     205        pVCpu->iem.s.CodeTlb.uTlbRevisionGlobal = pVCpu->iem.s.DataTlb.uTlbRevisionGlobal = uInitialTlbRevision;
     206#endif
     207        pVCpu->iem.s.CodeTlb.uTlbPhysRev        = pVCpu->iem.s.DataTlb.uTlbPhysRev        = uInitialTlbPhysRev;
    205208
    206209        /*
     
    323326        /* Code TLB: */
    324327        STAMR3RegisterF(pVM, &pVCpu->iem.s.CodeTlb.uTlbRevision,        STAMTYPE_X64,       STAMVISIBILITY_ALWAYS, STAMUNIT_NONE,
    325                         "Code TLB revision",                            "/IEM/CPU%u/Tlb/Code/Revision", idCpu);
     328                        "Code TLB non-global revision",                 "/IEM/CPU%u/Tlb/Code/RevisionNonGlobal", idCpu);
     329        STAMR3RegisterF(pVM, &pVCpu->iem.s.CodeTlb.uTlbRevisionGlobal,  STAMTYPE_X64,       STAMVISIBILITY_ALWAYS, STAMUNIT_NONE,
     330                        "Code TLB global revision",                     "/IEM/CPU%u/Tlb/Code/RevisionGlobal", idCpu);
    326331        STAMR3RegisterF(pVM, &pVCpu->iem.s.CodeTlb.cTlsFlushes,         STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE,
    327332                        "Code TLB non-global flushes",                  "/IEM/CPU%u/Tlb/Code/RevisionNonGlobalFlushes", idCpu);
     
    340345        STAMR3RegisterF(pVM, &pVCpu->iem.s.CodeTlb.cTlbCoreMisses,      STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
    341346                        "Code TLB misses",                              "/IEM/CPU%u/Tlb/Code/Misses", idCpu);
     347        STAMR3RegisterF(pVM, &pVCpu->iem.s.CodeTlb.cTlbCoreGlobalLoads, STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
     348                        "Code TLB global loads",                        "/IEM/CPU%u/Tlb/Code/Misses/GlobalLoads", idCpu);
    342349        STAMR3RegisterF(pVM, &pVCpu->iem.s.CodeTlb.cTlbSlowCodeReadPath, STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
    343350                        "Code TLB slow read path",                      "/IEM/CPU%u/Tlb/Code/SlowReads", idCpu);
     
    393400        /* Data TLB organized as best we can... */
    394401        STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.uTlbRevision,        STAMTYPE_X64,       STAMVISIBILITY_ALWAYS, STAMUNIT_NONE,
    395                         "Data TLB revision",                            "/IEM/CPU%u/Tlb/Data/Revision", idCpu);
     402                        "Data TLB non-global revision",                 "/IEM/CPU%u/Tlb/Data/RevisionNonGlobal", idCpu);
     403        STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.uTlbRevisionGlobal,  STAMTYPE_X64,       STAMVISIBILITY_ALWAYS, STAMUNIT_NONE,
     404                        "Data TLB global revision",                     "/IEM/CPU%u/Tlb/Data/RevisionGlobal", idCpu);
    396405        STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.cTlsFlushes,         STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE,
    397406                        "Data TLB non-global flushes",                  "/IEM/CPU%u/Tlb/Data/RevisionNonGlobalFlushes", idCpu);
     
    411420                        "Data TLB core misses (iemMemMap, direct iemMemMapJmp (not safe path))",
    412421                        "/IEM/CPU%u/Tlb/Data/Misses/Core", idCpu);
     422        STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.cTlbCoreGlobalLoads, STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
     423                        "Data TLB global loads",
     424                        "/IEM/CPU%u/Tlb/Data/Misses/Core/GlobalLoads", idCpu);
    413425        STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.cTlbSafeReadPath,    STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
    414426                        "Data TLB safe read path (inline/native misses going to iemMemMapJmp)",
     
    430442                        "Data TLB misses in iemMemMapJmp - not part of safe-path total",
    431443                        "/IEM/CPU%u/Tlb/Data/Misses/Safe/SubPartMisses", idCpu);
     444        STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.cTlbSafeGlobalLoads, STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
     445                        "Data TLB global loads",
     446                        "/IEM/CPU%u/Tlb/Data/Misses/Safe/SubPartMisses/GlobalLoads", idCpu);
    432447
    433448# ifdef IEM_WITH_TLB_STATISTICS
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r104990 r105036  
    495495/** Pointer to an IEM TLB entry. */
    496496typedef IEMTLBENTRY *PIEMTLBENTRY;
     497/** Pointer to a const IEM TLB entry. */
     498typedef IEMTLBENTRY const *PCIEMTLBENTRY;
    497499
    498500/** @name IEMTLBE_F_XXX - TLB entry flags (IEMTLBENTRY::fFlagsAndPhysRev)
     
    538540typedef struct IEMTLB
    539541{
    540     /** The TLB revision.
     542    /** The non-global TLB revision.
    541543     * This is actually only 28 bits wide (see IEMTLBENTRY::uTag) and is incremented
    542544     * by adding RT_BIT_64(36) to it.  When it wraps around and becomes zero, all
     
    553555     * as IEMTLBENTRY::fFlagsAndPhysRev bits 63 thru 8, 4, and 3.
    554556     *
    555      * The initial value is choosen to cause an early wraparound. */
     557     * The initial value is choosen to cause an early wraparound.
     558     *
     559     * @note This is placed between the two TLB revisions because we
     560     *       load it in pair with one or the other on arm64. */
    556561    uint64_t volatile   uTlbPhysRev;
     562    /** The global TLB revision.
     563     * Same as uTlbRevision, but only increased for global flushes. */
     564    uint64_t            uTlbRevisionGlobal;
    557565
    558566    /* Statistics: */
     
    574582     *       TLB is all misses. */
    575583    uint64_t            cTlbCoreMisses;
     584    /** Subset of cTlbCoreMisses that results in PTE.G=1 loads (odd entries). */
     585    uint64_t            cTlbCoreGlobalLoads;
    576586    /** Safe read/write TLB misses in iemMemMapJmp (so data only). */
    577587    uint64_t            cTlbSafeMisses;
     588    /** Subset of cTlbSafeMisses that results in PTE.G=1 loads (odd entries). */
     589    uint64_t            cTlbSafeGlobalLoads;
    578590    /** Safe read path taken (data only).  */
    579591    uint64_t            cTlbSafeReadPath;
     
    611623    uint32_t            cTlbPhysRevRollovers;
    612624
    613     /** The TLB entries. */
    614     IEMTLBENTRY         aEntries[IEMTLB_ENTRY_COUNT];
     625    uint32_t            au32Padding[10];
     626
     627    /** The TLB entries.
     628     * Even entries are for PTE.G=0 and uses uTlbRevision.
     629     * Odd  entries are for PTE.G=1 and uses uTlbRevisionGlobal. */
     630    IEMTLBENTRY         aEntries[IEMTLB_ENTRY_COUNT * 2];
    615631} IEMTLB;
    616632AssertCompileSizeAlignment(IEMTLB, 64);
     
    623639#define IEMTLB_PHYS_REV_INCR    RT_BIT_64(10)
    624640/**
    625  * Calculates the TLB tag for a virtual address.
    626  * @returns Tag value for indexing and comparing with IEMTLB::uTag.
    627  * @param   a_pTlb      The TLB.
    628  * @param   a_GCPtr     The virtual address.  Must be RTGCPTR or same size or
    629  *                      the clearing of the top 16 bits won't work (if 32-bit
    630  *                      we'll end up with mostly zeros).
    631  */
    632 #define IEMTLB_CALC_TAG(a_pTlb, a_GCPtr)    ( IEMTLB_CALC_TAG_NO_REV(a_GCPtr) | (a_pTlb)->uTlbRevision )
    633 /**
    634641 * Calculates the TLB tag for a virtual address but without TLB revision.
    635642 * @returns Tag value for indexing and comparing with IEMTLB::uTag.
     
    640647#define IEMTLB_CALC_TAG_NO_REV(a_GCPtr)     ( (((a_GCPtr) << 16) >> (GUEST_PAGE_SHIFT + 16)) )
    641648/**
    642  * Converts a TLB tag value into a TLB index.
     649 * Converts a TLB tag value into a even TLB index.
    643650 * @returns Index into IEMTLB::aEntries.
    644651 * @param   a_uTag      Value returned by IEMTLB_CALC_TAG.
    645652 */
    646653#if IEMTLB_ENTRY_COUNT == 256
    647 # define IEMTLB_TAG_TO_INDEX(a_uTag)        ( (uint8_t)(a_uTag) )
     654# define IEMTLB_TAG_TO_EVEN_INDEX(a_uTag)   ( (uint8_t)(a_uTag) * 2U )
    648655#else
    649 # define IEMTLB_TAG_TO_INDEX(a_uTag)        ( (a_uTag) & (IEMTLB_ENTRY_COUNT - 1U) )
     656# define IEMTLB_TAG_TO_EVEN_INDEX(a_uTag)   ( ((a_uTag) & (IEMTLB_ENTRY_COUNT - 1U)) * 2U )
    650657AssertCompile(RT_IS_POWER_OF_TWO(IEMTLB_ENTRY_COUNT));
    651658#endif
    652659/**
    653  * Converts a TLB tag value into a TLB index.
    654  * @returns Index into IEMTLB::aEntries.
     660 * Converts a TLB tag value into an even TLB index.
     661 * @returns Pointer into IEMTLB::aEntries corresponding to .
    655662 * @param   a_pTlb      The TLB.
    656  * @param   a_uTag      Value returned by IEMTLB_CALC_TAG.
    657  */
    658 #define IEMTLB_TAG_TO_ENTRY(a_pTlb, a_uTag) ( &(a_pTlb)->aEntries[IEMTLB_TAG_TO_INDEX(a_uTag)] )
     663 * @param   a_uTag      Value returned by IEMTLB_CALC_TAG or
     664 *                      IEMTLB_CALC_TAG_NO_REV.
     665 */
     666#define IEMTLB_TAG_TO_EVEN_ENTRY(a_pTlb, a_uTag)    ( &(a_pTlb)->aEntries[IEMTLB_TAG_TO_EVEN_INDEX(a_uTag)] )
    659667
    660668
  • trunk/src/VBox/VMM/include/IEMN8veRecompilerEmit.h

    r104984 r105036  
    68996899    {
    69006900        pbCodeBuf[offFixup + 1] = (uint8_t)(offTarget - (offFixup + 2));
    6901         AssertStmt(pbCodeBuf[offFixup + 1] == offTarget - (offFixup + 2),
     6901        AssertStmt((int8_t)pbCodeBuf[offFixup + 1] == (int32_t)(offTarget - (offFixup + 2)),
    69026902                   IEMNATIVE_DO_LONGJMP(pReNative, VERR_IEM_EMIT_FIXED_JUMP_OUT_OF_RANGE));
    69036903    }
  • trunk/src/VBox/VMM/include/IEMN8veRecompilerTlbLookup.h

    r104987 r105036  
    338338    uint8_t * const  pCodeBuf   = iemNativeInstrBufEnsure(pReNative, off, 512);
    339339# elif defined(RT_ARCH_ARM64)
    340     uint32_t * const pCodeBuf   = iemNativeInstrBufEnsure(pReNative, off, 64);
     340    uint32_t * const pCodeBuf   = iemNativeInstrBufEnsure(pReNative, off, 96);
    341341# endif
    342342
     
    387387        /* jmp  limitdone */
    388388        offFixupLimitDone = off;
    389         off = iemNativeEmitJmpToFixedEx(pCodeBuf, off, off /* ASSUME short jump suffices */);
     389        off = iemNativeEmitJmpToFixedEx(pCodeBuf, off, off + 256 /* force near */);
    390390    }
    391391
     
    427427        /* jbe short jmpback */
    428428        offFixupMisalignedAccessJmpBack = off;
    429         off = iemNativeEmitJccToFixedEx(pCodeBuf, off, off + 100, kIemNativeInstrCond_be);
    430 #ifdef IEM_WITH_TLB_STATISTICS
     429        off = iemNativeEmitJccToFixedEx(pCodeBuf, off, off + 256 /*near*/, kIemNativeInstrCond_be);
     430# ifdef IEM_WITH_TLB_STATISTICS
    431431        off = iemNativeEmitIncU32CounterInVCpuEx(pCodeBuf, off, pTlbState->idxReg1, pTlbState->idxReg2,
    432432                                                 offVCpuTlb + RT_UOFFSETOF(IEMTLB, cTlbNativeMissCrossPage));
    433 #endif
     433# endif
    434434        off = iemNativeEmitJmpToLabelEx(pReNative, pCodeBuf, off, idxLabelTlbMiss);
    435435    }
     436
     437    /* The ODD TLB entry is checked last when CR4.PGE=0 or when not in ring-0. */
     438    bool const fEvenFirst       = (pReNative->fExec & IEM_F_X86_CPL_MASK) != 0
     439                               || !(pReNative->pVCpu->cpum.GstCtx.cr4 & X86_CR4_PGE);
     440    bool const fIncCheckAltTlbe = (pReNative->fExec & IEM_F_X86_CPL_MASK) == 0;
     441
     442    /*
     443     * Snippet for checking the alternative TLBE entry when CR4.PGE=1 and
     444     * for doing statistics.
     445     *
     446     * This code assists step 3c, so look down there for register assignments.
     447     */
     448    /* checkalttlbe_and_missedtagstats: */
     449    uint32_t const offCheckAltTlbeAndMissedTagStats = off;
     450    uint32_t       offFixupCheckAltTlbeJmpBack      = UINT32_MAX / 2;
     451    if (fIncCheckAltTlbe)
     452    {
     453# ifdef RT_ARCH_AMD64
     454        /* Update pTlbe: reg2 = fEvenFirst ? reg2 + sizeof(IEMTLBENTRY) : reg2 - sizeof(IEMTLBENTRY); */
     455        pCodeBuf[off++] = X86_OP_REX_W | (pTlbState->idxReg2 < 8 ? 0 : X86_OP_REX_R | X86_OP_REX_B);
     456        pCodeBuf[off++] = 0x8d; /* LEA r64,m64 */
     457        off = iemNativeEmitGprByGprDisp(pCodeBuf, off, pTlbState->idxReg2, pTlbState->idxReg2,
     458                                        fEvenFirst ? (int32_t)sizeof(IEMTLBENTRY) : -(int32_t)sizeof(IEMTLBENTRY));
     459
     460        /* reg1 = reg1 & ~IEMTLB_REVISION_MASK; */
     461        off = iemNativeEmitShiftGprLeftEx(pCodeBuf, off, pTlbState->idxReg1, 16 + GUEST_PAGE_SHIFT);
     462        off = iemNativeEmitShiftGprRightEx(pCodeBuf, off, pTlbState->idxReg1, 16 + GUEST_PAGE_SHIFT);
     463        /* or  reg1, [qword pVCpu->iem.s.DataTlb.uTlbRevisionGlobal/uTlbRevision] */
     464        pCodeBuf[off++] = pTlbState->idxReg1 < 8 ? X86_OP_REX_W : X86_OP_REX_W | X86_OP_REX_R;
     465        pCodeBuf[off++] = 0x0b; /* OR r64,r/m64 */
     466        off = iemNativeEmitGprByVCpuDisp(pCodeBuf, off, pTlbState->idxReg1,
     467                                         fEvenFirst ? offVCpuTlb + RT_UOFFSETOF(IEMTLB, uTlbRevisionGlobal)
     468                                         :            offVCpuTlb + RT_UOFFSETOF(IEMTLB, uTlbRevision));
     469
     470        /* cmp reg1, [reg2] */
     471        pCodeBuf[off++] = X86_OP_REX_W | (pTlbState->idxReg1 < 8 ? 0 : X86_OP_REX_R) | (pTlbState->idxReg2 < 8 ? 0 : X86_OP_REX_B);
     472        pCodeBuf[off++] = 0x3b;
     473        off = iemNativeEmitGprByGprDisp(pCodeBuf, off, pTlbState->idxReg1, pTlbState->idxReg2, RT_UOFFSETOF(IEMTLBENTRY, uTag));
     474
     475# elif defined(RT_ARCH_ARM64)
     476        /* reg3 = uTlbRevision/uTlbRevisionGlobal; (We've ditched reg4 already, so have to get it via pVCpu.) */
     477        off = iemNativeEmitLoadGprFromVCpuU64Ex(pCodeBuf, off, pTlbState->idxReg3,
     478                                                fEvenFirst ? offVCpuTlb + RT_UOFFSETOF(IEMTLB, uTlbRevisionGlobal)
     479                                                :            offVCpuTlb + RT_UOFFSETOF(IEMTLB, uTlbRevision));
     480
     481        /* reg1 = reg1 & ~IEMTLB_REVISION_MASK; */
     482        AssertCompile(UINT64_C(0x0000000fffffffff) == ~IEMTLB_REVISION_MASK);
     483        Assert(Armv8A64ConvertImmRImmS2Mask64(0x63, 0) == ~IEMTLB_REVISION_MASK);
     484        pCodeBuf[off++] = Armv8A64MkInstrAndImm(pTlbState->idxReg1, pTlbState->idxReg1, 0x63, 0);
     485
     486        /* reg1 |= reg3 (uTlbRevision/uTlbRevisionGlobal); */
     487        pCodeBuf[off++] = Armv8A64MkInstrOrr(pTlbState->idxReg1, pTlbState->idxReg1, pTlbState->idxReg3);
     488
     489        /* reg2 = reg2 +/- sizeof(IEMTLBENTRY); via preindexing.
     490           reg3 = uTag; [pair: reg4 = fFlagsAndPhysRev;] */
     491        AssertCompileMemberOffset(IEMTLBENTRY, uTag, 0);
     492#  ifdef IEMNATIVE_WITH_TLB_LOOKUP_LOAD_STORE_PAIR
     493        AssertCompileAdjacentMembers(IEMTLBENTRY, uTag, fFlagsAndPhysRev);
     494        pCodeBuf[off++] = Armv8A64MkInstrLdPairGpr(pTlbState->idxReg3, pTlbState->idxReg4, pTlbState->idxReg2,
     495                                                   fEvenFirst ? (int)sizeof(IEMTLBENTRY) / 8 : -(int)sizeof(IEMTLBENTRY) / 8,
     496                                                   kArm64InstrStLdPairType_PreIndex);
     497#  else
     498        pCodeBuf[off++] = Armv8A64MkInstrStrLdrPreIndex9(kArmv8A64InstrLdStType_Ld_Dword, pTlbState->idxReg3, pTlbState->idxReg2,
     499                                                         fEvenFirst ? (int)sizeof(IEMTLBENTRY) / 8 : -(int)sizeof(IEMTLBENTRY) / 8);
     500#  endif
     501        /* cmp reg1, reg3; (uRev | Hash(FlatPtr), IEMTLBENTRY::uTag)*/
     502        off = iemNativeEmitCmpGprWithGprEx(pCodeBuf, off, pTlbState->idxReg1, pTlbState->idxReg3);
     503
     504# else
     505#  error "portme"
     506# endif
     507        /* je  near jumpback_checkalttlbe */
     508        offFixupCheckAltTlbeJmpBack = off;
     509        off = iemNativeEmitJccToFixedEx(pCodeBuf, off, off + 256, kIemNativeInstrCond_e);
     510    }
     511
     512# ifdef IEM_WITH_TLB_STATISTICS
     513    /* inc stat */
     514    off = iemNativeEmitIncStamCounterInVCpuEx(pCodeBuf, off, pTlbState->idxReg1, pTlbState->idxReg2,
     515                                              offVCpuTlb + RT_UOFFSETOF(IEMTLB, cTlbNativeMissTag));
     516# endif
     517# ifndef IEM_WITH_TLB_STATISTICS
     518    if (fIncCheckAltTlbe)
     519# endif
     520        off = iemNativeEmitJmpToLabelEx(pReNative, pCodeBuf, off, idxLabelTlbMiss);
     521    off = iemNativeEmitBrkEx(pCodeBuf, off, 0x7679);
    436522
    437523    /*
     
    700786     * 3. TLB lookup.
    701787     *
    702      * 3a. Calculate the TLB tag value (IEMTLB_CALC_TAG).
     788     * 3a. Calculate the TLB tag value (IEMTLB_CALC_TAG_NO_REV).
    703789     *     In 64-bit mode we will also check for non-canonical addresses here.
    704790     */
     
    771857        off = iemNativeEmitGpr32EqGprShiftRightImmEx(pCodeBuf, off, pTlbState->idxReg1, idxRegFlatPtr, GUEST_PAGE_SHIFT);
    772858    }
     859
    773860    /* or  reg1, [qword pVCpu->iem.s.DataTlb.uTlbRevision] */
    774861# if defined(RT_ARCH_AMD64)
    775862    pCodeBuf[off++] = pTlbState->idxReg1 < 8 ? X86_OP_REX_W : X86_OP_REX_W | X86_OP_REX_R;
    776863    pCodeBuf[off++] = 0x0b; /* OR r64,r/m64 */
    777     off = iemNativeEmitGprByVCpuDisp(pCodeBuf, off, pTlbState->idxReg1, offVCpuTlb + RT_UOFFSETOF(IEMTLB, uTlbRevision));
     864    off = iemNativeEmitGprByVCpuDisp(pCodeBuf, off, pTlbState->idxReg1,
     865                                     fEvenFirst ? offVCpuTlb + RT_UOFFSETOF(IEMTLB, uTlbRevision)
     866                                     :            offVCpuTlb + RT_UOFFSETOF(IEMTLB, uTlbRevisionGlobal));
    778867# else
    779868#  ifdef IEMNATIVE_WITH_TLB_LOOKUP_LOAD_STORE_PAIR
    780     /* Load uTlbRevision into reg3 and uTlbPhysRev into reg5.
    781        We load the offVCpuTlb + aEntries into reg4 and use it for addressing here
    782        and later when calculating pTble (save an instruction). */
     869    /* Load uTlbRevision[Global] into reg3 and uTlbPhysRev into reg5.
     870       We load the pointer for IEMTLB::aEntries[!fEvenFirst] into reg4 and use
     871       it for addressing here and later when calculating pTble (saves one
     872       instruction, simplifies odd-first). */
    783873    AssertCompileMemberAlignment(IEMTLB, uTlbRevision, 16); /* It is said that misaligned pair loads doesn't perform well. */
    784874    AssertCompileAdjacentMembers(IEMTLB, uTlbRevision, uTlbPhysRev);
     875    AssertCompileAdjacentMembers(IEMTLB, uTlbPhysRev, uTlbRevisionGlobal);
    785876    AssertCompile(RTASSERT_OFFSET_OF(IEMTLB, uTlbPhysRev) < RTASSERT_OFFSET_OF(IEMTLB, aEntries));
    786877    AssertCompile(RTASSERT_OFFSET_OF(VMCPUCC, iem.s.DataTlb.aEntries) < _64K);
    787     if (offVCpuTlb + RT_UOFFSETOF(IEMTLB, aEntries) < _64K)
    788     {
    789         pCodeBuf[off++] = Armv8A64MkInstrMovZ(pTlbState->idxReg4, offVCpuTlb + RT_UOFFSETOF(IEMTLB, aEntries));
     878    uint32_t const offEntries = offVCpuTlb + RT_UOFFSETOF(IEMTLB, aEntries) + (fEvenFirst ? 0 : sizeof(IEMTLBENTRY));
     879    if (offEntries < _64K)
     880    {
     881        pCodeBuf[off++] = Armv8A64MkInstrMovZ(pTlbState->idxReg4, offEntries);
    790882        pCodeBuf[off++] = Armv8A64MkInstrAddReg(pTlbState->idxReg4, IEMNATIVE_REG_FIXED_PVMCPU, pTlbState->idxReg4);
    791883    }
    792884    else
    793885    {
    794         AssertCompileMemberAlignment(VMCPUCC, iem.s.CodeTlb.aEntries, 64);
    795         AssertCompileMemberAlignment(IEMTLB, aEntries, 64);
    796         AssertCompile(RTASSERT_OFFSET_OF(VMCPUCC, iem.s.CodeTlb.aEntries) < _64K*64U);
    797         pCodeBuf[off++] = Armv8A64MkInstrMovZ(pTlbState->idxReg4, (offVCpuTlb + RT_UOFFSETOF(IEMTLB, aEntries)) >> 6);
     886        AssertCompileMemberAlignment(VMCPUCC, iem.s.CodeTlb.aEntries, 32);
     887        AssertCompileMemberAlignment(IEMTLB, aEntries, 32);
     888        AssertCompileSizeAlignment(IEMTLBENTRY, 32);
     889        AssertCompile(RTASSERT_OFFSET_OF(VMCPUCC, iem.s.CodeTlb.aEntries) < _64K*32U);
     890
     891        pCodeBuf[off++] = Armv8A64MkInstrMovZ(pTlbState->idxReg4, offEntries >> 5);
    798892        pCodeBuf[off++] = Armv8A64MkInstrAddReg(pTlbState->idxReg4, IEMNATIVE_REG_FIXED_PVMCPU, pTlbState->idxReg4,
    799                                                 true /*64Bit*/, false /*fSetFlags*/, 6 /*cShift*/, kArmv8A64InstrShift_Lsl);
    800     }
    801     pCodeBuf[off++] = Armv8A64MkInstrLdPairGpr(pTlbState->idxReg3, pTlbState->idxReg5, pTlbState->idxReg4,
    802                                                (RT_OFFSETOF(IEMTLB, uTlbRevision) - RT_OFFSETOF(IEMTLB, aEntries)) / 8);
     893                                                true /*64Bit*/, false /*fSetFlags*/, 5 /*cShift*/, kArmv8A64InstrShift_Lsl);
     894    }
     895    AssertCompile(RTASSERT_OFFSET_OF(IEMTLB, aEntries) < 64U*8U - sizeof(IEMTLBENTRY));
     896    if (fEvenFirst)
     897        pCodeBuf[off++] = Armv8A64MkInstrLdPairGpr(pTlbState->idxReg3, pTlbState->idxReg5, pTlbState->idxReg4,
     898                                                   (RT_OFFSETOF(IEMTLB, uTlbRevision) - RT_OFFSETOF(IEMTLB, aEntries)) / 8);
     899    else /* This isn't 128-bit aligned, hope that doesn't hurt too much... */
     900        pCodeBuf[off++] = Armv8A64MkInstrLdPairGpr(pTlbState->idxReg5, pTlbState->idxReg3, pTlbState->idxReg4,
     901                                                   (  RT_OFFSETOF(IEMTLB, uTlbPhysRev) - RT_OFFSETOF(IEMTLB, aEntries)
     902                                                    - (int)sizeof(IEMTLBENTRY)) / 8);
    803903#  else
    804     off = iemNativeEmitLoadGprFromVCpuU64Ex(pCodeBuf, off, pTlbState->idxReg3, offVCpuTlb + RT_UOFFSETOF(IEMTLB, uTlbRevision));
     904    off = iemNativeEmitLoadGprFromVCpuU64Ex(pCodeBuf, off, pTlbState->idxReg3,
     905                                            fEvenFirst ? offVCpuTlb + RT_UOFFSETOF(IEMTLB, uTlbRevision)
     906                                            :            offVCpuTlb + RT_UOFFSETOF(IEMTLB, uTlbRevisionGlobal));
    805907#  endif
    806908    off = iemNativeEmitOrGprByGprEx(pCodeBuf, off, pTlbState->idxReg1, pTlbState->idxReg3);
     
    811913     */
    812914# if !defined(RT_ARCH_ARM64) || !defined(IEMNATIVE_WITH_TLB_LOOKUP_LOAD_STORE_PAIR)
    813     uint32_t const offTlbEntries = offVCpuTlb + RT_UOFFSETOF(IEMTLB, aEntries);
     915    uint32_t const offTlbEntriesAdjusted = offVCpuTlb + RT_UOFFSETOF(IEMTLB, aEntries) + (fEvenFirst ? 0 : sizeof(IEMTLBENTRY));
    814916# endif
    815917# if defined(RT_ARCH_AMD64)
     
    823925    off = iemNativeEmitAndGpr32ByImmEx(pCodeBuf, off, pTlbState->idxReg2, IEMTLB_ENTRY_COUNT - 1U);
    824926#  endif
    825     /* shl   reg2, 5 ; reg2 *= sizeof(IEMTLBENTRY) */
     927    /* shl   reg2, 6 ; reg2 *= sizeof(IEMTLBENTRY) * 2 */
    826928    AssertCompileSize(IEMTLBENTRY, 32);
    827     off = iemNativeEmitShiftGprLeftEx(pCodeBuf, off, pTlbState->idxReg2, 5);
    828     /* lea   reg2, [pVCpu->iem.s.DataTlb.aEntries + reg2] */
     929    off = iemNativeEmitShiftGprLeftEx(pCodeBuf, off, pTlbState->idxReg2, 6);
     930    /* lea   reg2, [&pVCpu->iem.s.DataTlb.aEntries[!fEvenFirst] + reg2] */
    829931    AssertCompile(IEMNATIVE_REG_FIXED_PVMCPU < 8);
    830932    pCodeBuf[off++] = pTlbState->idxReg2 < 8 ? X86_OP_REX_W : X86_OP_REX_W | X86_OP_REX_X | X86_OP_REX_R;
     
    832934    pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_MEM4, pTlbState->idxReg2 & 7, 4 /*SIB*/);
    833935    pCodeBuf[off++] = X86_SIB_MAKE(IEMNATIVE_REG_FIXED_PVMCPU & 7, pTlbState->idxReg2 & 7, 0);
    834     pCodeBuf[off++] = RT_BYTE1(offTlbEntries);
    835     pCodeBuf[off++] = RT_BYTE2(offTlbEntries);
    836     pCodeBuf[off++] = RT_BYTE3(offTlbEntries);
    837     pCodeBuf[off++] = RT_BYTE4(offTlbEntries);
     936    pCodeBuf[off++] = RT_BYTE1(offTlbEntriesAdjusted);
     937    pCodeBuf[off++] = RT_BYTE2(offTlbEntriesAdjusted);
     938    pCodeBuf[off++] = RT_BYTE3(offTlbEntriesAdjusted);
     939    pCodeBuf[off++] = RT_BYTE4(offTlbEntriesAdjusted);
    838940
    839941# elif defined(RT_ARCH_ARM64)
    840     /* reg2 = (reg1 & tlbmask) << 5 */
    841     pCodeBuf[off++] = Armv8A64MkInstrUbfiz(pTlbState->idxReg2, pTlbState->idxReg1, 5, IEMTLB_ENTRY_COUNT_AS_POWER_OF_TWO);
     942    /* reg2 = (reg1 & tlbmask) << 6 */
     943    AssertCompileSize(IEMTLBENTRY, 32);
     944    pCodeBuf[off++] = Armv8A64MkInstrUbfiz(pTlbState->idxReg2, pTlbState->idxReg1, 6, IEMTLB_ENTRY_COUNT_AS_POWER_OF_TWO);
    842945#  ifdef IEMNATIVE_WITH_TLB_LOOKUP_LOAD_STORE_PAIR
    843     /* reg2 += &pVCpu->iem.s.DataTlb.aEntries / CodeTlb.aEntries */
     946    /* reg2 += &pVCpu->iem.s.[Data|Code]Tlb.aEntries[!fEvenFirst] */
    844947    pCodeBuf[off++] = Armv8A64MkInstrAddReg(pTlbState->idxReg2, pTlbState->idxReg2, pTlbState->idxReg4);
    845948#  else
    846     /* reg2 += offsetof(VMCPUCC, iem.s.DataTlb.aEntries) */
    847     off = iemNativeEmitAddGprImmEx(pCodeBuf, off, pTlbState->idxReg2, offTlbEntries, pTlbState->idxReg3 /*iGprTmp*/);
     949    /* reg2 += offsetof(VMCPUCC, iem.s.DataTlb.aEntries[!fEvenFirst]) */
     950    off = iemNativeEmitAddGprImmEx(pCodeBuf, off, pTlbState->idxReg2, offTlbEntriesAdjusted, pTlbState->idxReg3 /*iGprTmp*/);
    848951    /* reg2 += pVCpu */
    849952    off = iemNativeEmitAddTwoGprsEx(pCodeBuf, off, pTlbState->idxReg2, IEMNATIVE_REG_FIXED_PVMCPU);
     
    862965    off = iemNativeEmitGprByGprDisp(pCodeBuf, off, pTlbState->idxReg1, pTlbState->idxReg2, RT_UOFFSETOF(IEMTLBENTRY, uTag));
    863966# elif defined(RT_ARCH_ARM64)
     967    /* reg3 = uTag; [pair: reg4 = fFlagsAndPhysRev;] */
    864968#  ifdef IEMNATIVE_WITH_TLB_LOOKUP_LOAD_STORE_PAIR
    865969    AssertCompileMemberAlignment(IEMTLBENTRY, uTag, 16); /* It is said that misaligned pair loads doesn't perform well. */
     
    874978#  error "Port me"
    875979# endif
     980    /* jne checkalttlbe_and_missedtagstats */
    876981# ifndef IEM_WITH_TLB_STATISTICS
    877     /* jne tlbmiss */
    878     off = iemNativeEmitJccToLabelEx(pReNative, pCodeBuf, off, idxLabelTlbMiss, kIemNativeInstrCond_ne);
    879 # else
    880     /* je  1F; inc stat; jmp tlbmiss */
    881     uint32_t const offFixup1 = off;
    882     off = iemNativeEmitJccToFixedEx(pCodeBuf, off, off + 16, kIemNativeInstrCond_e);
    883     off = iemNativeEmitIncStamCounterInVCpuEx(pCodeBuf, off, pTlbState->idxReg1, pTlbState->idxReg2,
    884                                               offVCpuTlb + RT_UOFFSETOF(IEMTLB, cTlbNativeMissTag));
    885     off = iemNativeEmitJmpToLabelEx(pReNative, pCodeBuf, off, idxLabelTlbMiss);
    886     iemNativeFixupFixedJump(pReNative, offFixup1, off);
    887 # endif
     982    if (!fIncCheckAltTlbe)
     983        off = iemNativeEmitJccToLabelEx(pReNative, pCodeBuf, off, idxLabelTlbMiss, kIemNativeInstrCond_ne);
     984    else
     985# endif
     986    {
     987        off = iemNativeEmitJccToFixedEx(pCodeBuf, off, offCheckAltTlbeAndMissedTagStats, kIemNativeInstrCond_ne);
     988        if (fIncCheckAltTlbe)
     989            iemNativeFixupFixedJump(pReNative, offFixupCheckAltTlbeJmpBack, off);
     990    }
    888991
    889992    /*
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