Add code to compare ParentPagingEntry Attribute&Mask and input Attribute&Mask to decide if new next level page table is needed in non-present ParentPagingEntry condition. This can help avoid unneccessary page table creation.
For example, there is a page table in which [0, 1G] is mapped(Lv4[0] ,Lv3[0,0], a non-leaf level4 entry and a leaf level3 entry).And we only want to map [1G, 1G+2M] linear address still as non-present. The expected behaviour should be nothing happens in the process. However, previous code logic doesn't check if ParentPagingEntry Attribute&Mask and input Attribute&Mask are the same in non-present ParentPagingEntry condition. Then a new 4K memory is allocated for Lv2 since 1G+2M is not 1G-aligned. So when ParentPagingEntry is non-present, before allocate 4K memory for next level paging, we also check if ParentPagingEntry Attribute& Mask and input Attribute&Mask are the same. Signed-off-by: Dun Tan <dun....@intel.com> Cc: Eric Dong <eric.d...@intel.com> Cc: Ray Ni <ray...@intel.com> Cc: Rahul Kumar <rahul1.ku...@intel.com> Cc: Gerd Hoffmann <kra...@redhat.com> --- UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c b/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c index fbfd6389dc..29191d26b5 100644 --- a/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c +++ b/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c @@ -355,6 +355,24 @@ PageTableLibMapInLevel ( return Status; } + // + // Use NOP attributes as the attribute of grand-parents because CPU will consider + // the actual attributes of grand-parents when determing the memory type. + // + PleBAttribute.Uint64 = PageTableLibGetPleBMapAttribute (&ParentPagingEntry->PleB, ParentAttribute); + if ((((IA32_MAP_ATTRIBUTE_ATTRIBUTES (&PleBAttribute) & IA32_MAP_ATTRIBUTE_ATTRIBUTES (Mask)) + == (IA32_MAP_ATTRIBUTE_ATTRIBUTES (Attribute) & IA32_MAP_ATTRIBUTE_ATTRIBUTES (Mask)))) && + ( ((Mask->Bits.PageTableBaseAddressLow == 0) && (Mask->Bits.PageTableBaseAddressHigh == 0)) + || ((IA32_MAP_ATTRIBUTE_PAGE_TABLE_BASE_ADDRESS (&PleBAttribute) + PagingEntryIndex * RegionLength) + == (IA32_MAP_ATTRIBUTE_PAGE_TABLE_BASE_ADDRESS (Attribute) + Offset)))) + { + // + // This function is called when the memory length is less than the region length of the parent level. + // No need to split the page when the attributes equal. + // + return RETURN_SUCCESS; + } + // // The parent entry is CR3 or PML5E/PML4E/PDPTE/PDE. // It does NOT point to an existing page directory. -- 2.31.1.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#101397): https://edk2.groups.io/g/devel/message/101397 Mute This Topic: https://groups.io/mt/97725715/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-