]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/PiSmmCore/Page.c
MdeModulePkg: remove PE/COFF header workaround for ELILO on IPF
[mirror_edk2.git] / MdeModulePkg / Core / PiSmmCore / Page.c
index 4154c2e6a1ec08e7c805e4c4b871022e919ab106..25f72d309b3adee1b8bb848a03baa850b066c74f 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   SMM Memory page management functions.\r
 \r
-  Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials are licensed and made available\r
   under the terms and conditions of the BSD License which accompanies this\r
   distribution.  The full text of the license may be found at\r
@@ -64,6 +64,8 @@ LIST_ENTRY   mFreeMemoryMapEntryList = INITIALIZE_LIST_HEAD_VARIABLE (mFreeMemor
   @param[out]  Memory                 A pointer to receive the base allocated memory\r
                                       address.\r
   @param[in]   AddRegion              If this memory is new added region.\r
+  @param[in]   NeedGuard              Flag to indicate Guard page is needed\r
+                                      or not\r
 \r
   @retval EFI_INVALID_PARAMETER  Parameters violate checking rules defined in spec.\r
   @retval EFI_NOT_FOUND          Could not allocate pages match the requirement.\r
@@ -77,7 +79,8 @@ SmmInternalAllocatePagesEx (
   IN  EFI_MEMORY_TYPE       MemoryType,\r
   IN  UINTN                 NumberOfPages,\r
   OUT EFI_PHYSICAL_ADDRESS  *Memory,\r
-  IN  BOOLEAN               AddRegion\r
+  IN  BOOLEAN               AddRegion,\r
+  IN  BOOLEAN               NeedGuard\r
   );\r
 \r
 /**\r
@@ -112,7 +115,8 @@ AllocateMemoryMapEntry (
                EfiRuntimeServicesData,\r
                EFI_SIZE_TO_PAGES (RUNTIME_PAGE_ALLOCATION_GRANULARITY),\r
                &Mem,\r
-               TRUE\r
+               TRUE,\r
+               FALSE\r
                );\r
     ASSERT_EFI_ERROR (Status);\r
     if(!EFI_ERROR (Status)) {\r
@@ -242,6 +246,8 @@ RemoveOldEntry (
   )\r
 {\r
   RemoveEntryList (&Entry->Link);\r
+  Entry->Link.ForwardLink = NULL;\r
+\r
   if (!Entry->FromStack) {\r
     InsertTailList (&mFreeMemoryMapEntryList, &Entry->Link);\r
   }\r
@@ -445,128 +451,7 @@ GetSmmMemoryMapEntryCount (
   return Count;\r
 }\r
 \r
-/**\r
-  Dump Smm memory map entry.\r
-**/\r
-VOID\r
-DumpSmmMemoryMapEntry (\r
-  VOID\r
-  )\r
-{\r
-  LIST_ENTRY               *Link;\r
-  MEMORY_MAP               *Entry;\r
-  EFI_PHYSICAL_ADDRESS     Last;\r
 \r
-  Last = 0;\r
-  DEBUG ((DEBUG_INFO, "DumpSmmMemoryMapEntry:\n"));\r
-  Link = gMemoryMap.ForwardLink;\r
-  while (Link != &gMemoryMap) {\r
-    Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);\r
-    Link  = Link->ForwardLink;\r
-\r
-    if ((Last != 0) && (Last != (UINT64)-1)) {\r
-      if (Last + 1 != Entry->Start) {\r
-        Last = (UINT64)-1;\r
-      } else {\r
-        Last = Entry->End;\r
-      }\r
-    } else if (Last == 0) {\r
-      Last = Entry->End;\r
-    }\r
-\r
-    DEBUG ((DEBUG_INFO, "Entry (Link - 0x%x)\n", &Entry->Link));\r
-    DEBUG ((DEBUG_INFO, "  Signature         - 0x%x\n", Entry->Signature));\r
-    DEBUG ((DEBUG_INFO, "  Link.ForwardLink  - 0x%x\n", Entry->Link.ForwardLink));\r
-    DEBUG ((DEBUG_INFO, "  Link.BackLink     - 0x%x\n", Entry->Link.BackLink));\r
-    DEBUG ((DEBUG_INFO, "  Type              - 0x%x\n", Entry->Type));\r
-    DEBUG ((DEBUG_INFO, "  Start             - 0x%016lx\n", Entry->Start));\r
-    DEBUG ((DEBUG_INFO, "  End               - 0x%016lx\n", Entry->End));\r
-  }\r
-\r
-  ASSERT (Last != (UINT64)-1);\r
-}\r
-\r
-/**\r
-  Dump Smm memory map.\r
-**/\r
-VOID\r
-DumpSmmMemoryMap (\r
-  VOID\r
-  )\r
-{\r
-  LIST_ENTRY      *Node;\r
-  FREE_PAGE_LIST  *Pages;\r
-\r
-  DEBUG ((DEBUG_INFO, "DumpSmmMemoryMap\n"));\r
-\r
-  Pages = NULL;\r
-  Node = mSmmMemoryMap.ForwardLink;\r
-  while (Node != &mSmmMemoryMap) {\r
-    Pages = BASE_CR (Node, FREE_PAGE_LIST, Link);\r
-    DEBUG ((DEBUG_INFO, "Pages - 0x%x\n", Pages));\r
-    DEBUG ((DEBUG_INFO, "Pages->NumberOfPages - 0x%x\n", Pages->NumberOfPages));\r
-    Node = Node->ForwardLink;\r
-  }\r
-}\r
-\r
-/**\r
-  Check if a Smm base~length is in Smm memory map.\r
-\r
-  @param[in] Base   The base address of Smm memory to be checked.\r
-  @param[in] Length THe length of Smm memory to be checked.\r
-\r
-  @retval TRUE  Smm base~length is in smm memory map.\r
-  @retval FALSE Smm base~length is in smm memory map.\r
-**/\r
-BOOLEAN\r
-SmmMemoryMapConsistencyCheckRange (\r
-  IN EFI_PHYSICAL_ADDRESS Base,\r
-  IN UINTN                Length\r
-  )\r
-{\r
-  LIST_ENTRY               *Link;\r
-  MEMORY_MAP               *Entry;\r
-  BOOLEAN                  Result;\r
-\r
-  Result = FALSE;\r
-  Link = gMemoryMap.ForwardLink;\r
-  while (Link != &gMemoryMap) {\r
-    Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);\r
-    Link  = Link->ForwardLink;\r
-\r
-    if (Entry->Type != EfiConventionalMemory) {\r
-      continue;\r
-    }\r
-    if (Entry->Start == Base && Entry->End == Base + Length - 1) {\r
-      Result = TRUE;\r
-      break;\r
-    }\r
-  }\r
-\r
-  return Result;\r
-}\r
-\r
-/**\r
-  Check the consistency of Smm memory map.\r
-**/\r
-VOID\r
-SmmMemoryMapConsistencyCheck (\r
-  VOID\r
-  )\r
-{\r
-  LIST_ENTRY      *Node;\r
-  FREE_PAGE_LIST  *Pages;\r
-  BOOLEAN         Result;\r
-\r
-  Pages = NULL;\r
-  Node = mSmmMemoryMap.ForwardLink;\r
-  while (Node != &mSmmMemoryMap) {\r
-    Pages = BASE_CR (Node, FREE_PAGE_LIST, Link);\r
-    Result = SmmMemoryMapConsistencyCheckRange ((EFI_PHYSICAL_ADDRESS)(UINTN)Pages, (UINTN)EFI_PAGES_TO_SIZE(Pages->NumberOfPages));\r
-    ASSERT (Result);\r
-    Node = Node->ForwardLink;\r
-  }\r
-}\r
 \r
 /**\r
   Internal Function. Allocate n pages from given free page node.\r
@@ -688,6 +573,8 @@ InternalAllocAddress (
   @param[out]  Memory                 A pointer to receive the base allocated memory\r
                                       address.\r
   @param[in]   AddRegion              If this memory is new added region.\r
+  @param[in]   NeedGuard              Flag to indicate Guard page is needed\r
+                                      or not\r
 \r
   @retval EFI_INVALID_PARAMETER  Parameters violate checking rules defined in spec.\r
   @retval EFI_NOT_FOUND          Could not allocate pages match the requirement.\r
@@ -701,7 +588,8 @@ SmmInternalAllocatePagesEx (
   IN  EFI_MEMORY_TYPE       MemoryType,\r
   IN  UINTN                 NumberOfPages,\r
   OUT EFI_PHYSICAL_ADDRESS  *Memory,\r
-  IN  BOOLEAN               AddRegion\r
+  IN  BOOLEAN               AddRegion,\r
+  IN  BOOLEAN               NeedGuard\r
   )\r
 {\r
   UINTN  RequestedAddress;\r
@@ -723,6 +611,21 @@ SmmInternalAllocatePagesEx (
     case AllocateAnyPages:\r
       RequestedAddress = (UINTN)(-1);\r
     case AllocateMaxAddress:\r
+      if (NeedGuard) {\r
+        *Memory = InternalAllocMaxAddressWithGuard (\r
+                      &mSmmMemoryMap,\r
+                      NumberOfPages,\r
+                      RequestedAddress,\r
+                      MemoryType\r
+                      );\r
+        if (*Memory == (UINTN)-1) {\r
+          return EFI_OUT_OF_RESOURCES;\r
+        } else {\r
+          ASSERT (VerifyMemoryGuard (*Memory, NumberOfPages) == TRUE);\r
+          return EFI_SUCCESS;\r
+        }\r
+      }\r
+\r
       *Memory = InternalAllocMaxAddress (\r
                   &mSmmMemoryMap,\r
                   NumberOfPages,\r
@@ -766,6 +669,8 @@ SmmInternalAllocatePagesEx (
   @param[in]   NumberOfPages          The number of pages to allocate.\r
   @param[out]  Memory                 A pointer to receive the base allocated memory\r
                                       address.\r
+  @param[in]   NeedGuard              Flag to indicate Guard page is needed\r
+                                      or not\r
 \r
   @retval EFI_INVALID_PARAMETER  Parameters violate checking rules defined in spec.\r
   @retval EFI_NOT_FOUND          Could not allocate pages match the requirement.\r
@@ -779,10 +684,12 @@ SmmInternalAllocatePages (
   IN  EFI_ALLOCATE_TYPE     Type,\r
   IN  EFI_MEMORY_TYPE       MemoryType,\r
   IN  UINTN                 NumberOfPages,\r
-  OUT EFI_PHYSICAL_ADDRESS  *Memory\r
+  OUT EFI_PHYSICAL_ADDRESS  *Memory,\r
+  IN  BOOLEAN               NeedGuard\r
   )\r
 {\r
-  return SmmInternalAllocatePagesEx (Type, MemoryType, NumberOfPages, Memory, FALSE);\r
+  return SmmInternalAllocatePagesEx (Type, MemoryType, NumberOfPages, Memory,\r
+                                     FALSE, NeedGuard);\r
 }\r
 \r
 /**\r
@@ -811,8 +718,11 @@ SmmAllocatePages (
   )\r
 {\r
   EFI_STATUS  Status;\r
+  BOOLEAN     NeedGuard;\r
 \r
-  Status = SmmInternalAllocatePages (Type, MemoryType, NumberOfPages, Memory);\r
+  NeedGuard = IsPageTypeToGuard (MemoryType, Type);\r
+  Status = SmmInternalAllocatePages (Type, MemoryType, NumberOfPages, Memory,\r
+                                     NeedGuard);\r
   if (!EFI_ERROR (Status)) {\r
     SmmCoreUpdateProfile (\r
       (EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0),\r
@@ -931,6 +841,7 @@ SmmInternalFreePagesEx (
 \r
   @param[in]  Memory                 Base address of memory being freed.\r
   @param[in]  NumberOfPages          The number of pages to free.\r
+  @param[in]  IsGuarded              Is the memory to free guarded or not.\r
 \r
   @retval EFI_NOT_FOUND          Could not find the entry that covers the range.\r
   @retval EFI_INVALID_PARAMETER  Address not aligned, Address is zero or NumberOfPages is zero.\r
@@ -941,12 +852,51 @@ EFI_STATUS
 EFIAPI\r
 SmmInternalFreePages (\r
   IN EFI_PHYSICAL_ADDRESS  Memory,\r
-  IN UINTN                 NumberOfPages\r
+  IN UINTN                 NumberOfPages,\r
+  IN BOOLEAN               IsGuarded\r
   )\r
 {\r
+  if (IsGuarded) {\r
+    return SmmInternalFreePagesExWithGuard (Memory, NumberOfPages, FALSE);\r
+  }\r
   return SmmInternalFreePagesEx (Memory, NumberOfPages, FALSE);\r
 }\r
 \r
+/**\r
+  Check whether the input range is in memory map.\r
+\r
+  @param  Memory                 Base address of memory being inputed.\r
+  @param  NumberOfPages          The number of pages.\r
+\r
+  @retval TRUE   In memory map.\r
+  @retval FALSE  Not in memory map.\r
+\r
+**/\r
+BOOLEAN\r
+InMemMap (\r
+  IN EFI_PHYSICAL_ADDRESS  Memory,\r
+  IN UINTN                 NumberOfPages\r
+  )\r
+{\r
+  LIST_ENTRY               *Link;\r
+  MEMORY_MAP               *Entry;\r
+  EFI_PHYSICAL_ADDRESS     Last;\r
+\r
+  Last = Memory + EFI_PAGES_TO_SIZE (NumberOfPages) - 1;\r
+\r
+  Link = gMemoryMap.ForwardLink;\r
+  while (Link != &gMemoryMap) {\r
+    Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);\r
+    Link  = Link->ForwardLink;\r
+\r
+    if ((Entry->Start <= Memory) && (Entry->End >= Last)) {\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
 /**\r
   Frees previous allocated pages.\r
 \r
@@ -966,8 +916,14 @@ SmmFreePages (
   )\r
 {\r
   EFI_STATUS  Status;\r
+  BOOLEAN     IsGuarded;\r
+\r
+  if (!InMemMap(Memory, NumberOfPages)) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
 \r
-  Status = SmmInternalFreePages (Memory, NumberOfPages);\r
+  IsGuarded = IsHeapGuardEnabled () && IsMemoryGuarded (Memory);\r
+  Status = SmmInternalFreePages (Memory, NumberOfPages, IsGuarded);\r
   if (!EFI_ERROR (Status)) {\r
     SmmCoreUpdateProfile (\r
       (EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0),\r