In previous code logic, when splitting a leaf parent entry to smaller granularity child page table, if the parent entry Attribute&Mask(without PageTableBaseAddress field) is equal to the input attribute&mask(without PageTableBaseAddress field), the split process won't happen. This may lead to failure in non-1:1 mapping.
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 want to remap [0, 2M] linear address range to [1G, 1G + 2M] with the same attibute. The expected behaviour should be: split Lv3[0,0] entry into 512 level2 entries and remap the first level2 entry to cover [0, 2M]. But the split won't happen in previous code since PageTableBaseAddress of input Attribute is not checked. So, when checking if a leaf parent entry needs to be splitted, we should also check if PageTableBaseAddress calculated by parent entry is equal to the value caculated by input attribute. 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 | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c b/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c index 127b65183f..ad68792ca8 100644 --- a/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c +++ b/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c @@ -274,6 +274,8 @@ PageTableLibMapInLevel ( IA32_MAP_ATTRIBUTE ChildMask; IA32_MAP_ATTRIBUTE CurrentMask; IA32_MAP_ATTRIBUTE LocalParentAttribute; + UINT64 PhysicalAddrInEntry; + UINT64 PhysicalAddrInAttr; ASSERT (Level != 0); ASSERT ((Attribute != NULL) && (Mask != NULL)); @@ -341,7 +343,15 @@ PageTableLibMapInLevel ( // 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; + if (Mask->Bits.PageTableBaseAddress == 0) { + return RETURN_SUCCESS; + } + + PhysicalAddrInEntry = IA32_MAP_ATTRIBUTE_PAGE_TABLE_BASE_ADDRESS (&PleBAttribute) + PagingEntryIndex * RegionLength; + PhysicalAddrInAttr = (IA32_MAP_ATTRIBUTE_PAGE_TABLE_BASE_ADDRESS (Attribute) + Offset) & (~RegionMask); + if (PhysicalAddrInEntry == PhysicalAddrInAttr) { + return RETURN_SUCCESS; + } } ASSERT (Buffer == NULL || *BufferSize >= SIZE_4KB); -- 2.31.1.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#101632): https://edk2.groups.io/g/devel/message/101632 Mute This Topic: https://groups.io/mt/97796377/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-