]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/PiSmmCore/Page.c
MdeModulePkg PiSmmCore: Set ForwardLink to NULL in RemoveOldEntry()
[mirror_edk2.git] / MdeModulePkg / Core / PiSmmCore / Page.c
index 5f19d7e6c911343e3c0ed2fc3ddaf6d7d7d16888..3699af7424584c33afd383b82c72c56610a7c5ab 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
@@ -110,9 +113,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 +125,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 +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
@@ -688,6 +694,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 +709,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 +732,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 +790,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 +805,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 +839,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 +892,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 +906,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 +962,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,9 +973,13 @@ 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
@@ -954,7 +990,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 +1002,10 @@ SmmFreePages (
   )\r
 {\r
   EFI_STATUS  Status;\r
+  BOOLEAN     IsGuarded;\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