]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/PiSmmCore/Pool.c
MdeModulePkg/S3SmmInitDone.h: Fix copyright coding style error.
[mirror_edk2.git] / MdeModulePkg / Core / PiSmmCore / Pool.c
index ea28484d68d9cf00fb8680a91f5dfcd1be48598c..48850413881cd0ea3d6defa7c1033e0cb102f904 100644 (file)
@@ -1,52 +1,49 @@
 /** @file\r
   SMM Memory pool management functions.\r
 \r
-  Copyright (c) 2009 - 2010, 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
+  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
+  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
+  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
 \r
 **/\r
 \r
 #include "PiSmmCore.h"\r
 \r
+LIST_ENTRY  mSmmPoolLists[SmmPoolTypeMax][MAX_POOL_INDEX];\r
 //\r
-// MIN_POOL_SHIFT must not be less than 5\r
-//\r
-#define MIN_POOL_SHIFT  6\r
-#define MIN_POOL_SIZE   (1 << MIN_POOL_SHIFT)\r
-\r
-//\r
-// MAX_POOL_SHIFT must not be less than EFI_PAGE_SHIFT - 1\r
+// To cache the SMRAM base since when Loading modules At fixed address feature is enabled,\r
+// all module is assigned an offset relative the SMRAM base in build time.\r
 //\r
-#define MAX_POOL_SHIFT  (EFI_PAGE_SHIFT - 1)\r
-#define MAX_POOL_SIZE   (1 << MAX_POOL_SHIFT)\r
+GLOBAL_REMOVE_IF_UNREFERENCED  EFI_PHYSICAL_ADDRESS       gLoadModuleAtFixAddressSmramBase = 0;\r
 \r
-//\r
-// MAX_POOL_INDEX are calculated by maximum and minimum pool sizes\r
-//\r
-#define MAX_POOL_INDEX  (MAX_POOL_SHIFT - MIN_POOL_SHIFT + 1)\r
+/**\r
+  Convert a UEFI memory type to SMM pool type.\r
 \r
-typedef struct {\r
-  UINTN        Size;\r
-  BOOLEAN      Available;\r
-} POOL_HEADER;\r
+  @param[in]  MemoryType              Type of pool to allocate.\r
 \r
-typedef struct {\r
-  POOL_HEADER  Header;\r
-  LIST_ENTRY   Link;\r
-} FREE_POOL_HEADER;\r
+  @return SMM pool type\r
+**/\r
+SMM_POOL_TYPE\r
+UefiMemoryTypeToSmmPoolType (\r
+  IN  EFI_MEMORY_TYPE   MemoryType\r
+  )\r
+{\r
+  ASSERT ((MemoryType == EfiRuntimeServicesCode) || (MemoryType == EfiRuntimeServicesData));\r
+  switch (MemoryType) {\r
+  case EfiRuntimeServicesCode:\r
+    return SmmPoolTypeCode;\r
+  case EfiRuntimeServicesData:\r
+    return SmmPoolTypeData;\r
+  default:\r
+    return SmmPoolTypeMax;\r
+  }\r
+}\r
 \r
-LIST_ENTRY  mSmmPoolLists[MAX_POOL_INDEX];\r
-//\r
-// To cache the SMRAM base since when Loading modules At fixed address feature is enabled, \r
-// all module is assigned an offset relative the SMRAM base in build time.\r
-//\r
-GLOBAL_REMOVE_IF_UNREFERENCED  EFI_PHYSICAL_ADDRESS       gLoadModuleAtFixAddressSmramBase = 0;\r
 \r
 /**\r
   Called to initialize the memory service.\r
@@ -62,52 +59,50 @@ SmmInitializeMemoryServices (
   )\r
 {\r
   UINTN                  Index;\r
-       UINT64                 SmmCodeSize;\r
-       UINTN                  CurrentSmramRangesIndex;\r
-       UINT64                 MaxSize;\r
+  EFI_STATUS             Status;\r
+  UINTN                  SmmPoolTypeIndex;\r
+  EFI_LOAD_FIXED_ADDRESS_CONFIGURATION_TABLE *LMFAConfigurationTable;\r
 \r
   //\r
   // Initialize Pool list\r
   //\r
-  for (Index = sizeof (mSmmPoolLists) / sizeof (*mSmmPoolLists); Index > 0;) {\r
-    InitializeListHead (&mSmmPoolLists[--Index]);\r
+  for (SmmPoolTypeIndex = 0; SmmPoolTypeIndex < SmmPoolTypeMax; SmmPoolTypeIndex++) {\r
+    for (Index = 0; Index < ARRAY_SIZE (mSmmPoolLists[SmmPoolTypeIndex]); Index++) {\r
+      InitializeListHead (&mSmmPoolLists[SmmPoolTypeIndex][Index]);\r
+    }\r
   }\r
-  CurrentSmramRangesIndex = 0;\r
+\r
+  Status = EfiGetSystemConfigurationTable (\r
+            &gLoadFixedAddressConfigurationTableGuid,\r
+           (VOID **) &LMFAConfigurationTable\r
+           );\r
+  if (!EFI_ERROR (Status) && LMFAConfigurationTable != NULL) {\r
+    gLoadModuleAtFixAddressSmramBase = LMFAConfigurationTable->SmramBase;\r
+  }\r
+\r
   //\r
-  // If Loadding Module At fixed Address feature is enabled, cache the SMRAM base here\r
+  // Add Free SMRAM regions\r
+  // Need add Free memory at first, to let gSmmMemoryMap record data\r
   //\r
-  if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0) {\r
-    //\r
-    // Build tool will calculate the smm code size and then patch the PcdLoadFixAddressSmmCodePageNumber\r
-    //\r
-    SmmCodeSize = LShiftU64 (PcdGet32(PcdLoadFixAddressSmmCodePageNumber), EFI_PAGE_SHIFT);\r
-    \r
-    //\r
-    // Find the largest SMRAM range between 1MB and 4GB that is at least 256KB - 4K in size\r
-    //\r
-    for (Index = 0, MaxSize = SIZE_256KB - EFI_PAGE_SIZE; Index < SmramRangeCount; Index++) {\r
-      if (SmramRanges[Index].CpuStart >= BASE_1MB) {\r
-        if ((SmramRanges[Index].CpuStart + SmramRanges[Index].PhysicalSize) <= BASE_4GB) {\r
-          if (SmramRanges[Index].PhysicalSize >= MaxSize) {\r
-            MaxSize = SmramRanges[Index].PhysicalSize;\r
-            CurrentSmramRangesIndex = Index;\r
-          }\r
-        }\r
-      }\r
+  for (Index = 0; Index < SmramRangeCount; Index++) {\r
+    if ((SmramRanges[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) {\r
+      continue;\r
     }\r
-    gLoadModuleAtFixAddressSmramBase = SmramRanges[CurrentSmramRangesIndex].CpuStart;\r
-    \r
-    //\r
-    // cut out a memory range from this SMRAM range with the size SmmCodeSize to hold SMM driver code\r
-    // A notable thing is that SMM core is already loaded into this range.\r
-    //\r
-    SmramRanges[CurrentSmramRangesIndex].CpuStart     = SmramRanges[CurrentSmramRangesIndex].CpuStart + SmmCodeSize; \r
-    SmramRanges[CurrentSmramRangesIndex].PhysicalSize = SmramRanges[CurrentSmramRangesIndex].PhysicalSize - SmmCodeSize;\r
+    SmmAddMemoryRegion (\r
+      SmramRanges[Index].CpuStart,\r
+      SmramRanges[Index].PhysicalSize,\r
+      EfiConventionalMemory,\r
+      SmramRanges[Index].RegionState\r
+      );\r
   }\r
+\r
   //\r
-  // Initialize free SMRAM regions\r
+  // Add the allocated SMRAM regions\r
   //\r
   for (Index = 0; Index < SmramRangeCount; Index++) {\r
+    if ((SmramRanges[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) == 0) {\r
+      continue;\r
+    }\r
     SmmAddMemoryRegion (\r
       SmramRanges[Index].CpuStart,\r
       SmramRanges[Index].PhysicalSize,\r
@@ -121,6 +116,7 @@ SmmInitializeMemoryServices (
 /**\r
   Internal Function. Allocate a pool by specified PoolIndex.\r
 \r
+  @param  PoolType              Type of pool to allocate.\r
   @param  PoolIndex             Index which indicate the Pool size.\r
   @param  FreePoolHdr           The returned Free pool.\r
 \r
@@ -130,36 +126,57 @@ SmmInitializeMemoryServices (
 **/\r
 EFI_STATUS\r
 InternalAllocPoolByIndex (\r
+  IN  EFI_MEMORY_TYPE   PoolType,\r
   IN  UINTN             PoolIndex,\r
   OUT FREE_POOL_HEADER  **FreePoolHdr\r
   )\r
 {\r
-  EFI_STATUS        Status;\r
-  FREE_POOL_HEADER  *Hdr;\r
+  EFI_STATUS            Status;\r
+  FREE_POOL_HEADER      *Hdr;\r
+  POOL_TAIL             *Tail;\r
+  EFI_PHYSICAL_ADDRESS  Address;\r
+  SMM_POOL_TYPE         SmmPoolType;\r
+\r
+  Address     = 0;\r
+  SmmPoolType = UefiMemoryTypeToSmmPoolType(PoolType);\r
 \r
   ASSERT (PoolIndex <= MAX_POOL_INDEX);\r
   Status = EFI_SUCCESS;\r
+  Hdr = NULL;\r
   if (PoolIndex == MAX_POOL_INDEX) {\r
-    Hdr = (FREE_POOL_HEADER *)AllocatePages (EFI_SIZE_TO_PAGES (MAX_POOL_SIZE << 1));\r
-    if (Hdr == NULL) {\r
+    Status = SmmInternalAllocatePages (AllocateAnyPages, PoolType,\r
+                                       EFI_SIZE_TO_PAGES (MAX_POOL_SIZE << 1),\r
+                                       &Address, FALSE);\r
+    if (EFI_ERROR (Status)) {\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
-  } else if (!IsListEmpty (&mSmmPoolLists[PoolIndex])) {\r
-    Hdr = BASE_CR (GetFirstNode (&mSmmPoolLists[PoolIndex]), FREE_POOL_HEADER, Link);\r
+    Hdr = (FREE_POOL_HEADER *) (UINTN) Address;\r
+  } else if (!IsListEmpty (&mSmmPoolLists[SmmPoolType][PoolIndex])) {\r
+    Hdr = BASE_CR (GetFirstNode (&mSmmPoolLists[SmmPoolType][PoolIndex]), FREE_POOL_HEADER, Link);\r
     RemoveEntryList (&Hdr->Link);\r
   } else {\r
-    Status = InternalAllocPoolByIndex (PoolIndex + 1, &Hdr);\r
+    Status = InternalAllocPoolByIndex (PoolType, PoolIndex + 1, &Hdr);\r
     if (!EFI_ERROR (Status)) {\r
+      Hdr->Header.Signature = 0;\r
       Hdr->Header.Size >>= 1;\r
       Hdr->Header.Available = TRUE;\r
-      InsertHeadList (&mSmmPoolLists[PoolIndex], &Hdr->Link);\r
+      Hdr->Header.Type = 0;\r
+      Tail = HEAD_TO_TAIL(&Hdr->Header);\r
+      Tail->Signature = 0;\r
+      Tail->Size = 0;\r
+      InsertHeadList (&mSmmPoolLists[SmmPoolType][PoolIndex], &Hdr->Link);\r
       Hdr = (FREE_POOL_HEADER*)((UINT8*)Hdr + Hdr->Header.Size);\r
     }\r
   }\r
 \r
   if (!EFI_ERROR (Status)) {\r
+    Hdr->Header.Signature = POOL_HEAD_SIGNATURE;\r
     Hdr->Header.Size = MIN_POOL_SIZE << PoolIndex;\r
     Hdr->Header.Available = FALSE;\r
+    Hdr->Header.Type = PoolType;\r
+    Tail = HEAD_TO_TAIL(&Hdr->Header);\r
+    Tail->Signature = POOL_TAIL_SIGNATURE;\r
+    Tail->Size = Hdr->Header.Size;\r
   }\r
 \r
   *FreePoolHdr = Hdr;\r
@@ -170,25 +187,34 @@ InternalAllocPoolByIndex (
   Internal Function. Free a pool by specified PoolIndex.\r
 \r
   @param  FreePoolHdr           The pool to free.\r
+  @param  PoolTail              The pointer to the pool tail.\r
 \r
   @retval EFI_SUCCESS           Pool successfully freed.\r
 \r
 **/\r
 EFI_STATUS\r
 InternalFreePoolByIndex (\r
-  IN FREE_POOL_HEADER  *FreePoolHdr\r
+  IN FREE_POOL_HEADER  *FreePoolHdr,\r
+  IN POOL_TAIL         *PoolTail\r
   )\r
 {\r
-  UINTN  PoolIndex;\r
+  UINTN                 PoolIndex;\r
+  SMM_POOL_TYPE         SmmPoolType;\r
 \r
   ASSERT ((FreePoolHdr->Header.Size & (FreePoolHdr->Header.Size - 1)) == 0);\r
   ASSERT (((UINTN)FreePoolHdr & (FreePoolHdr->Header.Size - 1)) == 0);\r
   ASSERT (FreePoolHdr->Header.Size >= MIN_POOL_SIZE);\r
 \r
+  SmmPoolType = UefiMemoryTypeToSmmPoolType(FreePoolHdr->Header.Type);\r
+\r
   PoolIndex = (UINTN) (HighBitSet32 ((UINT32)FreePoolHdr->Header.Size) - MIN_POOL_SHIFT);\r
+  FreePoolHdr->Header.Signature = 0;\r
   FreePoolHdr->Header.Available = TRUE;\r
+  FreePoolHdr->Header.Type = 0;\r
+  PoolTail->Signature = 0;\r
+  PoolTail->Size = 0;\r
   ASSERT (PoolIndex < MAX_POOL_INDEX);\r
-  InsertHeadList (&mSmmPoolLists[PoolIndex], &FreePoolHdr->Link);\r
+  InsertHeadList (&mSmmPoolLists[SmmPoolType][PoolIndex], &FreePoolHdr->Link);\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -207,34 +233,70 @@ InternalFreePoolByIndex (
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-SmmAllocatePool (\r
+SmmInternalAllocatePool (\r
   IN   EFI_MEMORY_TYPE  PoolType,\r
   IN   UINTN            Size,\r
   OUT  VOID             **Buffer\r
   )\r
 {\r
   POOL_HEADER           *PoolHdr;\r
+  POOL_TAIL             *PoolTail;\r
   FREE_POOL_HEADER      *FreePoolHdr;\r
   EFI_STATUS            Status;\r
   EFI_PHYSICAL_ADDRESS  Address;\r
   UINTN                 PoolIndex;\r
+  BOOLEAN               HasPoolTail;\r
+  BOOLEAN               NeedGuard;\r
+  UINTN                 NoPages;\r
+\r
+  Address = 0;\r
 \r
   if (PoolType != EfiRuntimeServicesCode &&\r
       PoolType != EfiRuntimeServicesData) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  Size += sizeof (*PoolHdr);\r
-  if (Size > MAX_POOL_SIZE) {\r
-    Size = EFI_SIZE_TO_PAGES (Size);\r
-    Status = SmmAllocatePages (AllocateAnyPages, PoolType, Size, &Address);\r
+  NeedGuard   = IsPoolTypeToGuard (PoolType);\r
+  HasPoolTail = !(NeedGuard &&\r
+                  ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) == 0));\r
+\r
+  //\r
+  // Adjust the size by the pool header & tail overhead\r
+  //\r
+  Size += POOL_OVERHEAD;\r
+  if (Size > MAX_POOL_SIZE || NeedGuard) {\r
+    if (!HasPoolTail) {\r
+      Size -= sizeof (POOL_TAIL);\r
+    }\r
+\r
+    NoPages = EFI_SIZE_TO_PAGES (Size);\r
+    Status = SmmInternalAllocatePages (AllocateAnyPages, PoolType, NoPages,\r
+                                       &Address, NeedGuard);\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
 \r
+    if (NeedGuard) {\r
+      ASSERT (VerifyMemoryGuard (Address, NoPages) == TRUE);\r
+      Address = (EFI_PHYSICAL_ADDRESS)(UINTN)AdjustPoolHeadA (\r
+                                               Address,\r
+                                               NoPages,\r
+                                               Size\r
+                                               );\r
+    }\r
+\r
     PoolHdr = (POOL_HEADER*)(UINTN)Address;\r
-    PoolHdr->Size = EFI_PAGES_TO_SIZE (Size);\r
+    PoolHdr->Signature = POOL_HEAD_SIGNATURE;\r
+    PoolHdr->Size = EFI_PAGES_TO_SIZE (NoPages);\r
     PoolHdr->Available = FALSE;\r
+    PoolHdr->Type = PoolType;\r
+\r
+    if (HasPoolTail) {\r
+      PoolTail = HEAD_TO_TAIL (PoolHdr);\r
+      PoolTail->Signature = POOL_TAIL_SIGNATURE;\r
+      PoolTail->Size = PoolHdr->Size;\r
+    }\r
+\r
     *Buffer = PoolHdr + 1;\r
     return Status;\r
   }\r
@@ -245,8 +307,47 @@ SmmAllocatePool (
     PoolIndex++;\r
   }\r
 \r
-  Status = InternalAllocPoolByIndex (PoolIndex, &FreePoolHdr);\r
-  *Buffer = &FreePoolHdr->Header + 1;\r
+  Status = InternalAllocPoolByIndex (PoolType, PoolIndex, &FreePoolHdr);\r
+  if (!EFI_ERROR(Status)) {\r
+    *Buffer = &FreePoolHdr->Header + 1;\r
+  }\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Allocate pool of a particular type.\r
+\r
+  @param  PoolType               Type of pool to allocate.\r
+  @param  Size                   The amount of pool to allocate.\r
+  @param  Buffer                 The address to return a pointer to the allocated\r
+                                 pool.\r
+\r
+  @retval EFI_INVALID_PARAMETER  PoolType not valid.\r
+  @retval EFI_OUT_OF_RESOURCES   Size exceeds max pool size or allocation failed.\r
+  @retval EFI_SUCCESS            Pool successfully allocated.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmmAllocatePool (\r
+  IN   EFI_MEMORY_TYPE  PoolType,\r
+  IN   UINTN            Size,\r
+  OUT  VOID             **Buffer\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  Status = SmmInternalAllocatePool (PoolType, Size, Buffer);\r
+  if (!EFI_ERROR (Status)) {\r
+    SmmCoreUpdateProfile (\r
+      (EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0),\r
+      MemoryProfileActionAllocatePool,\r
+      PoolType,\r
+      Size,\r
+      *Buffer,\r
+      NULL\r
+      );\r
+  }\r
   return Status;\r
 }\r
 \r
@@ -261,26 +362,94 @@ SmmAllocatePool (
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-SmmFreePool (\r
+SmmInternalFreePool (\r
   IN VOID  *Buffer\r
   )\r
 {\r
   FREE_POOL_HEADER  *FreePoolHdr;\r
+  POOL_TAIL         *PoolTail;\r
+  BOOLEAN           HasPoolTail;\r
+  BOOLEAN           MemoryGuarded;\r
 \r
   if (Buffer == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  MemoryGuarded = IsHeapGuardEnabled () &&\r
+                  IsMemoryGuarded ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer);\r
+  HasPoolTail   = !(MemoryGuarded &&\r
+                    ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) == 0));\r
+\r
   FreePoolHdr = (FREE_POOL_HEADER*)((POOL_HEADER*)Buffer - 1);\r
+  ASSERT (FreePoolHdr->Header.Signature == POOL_HEAD_SIGNATURE);\r
   ASSERT (!FreePoolHdr->Header.Available);\r
+  if (FreePoolHdr->Header.Signature != POOL_HEAD_SIGNATURE) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (HasPoolTail) {\r
+    PoolTail = HEAD_TO_TAIL (&FreePoolHdr->Header);\r
+    ASSERT (PoolTail->Signature == POOL_TAIL_SIGNATURE);\r
+    ASSERT (FreePoolHdr->Header.Size == PoolTail->Size);\r
+    if (PoolTail->Signature != POOL_TAIL_SIGNATURE) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    if (FreePoolHdr->Header.Size != PoolTail->Size) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+  } else {\r
+    PoolTail = NULL;\r
+  }\r
+\r
+  if (MemoryGuarded) {\r
+    Buffer = AdjustPoolHeadF ((EFI_PHYSICAL_ADDRESS)(UINTN)FreePoolHdr);\r
+    return SmmInternalFreePages (\r
+             (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer,\r
+             EFI_SIZE_TO_PAGES (FreePoolHdr->Header.Size),\r
+             TRUE\r
+             );\r
+  }\r
 \r
   if (FreePoolHdr->Header.Size > MAX_POOL_SIZE) {\r
     ASSERT (((UINTN)FreePoolHdr & EFI_PAGE_MASK) == 0);\r
     ASSERT ((FreePoolHdr->Header.Size & EFI_PAGE_MASK) == 0);\r
-    return SmmFreePages (\r
+    return SmmInternalFreePages (\r
              (EFI_PHYSICAL_ADDRESS)(UINTN)FreePoolHdr,\r
-             EFI_SIZE_TO_PAGES (FreePoolHdr->Header.Size)\r
+             EFI_SIZE_TO_PAGES (FreePoolHdr->Header.Size),\r
+             FALSE\r
              );\r
   }\r
-  return InternalFreePoolByIndex (FreePoolHdr);\r
+  return InternalFreePoolByIndex (FreePoolHdr, PoolTail);\r
+}\r
+\r
+/**\r
+  Frees pool.\r
+\r
+  @param  Buffer                 The allocated pool entry to free.\r
+\r
+  @retval EFI_INVALID_PARAMETER  Buffer is not a valid value.\r
+  @retval EFI_SUCCESS            Pool successfully freed.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmmFreePool (\r
+  IN VOID  *Buffer\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  Status = SmmInternalFreePool (Buffer);\r
+  if (!EFI_ERROR (Status)) {\r
+    SmmCoreUpdateProfile (\r
+      (EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0),\r
+      MemoryProfileActionFreePool,\r
+      EfiMaxMemoryType,\r
+      0,\r
+      Buffer,\r
+      NULL\r
+      );\r
+  }\r
+  return Status;\r
 }\r