]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/PiSmmCore/Page.c
MdeModulePkg/FirmwarePerformanceDxe: make global variable static
[mirror_edk2.git] / MdeModulePkg / Core / PiSmmCore / Page.c
index 5f19d7e6c911343e3c0ed2fc3ddaf6d7d7d16888..1f05bddcc0b80336dcb530d723c984cc96d77976 100644 (file)
@@ -1,14 +1,8 @@
 /** @file\r
   SMM Memory page management functions.\r
 \r
-  Copyright (c) 2009 - 2016, 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
-  http://opensource.org/licenses/bsd-license.php\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -64,6 +58,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 +73,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
@@ -110,9 +107,10 @@ AllocateMemoryMapEntry (
     Status = SmmInternalAllocatePagesEx (\r
                AllocateAnyPages,\r
                EfiRuntimeServicesData,\r
-               EFI_SIZE_TO_PAGES(DEFAULT_PAGE_ALLOCATION),\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
@@ -121,7 +119,7 @@ AllocateMemoryMapEntry (
       //\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< RUNTIME_PAGE_ALLOCATION_GRANULARITY / sizeof(MEMORY_MAP); Index++) {\r
         FreeDescriptorEntries[Index].Signature = MEMORY_MAP_SIGNATURE;\r
         InsertTailList (&mFreeMemoryMapEntryList, &FreeDescriptorEntries[Index].Link);\r
       }\r
@@ -242,6 +240,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 +445,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 +567,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 +582,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 +605,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 +663,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 +678,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 +712,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
@@ -861,7 +765,7 @@ InternalMergeNodes (
   @param[in]  AddRegion              If this memory is new added region.\r
 \r
   @retval EFI_NOT_FOUND          Could not find the entry that covers the range.\r
-  @retval EFI_INVALID_PARAMETER  Address not aligned.\r
+  @retval EFI_INVALID_PARAMETER  Address not aligned, Address is zero or NumberOfPages is zero.\r
   @return EFI_SUCCESS            Pages successfully freed.\r
 \r
 **/\r
@@ -875,7 +779,7 @@ SmmInternalFreePagesEx (
   LIST_ENTRY      *Node;\r
   FREE_PAGE_LIST  *Pages;\r
 \r
-  if ((Memory & EFI_PAGE_MASK) != 0) {\r
+  if (((Memory & EFI_PAGE_MASK) != 0) || (Memory == 0) || (NumberOfPages == 0)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -931,9 +835,10 @@ 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.\r
+  @retval EFI_INVALID_PARAMETER  Address not aligned, Address is zero or NumberOfPages is zero.\r
   @return EFI_SUCCESS            Pages successfully freed.\r
 \r
 **/\r
@@ -941,12 +846,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
@@ -954,7 +898,7 @@ SmmInternalFreePages (
   @param  NumberOfPages          The number of pages to free.\r
 \r
   @retval EFI_NOT_FOUND          Could not find the entry that covers the range.\r
-  @retval EFI_INVALID_PARAMETER  Address not aligned.\r
+  @retval EFI_INVALID_PARAMETER  Address not aligned, Address is zero or NumberOfPages is zero.\r
   @return EFI_SUCCESS            Pages successfully freed.\r
 \r
 **/\r
@@ -966,8 +910,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