]> git.proxmox.com Git - mirror_edk2.git/commitdiff
CpuPageTableLib: Avoid treating non-leaf entry as leaf one
authorRay Ni <ray.ni@intel.com>
Fri, 15 Jul 2022 07:22:57 +0000 (15:22 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Tue, 9 Aug 2022 07:08:05 +0000 (07:08 +0000)
Today's logic wrongly treats the non-leaf entry as leaf entry and
updates its paging attributes.

The patch fixes the bug to only update paging attributes for
non-present entries or leaf entries.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c

index d02fd5efa2eefa1c87e071ee6ab8092d71c6d89e..0df744cb9bc7d439a0952d310cd8e7f031ab289d 100644 (file)
@@ -248,6 +248,7 @@ PageTableLibMapInLevel (
   UINTN               BitStart;\r
   UINTN               Index;\r
   IA32_PAGING_ENTRY   *PagingEntry;\r
+  IA32_PAGING_ENTRY   *CurrentPagingEntry;\r
   UINT64              RegionLength;\r
   UINT64              SubLength;\r
   UINT64              SubOffset;\r
@@ -359,18 +360,20 @@ PageTableLibMapInLevel (
   //\r
   PagingEntry = (IA32_PAGING_ENTRY *)(UINTN)IA32_PNLE_PAGE_TABLE_BASE_ADDRESS (&ParentPagingEntry->Pnle);\r
   while (Offset < Length && Index < 512) {\r
-    SubLength = MIN (Length - Offset, RegionStart + RegionLength - (LinearAddress + Offset));\r
+    CurrentPagingEntry = (!Modify && CreateNew) ? &OneOfPagingEntry : &PagingEntry[Index];\r
+    SubLength          = MIN (Length - Offset, RegionStart + RegionLength - (LinearAddress + Offset));\r
     if ((Level <= MaxLeafLevel) &&\r
         (((LinearAddress + Offset) & RegionMask) == 0) &&\r
         (((IA32_MAP_ATTRIBUTE_PAGE_TABLE_BASE_ADDRESS (Attribute) + Offset) & RegionMask) == 0) &&\r
-        (SubLength == RegionLength)\r
+        (SubLength == RegionLength) &&\r
+        ((CurrentPagingEntry->Pce.Present == 0) || IsPle (CurrentPagingEntry, Level))\r
         )\r
     {\r
       //\r
       // Create one entry mapping the entire region (1G, 2M or 4K).\r
       //\r
       if (Modify) {\r
-        PageTableLibSetPle (Level, &PagingEntry[Index], Offset, Attribute, Mask);\r
+        PageTableLibSetPle (Level, CurrentPagingEntry, Offset, Attribute, Mask);\r
       }\r
     } else {\r
       //\r
@@ -382,7 +385,7 @@ PageTableLibMapInLevel (
       //      but the length is SMALLER than the RegionLength.\r
       //\r
       Status = PageTableLibMapInLevel (\r
-                 (!Modify && CreateNew) ? &OneOfPagingEntry : &PagingEntry[Index],\r
+                 CurrentPagingEntry,\r
                  Modify,\r
                  Buffer,\r
                  BufferSize,\r