Changeset 105177 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Jul 8, 2024 9:29:14 AM (7 months ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
r105137 r105177 728 728 729 729 730 #if defined(IEM_WITH_CODE_TLB) || defined(IEM_WITH_DATA_TLB) 731 template<bool a_fDataTlb> 732 DECLINLINE(void) iemTlbInvalidatePageWorker(PVMCPUCC pVCpu, IEMTLB *pTlb, RTGCPTR GCPtrTag, uintptr_t idxEven) 733 { 734 /* 735 * Flush the entry pair. 736 * 737 * We ASSUME that the guest hasn't tricked us into loading one of these 738 * from a large page and the other from a regular 4KB page. This is made 739 * much less of a problem, in that the guest would also have to flip the 740 * G bit to accomplish this. 741 */ 742 bool fMaybeLargePage = true; 743 if (pTlb->aEntries[idxEven].uTag == (GCPtrTag | pTlb->uTlbRevision)) 744 { 745 pTlb->aEntries[idxEven].uTag = 0; 746 fMaybeLargePage = RT_BOOL(pTlb->aEntries[idxEven].fFlagsAndPhysRev & IEMTLBE_F_PT_LARGE_PAGE); 747 if (!a_fDataTlb && GCPtrTag == IEMTLB_CALC_TAG_NO_REV(pVCpu->iem.s.uInstrBufPc)) 748 pVCpu->iem.s.cbInstrBufTotal = 0; 749 } 750 if (pTlb->aEntries[idxEven + 1].uTag == (GCPtrTag | pTlb->uTlbRevisionGlobal)) 751 { 752 pTlb->aEntries[idxEven + 1].uTag = 0; 753 fMaybeLargePage = RT_BOOL(pTlb->aEntries[idxEven].fFlagsAndPhysRev & IEMTLBE_F_PT_LARGE_PAGE); 754 if (!a_fDataTlb && GCPtrTag == IEMTLB_CALC_TAG_NO_REV(pVCpu->iem.s.uInstrBufPc)) 755 pVCpu->iem.s.cbInstrBufTotal = 0; 756 } 757 758 /* 759 * If we cannot rule out a large page, we have to scan all the 4K TLB 760 * entries such a page covers to ensure we evict all relevant entries. 761 * ASSUMES that tag calculation is a right shift by GUEST_PAGE_SHIFT. 762 */ 763 if (fMaybeLargePage) 764 { 765 AssertCompile(IEMTLB_CALC_TAG_NO_REV((RTGCPTR)0x8731U << GUEST_PAGE_SHIFT) == 0x8731U); 766 RTGCPTR const GCPtrInstrBufPcTag = IEMTLB_CALC_TAG_NO_REV(pVCpu->iem.s.uInstrBufPc); 767 if ((pVCpu->cpum.GstCtx.cr4 & X86_CR4_PAE) && (pVCpu->cpum.GstCtx.cr0 & X86_CR0_PG)) 768 { 769 /* 2MB large page */ 770 GCPtrTag &= ~(RTGCPTR)(RT_BIT_64(21 - GUEST_PAGE_SHIFT) - 1U); 771 RTGCPTR GCPtrTagGlob = GCPtrTag | pTlb->uTlbRevisionGlobal; 772 GCPtrTag |= pTlb->uTlbRevision; 773 774 # if IEMTLB_ENTRY_COUNT >= 512 775 idxEven = IEMTLB_TAG_TO_EVEN_INDEX(GCPtrTag); 776 RTGCPTR const GCPtrTagMask = ~(RTGCPTR)0; 777 uintptr_t const idxEvenEnd = idxEven + 512; 778 # else 779 RTGCPTR const GCPtrTagMask = ~(RTGCPTR)GUEST_PAGE_OFFSET_MASK 780 & ~(RTGCPTR)( (RT_BIT_64(9 - IEMTLB_ENTRY_COUNT_AS_POWER_OF_TWO) - 1U) 781 << IEMTLB_ENTRY_COUNT_AS_POWER_OF_TWO); 782 uintptr_t const idxEvenEnd = IEMTLB_ENTRY_COUNT; 783 # endif 784 for (idxEven = 0; idxEven < idxEvenEnd; idxEven += 2) 785 { 786 if ((pTlb->aEntries[idxEven].uTag & GCPtrTagMask) == GCPtrTag) 787 { 788 Assert(pTlb->aEntries[idxEven].fFlagsAndPhysRev & IEMTLBE_F_PT_LARGE_PAGE); /* bad guest */ 789 pTlb->aEntries[idxEven].uTag = 0; 790 if (!a_fDataTlb && GCPtrTag == GCPtrInstrBufPcTag) 791 pVCpu->iem.s.cbInstrBufTotal = 0; 792 } 793 if ((pTlb->aEntries[idxEven + 1].uTag & GCPtrTagMask) == GCPtrTagGlob) 794 { 795 Assert(pTlb->aEntries[idxEven + 1].fFlagsAndPhysRev & IEMTLBE_F_PT_LARGE_PAGE); /* bad guest */ 796 pTlb->aEntries[idxEven + 1].uTag = 0; 797 if (!a_fDataTlb && GCPtrTag == GCPtrInstrBufPcTag) 798 pVCpu->iem.s.cbInstrBufTotal = 0; 799 } 800 GCPtrTag++; 801 GCPtrTagGlob++; 802 } 803 } 804 else 805 { 806 /* 4MB large page */ 807 GCPtrTag &= ~(RTGCPTR)(RT_BIT_64(22 - GUEST_PAGE_SHIFT) - 1U); 808 RTGCPTR GCPtrTagGlob = GCPtrTag | pTlb->uTlbRevisionGlobal; 809 GCPtrTag |= pTlb->uTlbRevision; 810 811 # if IEMTLB_ENTRY_COUNT >= 1024 812 idxEven = IEMTLB_TAG_TO_EVEN_INDEX(GCPtrTag); 813 RTGCPTR const GCPtrTagMask = ~(RTGCPTR)0; 814 uintptr_t const idxEvenEnd = idxEven + 1024; 815 # else 816 RTGCPTR const GCPtrTagMask = ~(RTGCPTR)GUEST_PAGE_OFFSET_MASK 817 & ~(RTGCPTR)( (RT_BIT_64(10 - IEMTLB_ENTRY_COUNT_AS_POWER_OF_TWO) - 1U) 818 << IEMTLB_ENTRY_COUNT_AS_POWER_OF_TWO); 819 uintptr_t const idxEvenEnd = IEMTLB_ENTRY_COUNT; 820 # endif 821 for (idxEven = 0; idxEven < idxEvenEnd; idxEven += 2) 822 { 823 if ((pTlb->aEntries[idxEven].uTag & GCPtrTagMask) == GCPtrTag) 824 { 825 Assert(pTlb->aEntries[idxEven].fFlagsAndPhysRev & IEMTLBE_F_PT_LARGE_PAGE); /* bad guest */ 826 pTlb->aEntries[idxEven].uTag = 0; 827 if (!a_fDataTlb && GCPtrTag == GCPtrInstrBufPcTag) 828 pVCpu->iem.s.cbInstrBufTotal = 0; 829 } 830 if ((pTlb->aEntries[idxEven + 1].uTag & GCPtrTagMask) == GCPtrTagGlob) 831 { 832 Assert(pTlb->aEntries[idxEven + 1].fFlagsAndPhysRev & IEMTLBE_F_PT_LARGE_PAGE); /* bad guest */ 833 pTlb->aEntries[idxEven + 1].uTag = 0; 834 if (!a_fDataTlb && GCPtrTag == GCPtrInstrBufPcTag) 835 pVCpu->iem.s.cbInstrBufTotal = 0; 836 } 837 GCPtrTag++; 838 GCPtrTagGlob++; 839 } 840 } 841 } 842 } 843 #endif 844 845 730 846 /** 731 847 * Invalidates a page in the TLBs. … … 745 861 746 862 # ifdef IEM_WITH_CODE_TLB 747 if (pVCpu->iem.s.CodeTlb.aEntries[idxEven].uTag == (GCPtr | pVCpu->iem.s.CodeTlb.uTlbRevision)) 748 { 749 pVCpu->iem.s.CodeTlb.aEntries[idxEven].uTag = 0; 750 if (GCPtr == IEMTLB_CALC_TAG_NO_REV(pVCpu->iem.s.uInstrBufPc)) 751 pVCpu->iem.s.cbInstrBufTotal = 0; 752 } 753 if (pVCpu->iem.s.CodeTlb.aEntries[idxEven + 1].uTag == (GCPtr | pVCpu->iem.s.CodeTlb.uTlbRevisionGlobal)) 754 { 755 pVCpu->iem.s.CodeTlb.aEntries[idxEven + 1].uTag = 0; 756 if (GCPtr == IEMTLB_CALC_TAG_NO_REV(pVCpu->iem.s.uInstrBufPc)) 757 pVCpu->iem.s.cbInstrBufTotal = 0; 758 } 863 iemTlbInvalidatePageWorker<false>(pVCpu, &pVCpu->iem.s.CodeTlb, GCPtr, idxEven); 759 864 # endif 760 761 865 # ifdef IEM_WITH_DATA_TLB 762 if (pVCpu->iem.s.DataTlb.aEntries[idxEven].uTag == (GCPtr | pVCpu->iem.s.DataTlb.uTlbRevision)) 763 pVCpu->iem.s.DataTlb.aEntries[idxEven].uTag = 0; 764 if (pVCpu->iem.s.DataTlb.aEntries[idxEven + 1].uTag == (GCPtr | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal)) 765 pVCpu->iem.s.DataTlb.aEntries[idxEven + 1].uTag = 0; 866 iemTlbInvalidatePageWorker<true>(pVCpu, &pVCpu->iem.s.DataTlb, GCPtr, idxEven); 766 867 # endif 767 868 #else … … 1103 1204 } 1104 1205 pTlbe->fFlagsAndPhysRev = (~WalkFast.fEffective & (X86_PTE_US | X86_PTE_RW | X86_PTE_D | X86_PTE_A)) 1105 | (WalkFast.fEffective >> X86_PTE_PAE_BIT_NX) /*IEMTLBE_F_PT_NO_EXEC*/; 1206 | (WalkFast.fEffective >> X86_PTE_PAE_BIT_NX) /*IEMTLBE_F_PT_NO_EXEC*/ 1207 | (WalkFast.fInfo & PGM_WALKINFO_BIG_PAGE); 1106 1208 RTGCPHYS const GCPhysPg = WalkFast.GCPhys & ~(RTGCPHYS)GUEST_PAGE_OFFSET_MASK; 1107 1209 pTlbe->GCPhys = GCPhysPg; … … 6657 6759 pTlbe->uTag = uTagNoRev; 6658 6760 } 6659 pTlbe->fFlagsAndPhysRev = ~WalkFast.fEffective & (X86_PTE_US | X86_PTE_RW | X86_PTE_D | X86_PTE_A); /* skipping NX */ 6761 pTlbe->fFlagsAndPhysRev = (~WalkFast.fEffective & (X86_PTE_US | X86_PTE_RW | X86_PTE_D | X86_PTE_A) /* skipping NX */) 6762 | (WalkFast.fInfo & PGM_WALKINFO_BIG_PAGE); 6660 6763 RTGCPHYS const GCPhysPg = WalkFast.GCPhys & ~(RTGCPHYS)GUEST_PAGE_OFFSET_MASK; 6661 6764 pTlbe->GCPhys = GCPhysPg; … … 7051 7154 pTlbe->uTag = uTagNoRev; 7052 7155 } 7053 pTlbe->fFlagsAndPhysRev = ~WalkFast.fEffective & (X86_PTE_US | X86_PTE_RW | X86_PTE_D | X86_PTE_A); /* skipping NX */ 7156 pTlbe->fFlagsAndPhysRev = (~WalkFast.fEffective & (X86_PTE_US | X86_PTE_RW | X86_PTE_D | X86_PTE_A) /* skipping NX */) 7157 | (WalkFast.fInfo & PGM_WALKINFO_BIG_PAGE); 7054 7158 RTGCPHYS const GCPhysPg = WalkFast.GCPhys & ~(RTGCPHYS)GUEST_PAGE_OFFSET_MASK; 7055 7159 pTlbe->GCPhys = GCPhysPg; -
trunk/src/VBox/VMM/VMMR3/IEMR3.cpp
r105036 r105177 1039 1039 static void iemR3InfoTlbPrintSlot(PCDBGFINFOHLP pHlp, IEMTLB const *pTlb, IEMTLBENTRY const *pTlbe, uint32_t uSlot) 1040 1040 { 1041 pHlp->pfnPrintf(pHlp, "%02x: %s %#018RX64 -> %RGp / %p / %#05x %s%s%s%s /%s%s%s/%s %s\n",1041 pHlp->pfnPrintf(pHlp, "%02x: %s %#018RX64 -> %RGp / %p / %#05x %s%s%s%s%s/%s%s%s/%s %s\n", 1042 1042 uSlot, 1043 1043 (pTlbe->uTag & IEMTLB_REVISION_MASK) == pTlb->uTlbRevision ? "valid " … … 1051 1051 pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PT_NO_ACCESSED ? "-" : "A", 1052 1052 pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PT_NO_DIRTY ? "-" : "D", 1053 pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PT_LARGE_PAGE ? "-" : "S", 1053 1054 pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PG_NO_WRITE ? "-" : "w", 1054 1055 pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PG_NO_READ ? "-" : "r", -
trunk/src/VBox/VMM/include/IEMInternal-armv8.h
r104956 r105177 286 286 /** @name IEMTLBE_F_XXX - TLB entry flags (IEMTLBENTRY::fFlagsAndPhysRev) 287 287 * @{ */ 288 #define IEMTLBE_F_PT_NO_EXEC RT_BIT_64(0) /**< Page tables: Not executable. */ 289 #define IEMTLBE_F_PT_NO_WRITE RT_BIT_64(1) /**< Page tables: Not writable. */ 290 #define IEMTLBE_F_PT_NO_USER RT_BIT_64(2) /**< Page tables: Not user accessible (supervisor only). */ 291 #define IEMTLBE_F_PG_NO_WRITE RT_BIT_64(3) /**< Phys page: Not writable (access handler, ROM, whatever). */ 292 #define IEMTLBE_F_PG_NO_READ RT_BIT_64(4) /**< Phys page: Not readable (MMIO / access handler, ROM) */ 293 #define IEMTLBE_F_PT_NO_ACCESSED RT_BIT_64(5) /**< Phys tables: Not accessed (need to be marked accessed). */ 294 #define IEMTLBE_F_PT_NO_DIRTY RT_BIT_64(6) /**< Page tables: Not dirty (needs to be made dirty on write). */ 295 #define IEMTLBE_F_NO_MAPPINGR3 RT_BIT_64(7) /**< TLB entry: The IEMTLBENTRY::pMappingR3 member is invalid. */ 296 #define IEMTLBE_F_PG_UNASSIGNED RT_BIT_64(8) /**< Phys page: Unassigned memory (not RAM, ROM, MMIO2 or MMIO). */ 297 #define IEMTLBE_F_PG_CODE_PAGE RT_BIT_64(9) /**< Phys page: Code page. */ 298 #define IEMTLBE_F_PHYS_REV UINT64_C(0xfffffffffffffc00) /**< Physical revision mask. @sa IEMTLB_PHYS_REV_INCR */ 288 #define IEMTLBE_F_PT_NO_EXEC RT_BIT_64(0) /**< Page tables: Not executable. */ 289 #define IEMTLBE_F_PT_NO_WRITE RT_BIT_64(1) /**< Page tables: Not writable. */ 290 #define IEMTLBE_F_PT_NO_USER RT_BIT_64(2) /**< Page tables: Not user accessible (supervisor only). */ 291 #define IEMTLBE_F_PG_NO_WRITE RT_BIT_64(3) /**< Phys page: Not writable (access handler, ROM, whatever). */ 292 #define IEMTLBE_F_PG_NO_READ RT_BIT_64(4) /**< Phys page: Not readable (MMIO / access handler, ROM) */ 293 #define IEMTLBE_F_PT_NO_ACCESSED RT_BIT_64(5) /**< Phys tables: Not accessed (need to be marked accessed). */ 294 #define IEMTLBE_F_PT_NO_DIRTY RT_BIT_64(6) /**< Page tables: Not dirty (needs to be made dirty on write). */ 295 #define IEMTLBE_F_PT_LARGE_PAGE RT_BIT_64(7) /**< Page tables: Large 2 or 4 MiB page (for flushing). */ 296 #define IEMTLBE_F_NO_MAPPINGR3 RT_BIT_64(8) /**< TLB entry: The IEMTLBENTRY::pMappingR3 member is invalid. */ 297 #define IEMTLBE_F_PG_UNASSIGNED RT_BIT_64(9) /**< Phys page: Unassigned memory (not RAM, ROM, MMIO2 or MMIO). */ 298 #define IEMTLBE_F_PG_CODE_PAGE RT_BIT_64(10) /**< Phys page: Code page. */ 299 #define IEMTLBE_F_PHYS_REV UINT64_C(0xfffffffffffff800) /**< Physical revision mask. @sa IEMTLB_PHYS_REV_INCR */ 299 300 /** @} */ 300 301 -
trunk/src/VBox/VMM/include/IEMInternal.h
r105123 r105177 500 500 /** @name IEMTLBE_F_XXX - TLB entry flags (IEMTLBENTRY::fFlagsAndPhysRev) 501 501 * @{ */ 502 #define IEMTLBE_F_PT_NO_EXEC RT_BIT_64(0) /**< Page tables: Not executable. */ 503 #define IEMTLBE_F_PT_NO_WRITE RT_BIT_64(1) /**< Page tables: Not writable. */ 504 #define IEMTLBE_F_PT_NO_USER RT_BIT_64(2) /**< Page tables: Not user accessible (supervisor only). */ 505 #define IEMTLBE_F_PG_NO_WRITE RT_BIT_64(3) /**< Phys page: Not writable (access handler, ROM, whatever). */ 506 #define IEMTLBE_F_PG_NO_READ RT_BIT_64(4) /**< Phys page: Not readable (MMIO / access handler, ROM) */ 507 #define IEMTLBE_F_PT_NO_ACCESSED RT_BIT_64(5) /**< Phys tables: Not accessed (need to be marked accessed). */ 508 #define IEMTLBE_F_PT_NO_DIRTY RT_BIT_64(6) /**< Page tables: Not dirty (needs to be made dirty on write). */ 509 #define IEMTLBE_F_NO_MAPPINGR3 RT_BIT_64(7) /**< TLB entry: The IEMTLBENTRY::pMappingR3 member is invalid. */ 510 #define IEMTLBE_F_PG_UNASSIGNED RT_BIT_64(8) /**< Phys page: Unassigned memory (not RAM, ROM, MMIO2 or MMIO). */ 511 #define IEMTLBE_F_PG_CODE_PAGE RT_BIT_64(9) /**< Phys page: Code page. */ 512 #define IEMTLBE_F_PHYS_REV UINT64_C(0xfffffffffffffc00) /**< Physical revision mask. @sa IEMTLB_PHYS_REV_INCR */ 502 #define IEMTLBE_F_PT_NO_EXEC RT_BIT_64(0) /**< Page tables: Not executable. */ 503 #define IEMTLBE_F_PT_NO_WRITE RT_BIT_64(1) /**< Page tables: Not writable. */ 504 #define IEMTLBE_F_PT_NO_USER RT_BIT_64(2) /**< Page tables: Not user accessible (supervisor only). */ 505 #define IEMTLBE_F_PG_NO_WRITE RT_BIT_64(3) /**< Phys page: Not writable (access handler, ROM, whatever). */ 506 #define IEMTLBE_F_PG_NO_READ RT_BIT_64(4) /**< Phys page: Not readable (MMIO / access handler, ROM) */ 507 #define IEMTLBE_F_PT_NO_ACCESSED RT_BIT_64(5) /**< Phys tables: Not accessed (need to be marked accessed). */ 508 #define IEMTLBE_F_PT_NO_DIRTY RT_BIT_64(6) /**< Page tables: Not dirty (needs to be made dirty on write). */ 509 #define IEMTLBE_F_PT_LARGE_PAGE RT_BIT_64(7) /**< Page tables: Large 2 or 4 MiB page (for flushing). */ 510 #define IEMTLBE_F_NO_MAPPINGR3 RT_BIT_64(8) /**< TLB entry: The IEMTLBENTRY::pMappingR3 member is invalid. */ 511 #define IEMTLBE_F_PG_UNASSIGNED RT_BIT_64(9) /**< Phys page: Unassigned memory (not RAM, ROM, MMIO2 or MMIO). */ 512 #define IEMTLBE_F_PG_CODE_PAGE RT_BIT_64(10) /**< Phys page: Code page. */ 513 #define IEMTLBE_F_PHYS_REV UINT64_C(0xfffffffffffff800) /**< Physical revision mask. @sa IEMTLB_PHYS_REV_INCR */ 513 514 /** @} */ 514 515 AssertCompile(PGMIEMGCPHYS2PTR_F_NO_WRITE == IEMTLBE_F_PG_NO_WRITE); … … 517 518 AssertCompile(PGMIEMGCPHYS2PTR_F_UNASSIGNED == IEMTLBE_F_PG_UNASSIGNED); 518 519 AssertCompile(PGMIEMGCPHYS2PTR_F_CODE_PAGE == IEMTLBE_F_PG_CODE_PAGE); 520 AssertCompile(PGM_WALKINFO_BIG_PAGE == IEMTLBE_F_PT_LARGE_PAGE); 519 521 /** The bits set by PGMPhysIemGCPhys2PtrNoLock. */ 520 522 #define IEMTLBE_GCPHYS2PTR_MASK ( PGMIEMGCPHYS2PTR_F_NO_WRITE \ … … 529 531 * from a 8-bit register without an additional AND instruction. 530 532 * See also @bugref{10687}. */ 531 #define IEMTLB_ENTRY_COUNT 1024 532 #define IEMTLB_ENTRY_COUNT_AS_POWER_OF_TWO 10 533 #if defined(RT_ARCH_AMD64) 534 # define IEMTLB_ENTRY_COUNT 256 535 # define IEMTLB_ENTRY_COUNT_AS_POWER_OF_TWO 8 536 #else 537 # define IEMTLB_ENTRY_COUNT 8192 538 # define IEMTLB_ENTRY_COUNT_AS_POWER_OF_TWO 13 539 #endif 533 540 AssertCompile(RT_BIT_32(IEMTLB_ENTRY_COUNT_AS_POWER_OF_TWO) == IEMTLB_ENTRY_COUNT); 534 541 … … 637 644 /** IEMTLB::uTlbPhysRev increment. 638 645 * @sa IEMTLBE_F_PHYS_REV */ 639 #define IEMTLB_PHYS_REV_INCR RT_BIT_64(10) 646 #define IEMTLB_PHYS_REV_INCR RT_BIT_64(11) 647 AssertCompile(IEMTLBE_F_PHYS_REV == ~(IEMTLB_PHYS_REV_INCR - 1U)); 648 640 649 /** 641 650 * Calculates the TLB tag for a virtual address but without TLB revision.
Note:
See TracChangeset
for help on using the changeset viewer.