]> git.proxmox.com Git - mirror_edk2.git/commitdiff
CpuPageTableLib: Fix bug that wrongly requires extra size for mapping
authorRay Ni <ray.ni@intel.com>
Mon, 18 Jul 2022 08:41:37 +0000 (16:41 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Tue, 9 Aug 2022 07:08:05 +0000 (07:08 +0000)
With following paging structure to map
  [2M-4K, 2M] as P = 1, RW = 0,
  [2M, 4M]    as P = 1, RW = 1:

PML4[0] -> PDPTE[0] -> PDE[0](RW = 0) -> PTE[255](P = 0, RW = 0)
                    -> PDE[1](RW = 1)

When a new request to map [2M-4K, 2M+4K] as P = 1, RW = 1,
CpuPageTableMap() wrongly requests 4K buffer size for the new mapping
request.

But in fact, for [2M-4K, 2M] request, PTE[255] can be changed in place,
for [2M, 2M+4K], no change is needed because PDE[1].RW = 1 already.

The change fixes the bug.

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 b1ff14e2b0572618df97ad45ca32404fb3be8a97..13af9a8cdd4530b3a30fad2005921b5475c0b224 100644 (file)
@@ -272,6 +272,7 @@ PageTableLibMapInLevel (
   IA32_MAP_ATTRIBUTE  ChildAttribute;\r
   IA32_MAP_ATTRIBUTE  ChildMask;\r
   IA32_MAP_ATTRIBUTE  CurrentMask;\r
+  IA32_MAP_ATTRIBUTE  LocalParentAttribute;\r
 \r
   ASSERT (Level != 0);\r
   ASSERT ((Attribute != NULL) && (Mask != NULL));\r
@@ -284,6 +285,9 @@ PageTableLibMapInLevel (
   NopAttribute.Bits.ReadWrite      = 1;\r
   NopAttribute.Bits.UserSupervisor = 1;\r
 \r
+  LocalParentAttribute.Uint64 = ParentAttribute->Uint64;\r
+  ParentAttribute             = &LocalParentAttribute;\r
+\r
   //\r
   // ParentPagingEntry ONLY is deferenced for checking Present and MustBeOne bits\r
   // when Modify is FALSE.\r
@@ -420,7 +424,7 @@ PageTableLibMapInLevel (
           }\r
 \r
           if (IsPle (&PagingEntry[Index], Level)) {\r
-            PageTableLibSetPle (Level - 1, &PagingEntry[Index], 0, &ChildAttribute, &ChildMask);\r
+            PageTableLibSetPle (Level, &PagingEntry[Index], 0, &ChildAttribute, &ChildMask);\r
           } else {\r
             PageTableLibSetPnle (&PagingEntry[Index].Pnle, &ChildAttribute, &ChildMask);\r
           }\r
@@ -664,13 +668,6 @@ PageTableMap (
   //\r
   // Update the page table when the supplied buffer is sufficient.\r
   //\r
-  ParentAttribute.Uint64                    = 0;\r
-  ParentAttribute.Bits.PageTableBaseAddress = 1;\r
-  ParentAttribute.Bits.Present              = 1;\r
-  ParentAttribute.Bits.ReadWrite            = 1;\r
-  ParentAttribute.Bits.UserSupervisor       = 1;\r
-  ParentAttribute.Bits.Nx                   = 0;\r
-\r
   Status = PageTableLibMapInLevel (\r
              &TopPagingEntry,\r
              &ParentAttribute,\r