// ParentPagingEntry ONLY is deferenced for checking Present and MustBeOne bits\r
// when Modify is FALSE.\r
//\r
-\r
- if (ParentPagingEntry->Pce.Present == 0) {\r
- //\r
- // [LinearAddress, LinearAddress + Length] contains non-present range.\r
- //\r
- Status = IsAttributesAndMaskValidForNonPresentEntry (Attribute, Mask);\r
- if (RETURN_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Check the attribute in ParentPagingEntry is equal to attribute calculated by input Attribue and Mask.\r
- //\r
- PleBAttribute.Uint64 = PageTableLibGetPleBMapAttribute (&ParentPagingEntry->PleB, ParentAttribute);\r
- if ((IA32_MAP_ATTRIBUTE_ATTRIBUTES (&PleBAttribute) & IA32_MAP_ATTRIBUTE_ATTRIBUTES (Mask))\r
- == (IA32_MAP_ATTRIBUTE_ATTRIBUTES (Attribute) & IA32_MAP_ATTRIBUTE_ATTRIBUTES (Mask)))\r
- {\r
- return RETURN_SUCCESS;\r
- }\r
-\r
+ if ((ParentPagingEntry->Pce.Present == 0) || IsPle (ParentPagingEntry, Level + 1)) {\r
//\r
- // The parent entry is CR3 or PML5E/PML4E/PDPTE/PDE.\r
+ // When ParentPagingEntry is non-present, parent entry is CR3 or PML5E/PML4E/PDPTE/PDE.\r
// It does NOT point to an existing page directory.\r
+ // When ParentPagingEntry is present, parent entry is leaf PDPTE_1G or PDE_2M. Split to 2M or 4K pages.\r
+ // Note: it's impossible the parent entry is a PTE_4K.\r
//\r
- ASSERT (Buffer == NULL || *BufferSize >= SIZE_4KB);\r
- CreateNew = TRUE;\r
- *BufferSize -= SIZE_4KB;\r
-\r
- if (Modify) {\r
- ParentPagingEntry->Uintn = (UINTN)Buffer + *BufferSize;\r
- ZeroMem ((VOID *)ParentPagingEntry->Uintn, SIZE_4KB);\r
- //\r
- // Set default attribute bits for PML5E/PML4E/PDPTE/PDE.\r
- //\r
- PageTableLibSetPnle (&ParentPagingEntry->Pnle, &NopAttribute, &AllOneMask);\r
- } else {\r
+ PleBAttribute.Uint64 = PageTableLibGetPleBMapAttribute (&ParentPagingEntry->PleB, ParentAttribute);\r
+ if (ParentPagingEntry->Pce.Present == 0) {\r
//\r
- // Just make sure Present and MustBeZero (PageSize) bits are accurate.\r
+ // [LinearAddress, LinearAddress + Length] contains non-present range.\r
//\r
+ Status = IsAttributesAndMaskValidForNonPresentEntry (Attribute, Mask);\r
+ if (RETURN_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
OneOfPagingEntry.Pnle.Uint64 = 0;\r
+ } else {\r
+ PageTableLibSetPle (Level, &OneOfPagingEntry, 0, &PleBAttribute, &AllOneMask);\r
}\r
- } else if (IsPle (ParentPagingEntry, Level + 1)) {\r
- //\r
- // The parent entry is a PDPTE_1G or PDE_2M. Split to 2M or 4K pages.\r
- // Note: it's impossible the parent entry is a PTE_4K.\r
- //\r
+\r
//\r
- // Use NOP attributes as the attribute of grand-parents because CPU will consider\r
- // the actual attributes of grand-parents when determing the memory type.\r
+ // Check if the attribute, the physical address calculated by ParentPagingEntry is equal to\r
+ // the attribute, the physical address calculated by input Attribue and Mask.\r
//\r
- PleBAttribute.Uint64 = PageTableLibGetPleBMapAttribute (&ParentPagingEntry->PleB, ParentAttribute);\r
if ((IA32_MAP_ATTRIBUTE_ATTRIBUTES (&PleBAttribute) & IA32_MAP_ATTRIBUTE_ATTRIBUTES (Mask))\r
== (IA32_MAP_ATTRIBUTE_ATTRIBUTES (Attribute) & IA32_MAP_ATTRIBUTE_ATTRIBUTES (Mask)))\r
{\r
- //\r
- // This function is called when the memory length is less than the region length of the parent level.\r
- // No need to split the page when the attributes equal.\r
- //\r
if ((Mask->Bits.PageTableBaseAddressLow == 0) && (Mask->Bits.PageTableBaseAddressHigh == 0)) {\r
return RETURN_SUCCESS;\r
}\r
\r
+ //\r
+ // Non-present entry won't reach there since:\r
+ // 1.When map non-present entry to present, the attribute must be different.\r
+ // 2.When still map non-present entry to non-present, PageTableBaseAddressLow and High in Mask must be 0.\r
+ //\r
+ ASSERT (ParentPagingEntry->Pce.Present == 1);\r
PhysicalAddrInEntry = IA32_MAP_ATTRIBUTE_PAGE_TABLE_BASE_ADDRESS (&PleBAttribute) + MultU64x32 (RegionLength, (UINT32)PagingEntryIndex);\r
PhysicalAddrInAttr = (IA32_MAP_ATTRIBUTE_PAGE_TABLE_BASE_ADDRESS (Attribute) + Offset) & (~RegionMask);\r
if (PhysicalAddrInEntry == PhysicalAddrInAttr) {\r
ASSERT (Buffer == NULL || *BufferSize >= SIZE_4KB);\r
CreateNew = TRUE;\r
*BufferSize -= SIZE_4KB;\r
- PageTableLibSetPle (Level, &OneOfPagingEntry, 0, &PleBAttribute, &AllOneMask);\r
+\r
if (Modify) {\r
- //\r
- // Create 512 child-level entries that map to 2M/4K.\r
- //\r
PagingEntry = (IA32_PAGING_ENTRY *)((UINTN)Buffer + *BufferSize);\r
ZeroMem (PagingEntry, SIZE_4KB);\r
\r
- for (SubOffset = 0, Index = 0; Index < 512; Index++) {\r
- PagingEntry[Index].Uint64 = OneOfPagingEntry.Uint64 + SubOffset;\r
- SubOffset += RegionLength;\r
+ if (ParentPagingEntry->Pce.Present) {\r
+ //\r
+ // Create 512 child-level entries that map to 2M/4K.\r
+ //\r
+ for (SubOffset = 0, Index = 0; Index < 512; Index++) {\r
+ PagingEntry[Index].Uint64 = OneOfPagingEntry.Uint64 + SubOffset;\r
+ SubOffset += RegionLength;\r
+ }\r
}\r
\r
//\r