]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Dxe/Mem/Page.c
MdeModulePkg: remove PE/COFF header workaround for ELILO on IPF
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Mem / Page.c
index b02bafb4bed9de2e66573f91f2290e7cc796caa0..3b4cc08e7cec9d60454540443635994440fd26d4 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   UEFI Memory page management functions.\r
 \r
-Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -14,8 +14,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include "DxeMain.h"\r
 #include "Imem.h"\r
-\r
-#define EFI_DEFAULT_PAGE_ALLOCATION_ALIGNMENT  (EFI_PAGE_SIZE)\r
+#include "HeapGuard.h"\r
 \r
 //\r
 // Entry for tracking the memory regions for each memory type to coalesce similar memory types\r
@@ -94,7 +93,7 @@ EFI_MEMORY_TYPE_INFORMATION gMemoryTypeInformation[EfiMaxMemoryType + 1] = {
 };\r
 //\r
 // Only used when load module at fixed address feature is enabled. True means the memory is alreay successfully allocated\r
-// and ready to load the module in to specified address.or else, the memory is not ready and module will be loaded at a \r
+// and ready to load the module in to specified address.or else, the memory is not ready and module will be loaded at a\r
 //  address assigned by DXE core.\r
 //\r
 GLOBAL_REMOVE_IF_UNREFERENCED   BOOLEAN       gLoadFixedAddressCodeMemoryReady = FALSE;\r
@@ -179,20 +178,22 @@ CoreAddRange (
   ASSERT_LOCKED (&gMemoryLock);\r
 \r
   DEBUG ((DEBUG_PAGE, "AddRange: %lx-%lx to %d\n", Start, End, Type));\r
-  \r
-  //\r
-  // If memory of type EfiConventionalMemory is being added that includes the page \r
-  // starting at address 0, then zero the page starting at address 0.  This has \r
-  // two benifits.  It helps find NULL pointer bugs and it also maximizes \r
-  // compatibility with operating systems that may evaluate memory in this page \r
-  // for legacy data structures.  If memory of any other type is added starting \r
-  // at address 0, then do not zero the page at address 0 because the page is being \r
+\r
+  //\r
+  // If memory of type EfiConventionalMemory is being added that includes the page\r
+  // starting at address 0, then zero the page starting at address 0.  This has\r
+  // two benifits.  It helps find NULL pointer bugs and it also maximizes\r
+  // compatibility with operating systems that may evaluate memory in this page\r
+  // for legacy data structures.  If memory of any other type is added starting\r
+  // at address 0, then do not zero the page at address 0 because the page is being\r
   // used for other purposes.\r
-  //  \r
+  //\r
   if (Type == EfiConventionalMemory && Start == 0 && (End >= EFI_PAGE_SIZE - 1)) {\r
-    SetMem ((VOID *)(UINTN)Start, EFI_PAGE_SIZE, 0);\r
+    if ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT0) == 0) {\r
+      SetMem ((VOID *)(UINTN)Start, EFI_PAGE_SIZE, 0);\r
+    }\r
   }\r
-  \r
+\r
   //\r
   // Memory map being altered so updated key\r
   //\r
@@ -204,7 +205,7 @@ CoreAddRange (
   // If we are in EFI 1.10 compatability mode no event groups will be\r
   // found and nothing will happen we we call this function. These events\r
   // will get signaled but since a lock is held around the call to this\r
-  // function the notificaiton events will only be called after this funciton\r
+  // function the notificaiton events will only be called after this function\r
   // returns and the lock is released.\r
   //\r
   CoreNotifySignalList (&gEfiEventMemoryMapChangeGuid);\r
@@ -287,12 +288,17 @@ AllocateMemoryMapEntry (
     //\r
     // The list is empty, to allocate one page to refuel the list\r
     //\r
-    FreeDescriptorEntries = CoreAllocatePoolPages (EfiBootServicesData, EFI_SIZE_TO_PAGES(DEFAULT_PAGE_ALLOCATION), DEFAULT_PAGE_ALLOCATION);\r
-    if(FreeDescriptorEntries != NULL) {\r
+    FreeDescriptorEntries = CoreAllocatePoolPages (\r
+                              EfiBootServicesData,\r
+                              EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION_GRANULARITY),\r
+                              DEFAULT_PAGE_ALLOCATION_GRANULARITY,\r
+                              FALSE\r
+                              );\r
+    if (FreeDescriptorEntries != NULL) {\r
       //\r
       // Enque the free memmory map entries into the list\r
       //\r
-      for (Index = 0; Index< DEFAULT_PAGE_ALLOCATION / sizeof(MEMORY_MAP); Index++) {\r
+      for (Index = 0; Index < DEFAULT_PAGE_ALLOCATION_GRANULARITY / sizeof(MEMORY_MAP); Index++) {\r
         FreeDescriptorEntries[Index].Signature = MEMORY_MAP_SIGNATURE;\r
         InsertTailList (&mFreeMemoryMapEntryList, &FreeDescriptorEntries[Index].Link);\r
       }\r
@@ -448,8 +454,8 @@ PromoteMemoryResource (
   return Promoted;\r
 }\r
 /**\r
-  This function try to allocate Runtime code & Boot time code memory range. If LMFA enabled, 2 patchable PCD \r
-  PcdLoadFixAddressRuntimeCodePageNumber & PcdLoadFixAddressBootTimeCodePageNumber which are set by tools will record the \r
+  This function try to allocate Runtime code & Boot time code memory range. If LMFA enabled, 2 patchable PCD\r
+  PcdLoadFixAddressRuntimeCodePageNumber & PcdLoadFixAddressBootTimeCodePageNumber which are set by tools will record the\r
   size of boot time and runtime code.\r
 \r
 **/\r
@@ -467,7 +473,7 @@ CoreLoadingFixedAddressHook (
    //\r
    // Make sure these 2 areas are not initialzied.\r
    //\r
-   if (!gLoadFixedAddressCodeMemoryReady) {   \r
+   if (!gLoadFixedAddressCodeMemoryReady) {\r
      RuntimeCodePageNumber = PcdGet32(PcdLoadFixAddressRuntimeCodePageNumber);\r
      BootTimeCodePageNumber= PcdGet32(PcdLoadFixAddressBootTimeCodePageNumber);\r
      RuntimeCodeBase       = (EFI_PHYSICAL_ADDRESS)(gLoadModuleAtFixAddressConfigurationTable.DxeCodeTopAddress - EFI_PAGES_TO_SIZE (RuntimeCodePageNumber));\r
@@ -483,7 +489,7 @@ CoreLoadingFixedAddressHook (
                        );\r
      if (EFI_ERROR(Status)) {\r
        //\r
-       // Runtime memory allocation failed \r
+       // Runtime memory allocation failed\r
        //\r
        return;\r
      }\r
@@ -498,19 +504,19 @@ CoreLoadingFixedAddressHook (
                        );\r
      if (EFI_ERROR(Status)) {\r
        //\r
-        // boot memory allocation failed. Free Runtime code range and will try the allocation again when \r
-        // new memory range is installed.\r
-        //\r
-        CoreFreePages (\r
+        // boot memory allocation failed. Free Runtime code range and will try the allocation again when\r
+        // new memory range is installed.\r
+        //\r
+        CoreFreePages (\r
               RuntimeCodeBase,\r
               RuntimeCodePageNumber\r
               );\r
        return;\r
      }\r
      gLoadFixedAddressCodeMemoryReady = TRUE;\r
-   } \r
+   }\r
    return;\r
-}  \r
+}\r
 \r
 /**\r
   Called to initialize the memory map and add descriptors to\r
@@ -539,7 +545,7 @@ CoreAddMemoryDescriptor (
   EFI_STATUS                  Status;\r
   UINTN                       Index;\r
   UINTN                       FreeIndex;\r
-  \r
+\r
   if ((Start & EFI_PAGE_MASK) != 0) {\r
     return;\r
   }\r
@@ -553,13 +559,16 @@ CoreAddMemoryDescriptor (
   CoreFreeMemoryMapStack ();\r
   CoreReleaseMemoryLock ();\r
 \r
+  ApplyMemoryProtectionPolicy (EfiMaxMemoryType, Type, Start,\r
+    LShiftU64 (NumberOfPages, EFI_PAGE_SHIFT));\r
+\r
   //\r
   // If Loading Module At Fixed Address feature is enabled. try to allocate memory with Runtime code & Boot time code type\r
   //\r
   if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0) {\r
     CoreLoadingFixedAddressHook();\r
   }\r
-  \r
+\r
   //\r
   // Check to see if the statistics for the different memory types have already been established\r
   //\r
@@ -567,7 +576,7 @@ CoreAddMemoryDescriptor (
     return;\r
   }\r
 \r
-  \r
+\r
   //\r
   // Loop through each memory type in the order specified by the gMemoryTypeInformation[] array\r
   //\r
@@ -751,6 +760,17 @@ CoreConvertPagesEx (
       return EFI_NOT_FOUND;\r
     }\r
 \r
+    //\r
+    // If we are converting the type of the range from EfiConventionalMemory to\r
+    // another type, we have to ensure that the entire range is covered by a\r
+    // single entry.\r
+    //\r
+    if (ChangingType && (NewType != EfiConventionalMemory)) {\r
+      if (Entry->End < End) {\r
+        DEBUG ((DEBUG_ERROR | DEBUG_PAGE, "ConvertPages: range %lx - %lx covers multiple entries\n", Start, End));\r
+        return EFI_NOT_FOUND;\r
+      }\r
+    }\r
     //\r
     // Convert range to the end, or to the end of the descriptor\r
     // if that's all we've got\r
@@ -774,7 +794,12 @@ CoreConvertPagesEx (
       // Debug code - verify conversion is allowed\r
       //\r
       if (!(NewType == EfiConventionalMemory ? 1 : 0) ^ (Entry->Type == EfiConventionalMemory ? 1 : 0)) {\r
-        DEBUG ((DEBUG_ERROR | DEBUG_PAGE, "ConvertPages: Incompatible memory types\n"));\r
+        DEBUG ((DEBUG_ERROR | DEBUG_PAGE, "ConvertPages: Incompatible memory types, "));\r
+        if (Entry->Type == EfiConventionalMemory) {\r
+          DEBUG ((DEBUG_ERROR | DEBUG_PAGE, "the pages to free have been freed\n"));\r
+        } else {\r
+          DEBUG ((DEBUG_ERROR | DEBUG_PAGE, "the pages to allocate have been allocated\n"));\r
+        }\r
         return EFI_NOT_FOUND;\r
       }\r
 \r
@@ -972,6 +997,7 @@ CoreUpdateMemoryAttributes (
   @param  NewType                The type of memory the range is going to be\r
                                  turned into\r
   @param  Alignment              Bits to align with\r
+  @param  NeedGuard              Flag to indicate Guard page is needed or not\r
 \r
   @return The base address of the range, or 0 if the range was not found\r
 \r
@@ -982,7 +1008,8 @@ CoreFindFreePagesI (
   IN UINT64           MinAddress,\r
   IN UINT64           NumberOfPages,\r
   IN EFI_MEMORY_TYPE  NewType,\r
-  IN UINTN            Alignment\r
+  IN UINTN            Alignment,\r
+  IN BOOLEAN          NeedGuard\r
   )\r
 {\r
   UINT64          NumberOfBytes;\r
@@ -1074,6 +1101,17 @@ CoreFindFreePagesI (
       // If this is the best match so far remember it\r
       //\r
       if (DescEnd > Target) {\r
+        if (NeedGuard) {\r
+          DescEnd = AdjustMemoryS (\r
+                      DescEnd + 1 - DescNumberOfBytes,\r
+                      DescNumberOfBytes,\r
+                      NumberOfBytes\r
+                      );\r
+          if (DescEnd == 0) {\r
+            continue;\r
+          }\r
+        }\r
+\r
         Target = DescEnd;\r
       }\r
     }\r
@@ -1104,6 +1142,7 @@ CoreFindFreePagesI (
   @param  NewType                The type of memory the range is going to be\r
                                  turned into\r
   @param  Alignment              Bits to align with\r
+  @param  NeedGuard              Flag to indicate Guard page is needed or not\r
 \r
   @return The base address of the range, or 0 if the range was not found.\r
 \r
@@ -1113,7 +1152,8 @@ FindFreePages (
     IN UINT64           MaxAddress,\r
     IN UINT64           NoPages,\r
     IN EFI_MEMORY_TYPE  NewType,\r
-    IN UINTN            Alignment\r
+    IN UINTN            Alignment,\r
+    IN BOOLEAN          NeedGuard\r
     )\r
 {\r
   UINT64   Start;\r
@@ -1123,11 +1163,12 @@ FindFreePages (
   //\r
   if ((UINT32)NewType < EfiMaxMemoryType && MaxAddress >= mMemoryTypeStatistics[NewType].MaximumAddress) {\r
     Start = CoreFindFreePagesI (\r
-              mMemoryTypeStatistics[NewType].MaximumAddress, \r
-              mMemoryTypeStatistics[NewType].BaseAddress, \r
-              NoPages, \r
-              NewType, \r
-              Alignment\r
+              mMemoryTypeStatistics[NewType].MaximumAddress,\r
+              mMemoryTypeStatistics[NewType].BaseAddress,\r
+              NoPages,\r
+              NewType,\r
+              Alignment,\r
+              NeedGuard\r
               );\r
     if (Start != 0) {\r
       return Start;\r
@@ -1138,7 +1179,8 @@ FindFreePages (
   // Attempt to find free pages in the default allocation bin\r
   //\r
   if (MaxAddress >= mDefaultMaximumAddress) {\r
-    Start = CoreFindFreePagesI (mDefaultMaximumAddress, 0, NoPages, NewType, Alignment);\r
+    Start = CoreFindFreePagesI (mDefaultMaximumAddress, 0, NoPages, NewType,\r
+                                Alignment, NeedGuard);\r
     if (Start != 0) {\r
       if (Start < mDefaultBaseAddress) {\r
         mDefaultBaseAddress = Start;\r
@@ -1148,12 +1190,13 @@ FindFreePages (
   }\r
 \r
   //\r
-  // The allocation did not succeed in any of the prefered bins even after \r
-  // promoting resources. Attempt to find free pages anywhere is the requested \r
-  // address range.  If this allocation fails, then there are not enough \r
+  // The allocation did not succeed in any of the prefered bins even after\r
+  // promoting resources. Attempt to find free pages anywhere is the requested\r
+  // address range.  If this allocation fails, then there are not enough\r
   // resources anywhere to satisfy the request.\r
   //\r
-  Start = CoreFindFreePagesI (MaxAddress, 0, NoPages, NewType, Alignment);\r
+  Start = CoreFindFreePagesI (MaxAddress, 0, NoPages, NewType, Alignment,\r
+                              NeedGuard);\r
   if (Start != 0) {\r
     return Start;\r
   }\r
@@ -1168,7 +1211,7 @@ FindFreePages (
   //\r
   // If any memory resources were promoted, then re-attempt the allocation\r
   //\r
-  return FindFreePages (MaxAddress, NoPages, NewType, Alignment);\r
+  return FindFreePages (MaxAddress, NoPages, NewType, Alignment, NeedGuard);\r
 }\r
 \r
 \r
@@ -1181,6 +1224,7 @@ FindFreePages (
   @param  NumberOfPages          The number of pages to allocate\r
   @param  Memory                 A pointer to receive the base allocated memory\r
                                  address\r
+  @param  NeedGuard              Flag to indicate Guard page is needed or not\r
 \r
   @return Status. On success, Memory is filled in with the base address allocated\r
   @retval EFI_INVALID_PARAMETER  Parameters violate checking rules defined in\r
@@ -1196,7 +1240,8 @@ CoreInternalAllocatePages (
   IN EFI_ALLOCATE_TYPE      Type,\r
   IN EFI_MEMORY_TYPE        MemoryType,\r
   IN UINTN                  NumberOfPages,\r
-  IN OUT EFI_PHYSICAL_ADDRESS  *Memory\r
+  IN OUT EFI_PHYSICAL_ADDRESS  *Memory,\r
+  IN BOOLEAN                NeedGuard\r
   )\r
 {\r
   EFI_STATUS      Status;\r
@@ -1219,14 +1264,14 @@ CoreInternalAllocatePages (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  Alignment = EFI_DEFAULT_PAGE_ALLOCATION_ALIGNMENT;\r
+  Alignment = DEFAULT_PAGE_ALLOCATION_GRANULARITY;\r
 \r
   if  (MemoryType == EfiACPIReclaimMemory   ||\r
        MemoryType == EfiACPIMemoryNVS       ||\r
        MemoryType == EfiRuntimeServicesCode ||\r
        MemoryType == EfiRuntimeServicesData) {\r
 \r
-    Alignment = EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT;\r
+    Alignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY;\r
   }\r
 \r
   if (Type == AllocateAddress) {\r
@@ -1266,7 +1311,7 @@ CoreInternalAllocatePages (
     End = Start + NumberOfBytes - 1;\r
 \r
     if ((Start >= End) ||\r
-        (Start > MaxAddress) || \r
+        (Start > MaxAddress) ||\r
         (End > MaxAddress)) {\r
       return EFI_NOT_FOUND;\r
     }\r
@@ -1282,7 +1327,8 @@ CoreInternalAllocatePages (
   // If not a specific address, then find an address to allocate\r
   //\r
   if (Type != AllocateAddress) {\r
-    Start = FindFreePages (MaxAddress, NumberOfPages, MemoryType, Alignment);\r
+    Start = FindFreePages (MaxAddress, NumberOfPages, MemoryType, Alignment,\r
+                           NeedGuard);\r
     if (Start == 0) {\r
       Status = EFI_OUT_OF_RESOURCES;\r
       goto Done;\r
@@ -1292,12 +1338,19 @@ CoreInternalAllocatePages (
   //\r
   // Convert pages from FreeMemory to the requested type\r
   //\r
-  Status = CoreConvertPages (Start, NumberOfPages, MemoryType);\r
+  if (NeedGuard) {\r
+    Status = CoreConvertPagesWithGuard(Start, NumberOfPages, MemoryType);\r
+  } else {\r
+    Status = CoreConvertPages(Start, NumberOfPages, MemoryType);\r
+  }\r
 \r
 Done:\r
   CoreReleaseMemoryLock ();\r
 \r
   if (!EFI_ERROR (Status)) {\r
+    if (NeedGuard) {\r
+      SetGuardForMemory (Start, NumberOfPages);\r
+    }\r
     *Memory = Start;\r
   }\r
 \r
@@ -1332,8 +1385,11 @@ CoreAllocatePages (
   )\r
 {\r
   EFI_STATUS  Status;\r
+  BOOLEAN     NeedGuard;\r
 \r
-  Status = CoreInternalAllocatePages (Type, MemoryType, NumberOfPages, Memory);\r
+  NeedGuard = IsPageTypeToGuard (MemoryType, Type) && !mOnGuarding;\r
+  Status = CoreInternalAllocatePages (Type, MemoryType, NumberOfPages, Memory,\r
+                                      NeedGuard);\r
   if (!EFI_ERROR (Status)) {\r
     CoreUpdateProfile (\r
       (EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0),\r
@@ -1344,6 +1400,8 @@ CoreAllocatePages (
       NULL\r
       );\r
     InstallMemoryAttributesTableOnMemoryAllocation (MemoryType);\r
+    ApplyMemoryProtectionPolicy (EfiConventionalMemory, MemoryType, *Memory,\r
+      EFI_PAGES_TO_SIZE (NumberOfPages));\r
   }\r
   return Status;\r
 }\r
@@ -1372,6 +1430,7 @@ CoreInternalFreePages (
   LIST_ENTRY      *Link;\r
   MEMORY_MAP      *Entry;\r
   UINTN           Alignment;\r
+  BOOLEAN         IsGuarded;\r
 \r
   //\r
   // Free the range\r
@@ -1381,6 +1440,7 @@ CoreInternalFreePages (
   //\r
   // Find the entry that the covers the range\r
   //\r
+  IsGuarded = FALSE;\r
   Entry = NULL;\r
   for (Link = gMemoryMap.ForwardLink; Link != &gMemoryMap; Link = Link->ForwardLink) {\r
     Entry = CR(Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);\r
@@ -1393,7 +1453,7 @@ CoreInternalFreePages (
     goto Done;\r
   }\r
 \r
-  Alignment = EFI_DEFAULT_PAGE_ALLOCATION_ALIGNMENT;\r
+  Alignment = DEFAULT_PAGE_ALLOCATION_GRANULARITY;\r
 \r
   ASSERT (Entry != NULL);\r
   if  (Entry->Type == EfiACPIReclaimMemory   ||\r
@@ -1401,7 +1461,7 @@ CoreInternalFreePages (
        Entry->Type == EfiRuntimeServicesCode ||\r
        Entry->Type == EfiRuntimeServicesData) {\r
 \r
-    Alignment = EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT;\r
+    Alignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY;\r
 \r
   }\r
 \r
@@ -1417,10 +1477,13 @@ CoreInternalFreePages (
     *MemoryType = Entry->Type;\r
   }\r
 \r
-  Status = CoreConvertPages (Memory, NumberOfPages, EfiConventionalMemory);\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    goto Done;\r
+  IsGuarded = IsPageTypeToGuard (Entry->Type, AllocateAnyPages) &&\r
+              IsMemoryGuarded (Memory);\r
+  if (IsGuarded) {\r
+    Status = CoreConvertPagesWithGuard (Memory, NumberOfPages,\r
+                                        EfiConventionalMemory);\r
+  } else {\r
+    Status = CoreConvertPages (Memory, NumberOfPages, EfiConventionalMemory);\r
   }\r
 \r
 Done:\r
@@ -1460,6 +1523,8 @@ CoreFreePages (
       NULL\r
       );\r
     InstallMemoryAttributesTableOnMemoryAllocation (MemoryType);\r
+    ApplyMemoryProtectionPolicy (MemoryType, EfiConventionalMemory, Memory,\r
+      EFI_PAGES_TO_SIZE (NumberOfPages));\r
   }\r
   return Status;\r
 }\r
@@ -1506,7 +1571,7 @@ MergeMemoryMapDescriptor (
     //\r
     // Check to see if MemoryMapDescriptor is immediately above MemoryMap\r
     //\r
-    if (MemoryMap->PhysicalStart + EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages) == MemoryMapDescriptor->PhysicalStart) { \r
+    if (MemoryMap->PhysicalStart + EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages) == MemoryMapDescriptor->PhysicalStart) {\r
       //\r
       // Merge MemoryMapDescriptor into MemoryMap\r
       //\r
@@ -1539,7 +1604,7 @@ MergeMemoryMapDescriptor (
   //\r
   // MemoryMapDescrtiptor could not be merged with any descriptors in MemoryMap.\r
   //\r
-  // Return the slot immediately after MemoryMapDescriptor as the next available \r
+  // Return the slot immediately after MemoryMapDescriptor as the next available\r
   // slot in the MemoryMap array\r
   //\r
   return NEXT_MEMORY_DESCRIPTOR (MemoryMapDescriptor, DescriptorSize);\r
@@ -1595,6 +1660,7 @@ CoreGetMemoryMap (
   EFI_GCD_MAP_ENTRY                 MergeGcdMapEntry;\r
   EFI_MEMORY_TYPE                   Type;\r
   EFI_MEMORY_DESCRIPTOR             *MemoryMapStart;\r
+  EFI_MEMORY_DESCRIPTOR             *MemoryMapEnd;\r
 \r
   //\r
   // Make sure the parameters are valid\r
@@ -1612,7 +1678,7 @@ CoreGetMemoryMap (
   NumberOfEntries = 0;\r
   for (Link = mGcdMemorySpaceMap.ForwardLink; Link != &mGcdMemorySpaceMap; Link = Link->ForwardLink) {\r
     GcdMapEntry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);\r
-    if ((GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypePersistentMemory) || \r
+    if ((GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypePersistent) ||\r
         (GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeReserved) ||\r
         ((GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) &&\r
         ((GcdMapEntry->Attributes & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME))) {\r
@@ -1698,13 +1764,13 @@ CoreGetMemoryMap (
     }\r
 \r
     //\r
-    // Check to see if the new Memory Map Descriptor can be merged with an \r
+    // Check to see if the new Memory Map Descriptor can be merged with an\r
     // existing descriptor if they are adjacent and have the same attributes\r
     //\r
     MemoryMap = MergeMemoryMapDescriptor (MemoryMapStart, MemoryMap, Size);\r
   }\r
 \r
\r
+\r
   ZeroMem (&MergeGcdMapEntry, sizeof (MergeGcdMapEntry));\r
   GcdMapEntry = NULL;\r
   for (Link = mGcdMemorySpaceMap.ForwardLink; ; Link = Link->ForwardLink) {\r
@@ -1713,8 +1779,8 @@ CoreGetMemoryMap (
       // Merge adjacent same type and attribute GCD memory range\r
       //\r
       GcdMapEntry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);\r
-  \r
-      if ((MergeGcdMapEntry.Capabilities == GcdMapEntry->Capabilities) && \r
+\r
+      if ((MergeGcdMapEntry.Capabilities == GcdMapEntry->Capabilities) &&\r
           (MergeGcdMapEntry.Attributes == GcdMapEntry->Attributes) &&\r
           (MergeGcdMapEntry.GcdMemoryType == GcdMapEntry->GcdMemoryType) &&\r
           (MergeGcdMapEntry.GcdIoType == GcdMapEntry->GcdIoType)) {\r
@@ -1727,19 +1793,19 @@ CoreGetMemoryMap (
         ((MergeGcdMapEntry.GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) &&\r
         ((MergeGcdMapEntry.Attributes & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME))) {\r
       //\r
-      // Page Align GCD range is required. When it is converted to EFI_MEMORY_DESCRIPTOR, \r
-      // it will be recorded as page PhysicalStart and NumberOfPages. \r
+      // Page Align GCD range is required. When it is converted to EFI_MEMORY_DESCRIPTOR,\r
+      // it will be recorded as page PhysicalStart and NumberOfPages.\r
       //\r
       ASSERT ((MergeGcdMapEntry.BaseAddress & EFI_PAGE_MASK) == 0);\r
       ASSERT (((MergeGcdMapEntry.EndAddress - MergeGcdMapEntry.BaseAddress + 1) & EFI_PAGE_MASK) == 0);\r
-      \r
-      // \r
+\r
+      //\r
       // Create EFI_MEMORY_DESCRIPTOR for every Reserved and runtime MMIO GCD entries\r
       //\r
       MemoryMap->PhysicalStart = MergeGcdMapEntry.BaseAddress;\r
       MemoryMap->VirtualStart  = 0;\r
       MemoryMap->NumberOfPages = RShiftU64 ((MergeGcdMapEntry.EndAddress - MergeGcdMapEntry.BaseAddress + 1), EFI_PAGE_SHIFT);\r
-      MemoryMap->Attribute     = (MergeGcdMapEntry.Attributes & ~EFI_MEMORY_PORT_IO) | \r
+      MemoryMap->Attribute     = (MergeGcdMapEntry.Attributes & ~EFI_MEMORY_PORT_IO) |\r
                                 (MergeGcdMapEntry.Capabilities & (EFI_MEMORY_RP | EFI_MEMORY_WP | EFI_MEMORY_XP | EFI_MEMORY_RO |\r
                                 EFI_MEMORY_UC | EFI_MEMORY_UCE | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB));\r
 \r
@@ -1754,33 +1820,33 @@ CoreGetMemoryMap (
       }\r
 \r
       //\r
-      // Check to see if the new Memory Map Descriptor can be merged with an \r
+      // Check to see if the new Memory Map Descriptor can be merged with an\r
       // existing descriptor if they are adjacent and have the same attributes\r
       //\r
       MemoryMap = MergeMemoryMapDescriptor (MemoryMapStart, MemoryMap, Size);\r
     }\r
-    \r
-    if (MergeGcdMapEntry.GcdMemoryType == EfiGcdMemoryTypePersistentMemory) {\r
+\r
+    if (MergeGcdMapEntry.GcdMemoryType == EfiGcdMemoryTypePersistent) {\r
       //\r
-      // Page Align GCD range is required. When it is converted to EFI_MEMORY_DESCRIPTOR, \r
-      // it will be recorded as page PhysicalStart and NumberOfPages. \r
+      // Page Align GCD range is required. When it is converted to EFI_MEMORY_DESCRIPTOR,\r
+      // it will be recorded as page PhysicalStart and NumberOfPages.\r
       //\r
       ASSERT ((MergeGcdMapEntry.BaseAddress & EFI_PAGE_MASK) == 0);\r
       ASSERT (((MergeGcdMapEntry.EndAddress - MergeGcdMapEntry.BaseAddress + 1) & EFI_PAGE_MASK) == 0);\r
 \r
-      // \r
+      //\r
       // Create EFI_MEMORY_DESCRIPTOR for every Persistent GCD entries\r
       //\r
       MemoryMap->PhysicalStart = MergeGcdMapEntry.BaseAddress;\r
       MemoryMap->VirtualStart  = 0;\r
       MemoryMap->NumberOfPages = RShiftU64 ((MergeGcdMapEntry.EndAddress - MergeGcdMapEntry.BaseAddress + 1), EFI_PAGE_SHIFT);\r
-      MemoryMap->Attribute     = MergeGcdMapEntry.Attributes | EFI_MEMORY_NV | \r
+      MemoryMap->Attribute     = MergeGcdMapEntry.Attributes | EFI_MEMORY_NV |\r
                                 (MergeGcdMapEntry.Capabilities & (EFI_MEMORY_RP | EFI_MEMORY_WP | EFI_MEMORY_XP | EFI_MEMORY_RO |\r
                                 EFI_MEMORY_UC | EFI_MEMORY_UCE | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB));\r
       MemoryMap->Type          = EfiPersistentMemory;\r
-      \r
+\r
       //\r
-      // Check to see if the new Memory Map Descriptor can be merged with an \r
+      // Check to see if the new Memory Map Descriptor can be merged with an\r
       // existing descriptor if they are adjacent and have the same attributes\r
       //\r
       MemoryMap = MergeMemoryMapDescriptor (MemoryMapStart, MemoryMap, Size);\r
@@ -1804,6 +1870,27 @@ CoreGetMemoryMap (
   //\r
   BufferSize = ((UINT8 *)MemoryMap - (UINT8 *)MemoryMapStart);\r
 \r
+  //\r
+  // Note: Some OSs will treat EFI_MEMORY_DESCRIPTOR.Attribute as really\r
+  //       set attributes and change memory paging attribute accordingly.\r
+  //       But current EFI_MEMORY_DESCRIPTOR.Attribute is assigned by\r
+  //       value from Capabilities in GCD memory map. This might cause\r
+  //       boot problems. Clearing all paging related capabilities can\r
+  //       workaround it. Following code is supposed to be removed once\r
+  //       the usage of EFI_MEMORY_DESCRIPTOR.Attribute is clarified in\r
+  //       UEFI spec and adopted by both EDK-II Core and all supported\r
+  //       OSs.\r
+  //\r
+  MemoryMapEnd = MemoryMap;\r
+  MemoryMap = MemoryMapStart;\r
+  while (MemoryMap < MemoryMapEnd) {\r
+    MemoryMap->Attribute &= ~(UINT64)(EFI_MEMORY_RP | EFI_MEMORY_RO |\r
+                                      EFI_MEMORY_XP);\r
+    MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, Size);\r
+  }\r
+  MergeMemoryMap (MemoryMapStart, &BufferSize, Size);\r
+  MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMapStart + BufferSize);\r
+\r
   Status = EFI_SUCCESS;\r
 \r
 Done:\r
@@ -1820,6 +1907,12 @@ Done:
 \r
   *MemoryMapSize = BufferSize;\r
 \r
+  DEBUG_CODE (\r
+    if (PcdGet8 (PcdHeapGuardPropertyMask) & (BIT1|BIT0)) {\r
+      DumpGuardedMemoryBitmap ();\r
+    }\r
+  );\r
+\r
   return Status;\r
 }\r
 \r
@@ -1831,6 +1924,7 @@ Done:
   @param  PoolType               The type of memory for the new pool pages\r
   @param  NumberOfPages          No of pages to allocate\r
   @param  Alignment              Bits to align.\r
+  @param  NeedGuard              Flag to indicate Guard page is needed or not\r
 \r
   @return The allocated memory, or NULL\r
 \r
@@ -1839,7 +1933,8 @@ VOID *
 CoreAllocatePoolPages (\r
   IN EFI_MEMORY_TYPE    PoolType,\r
   IN UINTN              NumberOfPages,\r
-  IN UINTN              Alignment\r
+  IN UINTN              Alignment,\r
+  IN BOOLEAN            NeedGuard\r
   )\r
 {\r
   UINT64            Start;\r
@@ -1847,7 +1942,8 @@ CoreAllocatePoolPages (
   //\r
   // Find the pages to convert\r
   //\r
-  Start = FindFreePages (MAX_ADDRESS, NumberOfPages, PoolType, Alignment);\r
+  Start = FindFreePages (MAX_ADDRESS, NumberOfPages, PoolType, Alignment,\r
+                         NeedGuard);\r
 \r
   //\r
   // Convert it to boot services data\r
@@ -1855,7 +1951,11 @@ CoreAllocatePoolPages (
   if (Start == 0) {\r
     DEBUG ((DEBUG_ERROR | DEBUG_PAGE, "AllocatePoolPages: failed to allocate %d pages\n", (UINT32)NumberOfPages));\r
   } else {\r
-    CoreConvertPages (Start, NumberOfPages, PoolType);\r
+    if (NeedGuard) {\r
+      CoreConvertPagesWithGuard (Start, NumberOfPages, PoolType);\r
+    } else {\r
+      CoreConvertPages (Start, NumberOfPages, PoolType);\r
+    }\r
   }\r
 \r
   return (VOID *)(UINTN) Start;\r
@@ -1918,12 +2018,12 @@ CoreTerminateMemoryMap (
         if (mMemoryTypeStatistics[Entry->Type].Runtime) {\r
           ASSERT (Entry->Type != EfiACPIReclaimMemory);\r
           ASSERT (Entry->Type != EfiACPIMemoryNVS);\r
-          if ((Entry->Start & (EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT - 1)) != 0) {\r
+          if ((Entry->Start & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) {\r
             DEBUG((DEBUG_ERROR | DEBUG_PAGE, "ExitBootServices: A RUNTIME memory entry is not on a proper alignment.\n"));\r
             Status =  EFI_INVALID_PARAMETER;\r
             goto Done;\r
           }\r
-          if (((Entry->End + 1) & (EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT - 1)) != 0) {\r
+          if (((Entry->End + 1) & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) {\r
             DEBUG((DEBUG_ERROR | DEBUG_PAGE, "ExitBootServices: A RUNTIME memory entry is not on a proper alignment.\n"));\r
             Status =  EFI_INVALID_PARAMETER;\r
             goto Done;\r