Changeset 105593 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Aug 6, 2024 12:25:42 AM (4 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
r105592 r105593 776 776 #if defined(IEM_WITH_CODE_TLB) || defined(IEM_WITH_DATA_TLB) 777 777 778 /** @todo graduate this to cdefs.h or asm-mem.h. */ 779 # if defined(_MM_HINT_T0) && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)) 780 # define MY_PREFETCH(a_pvAddr) _mm_prefetch((const char *)(a_pvAddr), _MM_HINT_T0); 781 # elif defined(_MSC_VER) && (defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)) 782 # define MY_PREFETCH(a_pvAddr) __prefetch((a_pvAddr)); 783 # elif defined(__GNUC__) || RT_CLANG_HAS_FEATURE(__builtin_prefetch) 784 # define MY_PREFETCH(a_pvAddr) __builtin_prefetch((a_pvAddr), 0 /*rw*/, 3 /*locality*/) 785 # else 786 # define MY_PREFETCH(a_pvAddr) ((void)0) 787 # endif 788 778 789 template<bool const a_fDataTlb, bool const a_f2MbLargePage, bool const a_fGlobal, bool const a_fNonGlobal> 779 DECLINLINE(void) iemTlbInvalidateLargePageWorkerInner(PVMCPUCC pVCpu, IEMTLB *pTlb, RTGCPTR GCPtrTag, RTGCPTR GCPtrInstrBufPcTag) 790 DECLINLINE(void) iemTlbInvalidateLargePageWorkerInner(PVMCPUCC pVCpu, IEMTLB *pTlb, RTGCPTR GCPtrTag, 791 RTGCPTR GCPtrInstrBufPcTag) RT_NOEXCEPT 780 792 { 781 793 IEMTLBTRACE_LARGE_SCAN(pVCpu, a_fGlobal, a_fNonGlobal, a_fDataTlb); 782 783 /* 784 * Combine TAG values with the TLB revisions. 785 */ 786 RTGCPTR GCPtrTagGlob = a_fGlobal ? GCPtrTag | pTlb->uTlbRevisionGlobal : 0; 787 if (a_fNonGlobal) 788 GCPtrTag |= pTlb->uTlbRevision; 794 AssertCompile(IEMTLB_ENTRY_COUNT >= 16); /* prefetching + unroll assumption */ 789 795 790 796 /* … … 797 803 * 798 804 * For our example with 2MB pages and a 256 entry TLB: 0xfffffffffffffeff 805 * 806 * MY_PREFETCH: Hope that prefetching 256 bytes at the time is okay for 807 * relevant host architectures. 799 808 */ 809 /** @todo benchmark this code from the guest side. */ 800 810 bool const fPartialScan = IEMTLB_ENTRY_COUNT > (a_f2MbLargePage ? 512 : 1024); 801 811 uintptr_t idxEven = fPartialScan ? IEMTLB_TAG_TO_EVEN_INDEX(GCPtrTag) : 0; 812 MY_PREFETCH(&pTlb->aEntries[0 + !a_fNonGlobal]); 813 MY_PREFETCH(&pTlb->aEntries[2 + !a_fNonGlobal]); 814 MY_PREFETCH(&pTlb->aEntries[4 + !a_fNonGlobal]); 815 MY_PREFETCH(&pTlb->aEntries[6 + !a_fNonGlobal]); 802 816 uintptr_t const idxEvenEnd = fPartialScan ? idxEven + ((a_f2MbLargePage ? 512 : 1024) * 2) : IEMTLB_ENTRY_COUNT * 2; 803 817 RTGCPTR const GCPtrTagMask = fPartialScan ? ~(RTGCPTR)0 … … 806 820 807 821 /* 822 * Combine TAG values with the TLB revisions. 823 */ 824 RTGCPTR GCPtrTagGlob = a_fGlobal ? GCPtrTag | pTlb->uTlbRevisionGlobal : 0; 825 if (a_fNonGlobal) 826 GCPtrTag |= pTlb->uTlbRevision; 827 828 /* 808 829 * Do the scanning. 809 830 */ 810 for (; idxEven < idxEvenEnd; idxEven += 2) 811 { 812 if (a_fNonGlobal) 813 { 814 if ((pTlb->aEntries[idxEven].uTag & GCPtrTagMask) == GCPtrTag) 815 { 816 if (pTlb->aEntries[idxEven].fFlagsAndPhysRev & IEMTLBE_F_PT_LARGE_PAGE) 817 { 818 IEMTLBTRACE_LARGE_EVICT_SLOT(pVCpu, GCPtrTag, pTlb->aEntries[idxEven].GCPhys, idxEven, a_fDataTlb); 819 pTlb->aEntries[idxEven].uTag = 0; 820 if (!a_fDataTlb && GCPtrTag == GCPtrInstrBufPcTag) 821 pVCpu->iem.s.cbInstrBufTotal = 0; 822 } 831 for (; idxEven < idxEvenEnd; idxEven += 8) 832 { 833 #define ONE_ITERATION(a_idxEvenIter) \ 834 if (a_fNonGlobal) \ 835 { \ 836 if ((pTlb->aEntries[a_idxEvenIter].uTag & GCPtrTagMask) == GCPtrTag) \ 837 { \ 838 if (pTlb->aEntries[a_idxEvenIter].fFlagsAndPhysRev & IEMTLBE_F_PT_LARGE_PAGE) \ 839 { \ 840 IEMTLBTRACE_LARGE_EVICT_SLOT(pVCpu, GCPtrTag, pTlb->aEntries[a_idxEvenIter].GCPhys, \ 841 a_idxEvenIter, a_fDataTlb); \ 842 pTlb->aEntries[a_idxEvenIter].uTag = 0; \ 843 if (!a_fDataTlb && GCPtrTag == GCPtrInstrBufPcTag) \ 844 pVCpu->iem.s.cbInstrBufTotal = 0; \ 845 } \ 846 } \ 847 GCPtrTag++; \ 848 } \ 849 \ 850 if (a_fGlobal) \ 851 { \ 852 if ((pTlb->aEntries[a_idxEvenIter + 1].uTag & GCPtrTagMask) == GCPtrTagGlob) \ 853 { \ 854 if (pTlb->aEntries[a_idxEvenIter + 1].fFlagsAndPhysRev & IEMTLBE_F_PT_LARGE_PAGE) \ 855 { \ 856 IEMTLBTRACE_LARGE_EVICT_SLOT(pVCpu, GCPtrTag, pTlb->aEntries[a_idxEvenIter + 1].GCPhys, \ 857 a_idxEvenIter + 1, a_fDataTlb); \ 858 pTlb->aEntries[a_idxEvenIter + 1].uTag = 0; \ 859 if (!a_fDataTlb && GCPtrTag == GCPtrInstrBufPcTag) \ 860 pVCpu->iem.s.cbInstrBufTotal = 0; \ 861 } \ 862 } \ 863 GCPtrTagGlob++; \ 823 864 } 824 GCPtrTag++; 825 } 826 827 if (a_fGlobal) 828 { 829 if ((pTlb->aEntries[idxEven + 1].uTag & GCPtrTagMask) == GCPtrTagGlob) 830 { 831 if (pTlb->aEntries[idxEven + 1].fFlagsAndPhysRev & IEMTLBE_F_PT_LARGE_PAGE) 832 { 833 IEMTLBTRACE_LARGE_EVICT_SLOT(pVCpu, GCPtrTag, pTlb->aEntries[idxEven + 1].GCPhys, idxEven + 1, a_fDataTlb); 834 pTlb->aEntries[idxEven + 1].uTag = 0; 835 if (!a_fDataTlb && GCPtrTag == GCPtrInstrBufPcTag) 836 pVCpu->iem.s.cbInstrBufTotal = 0; 837 } 838 } 839 GCPtrTagGlob++; 840 } 841 } 842 865 if (idxEven < idxEvenEnd - 8) 866 { 867 MY_PREFETCH(&pTlb->aEntries[idxEven + 8 + !a_fNonGlobal]); 868 MY_PREFETCH(&pTlb->aEntries[idxEven + 10 + !a_fNonGlobal]); 869 MY_PREFETCH(&pTlb->aEntries[idxEven + 12 + !a_fNonGlobal]); 870 MY_PREFETCH(&pTlb->aEntries[idxEven + 14 + !a_fNonGlobal]); 871 } 872 ONE_ITERATION(idxEven) 873 ONE_ITERATION(idxEven + 2) 874 ONE_ITERATION(idxEven + 4) 875 ONE_ITERATION(idxEven + 6) 876 #undef ONE_ITERATION 877 } 843 878 } 844 879 845 880 template<bool const a_fDataTlb, bool const a_f2MbLargePage> 846 DECLINLINE(void) iemTlbInvalidateLargePageWorker(PVMCPUCC pVCpu, IEMTLB *pTlb, RTGCPTR GCPtrTag, RTGCPTR GCPtrInstrBufPcTag) 881 DECLINLINE(void) iemTlbInvalidateLargePageWorker(PVMCPUCC pVCpu, IEMTLB *pTlb, RTGCPTR GCPtrTag, 882 RTGCPTR GCPtrInstrBufPcTag) RT_NOEXCEPT 847 883 { 848 884 AssertCompile(IEMTLB_CALC_TAG_NO_REV((RTGCPTR)0x8731U << GUEST_PAGE_SHIFT) == 0x8731U); … … 869 905 870 906 template<bool const a_fDataTlb> 871 DECLINLINE(void) iemTlbInvalidatePageWorker(PVMCPUCC pVCpu, IEMTLB *pTlb, RTGCPTR GCPtrTag, uintptr_t idxEven) 907 DECLINLINE(void) iemTlbInvalidatePageWorker(PVMCPUCC pVCpu, IEMTLB *pTlb, RTGCPTR GCPtrTag, uintptr_t idxEven) RT_NOEXCEPT 872 908 { 873 909 /*
Note:
See TracChangeset
for help on using the changeset viewer.