UefiCpuPkg/CpuPageTableLib: Add check for page table creation

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.tan@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Tested-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
Dun Tan 2023-03-20 12:24:17 +08:00 committed by mergify[bot]
parent aa3153b872
commit f7686f2727
1 changed files with 10 additions and 0 deletions

View File

@ -361,6 +361,16 @@ PageTableLibMapInLevel (
return Status;
}
//
// Check the attribute in ParentPagingEntry is equal to attribute calculated by input Attribue and Mask.
//
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)))
{
return RETURN_SUCCESS;
}
//
// The parent entry is CR3 or PML5E/PML4E/PDPTE/PDE.
// It does NOT point to an existing page directory.