]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg PiSmmCoreMemoryAllocLib: Fix a FreePool() assertion issue
authorStar Zeng <star.zeng@intel.com>
Fri, 28 Jul 2017 03:44:54 +0000 (11:44 +0800)
committerStar Zeng <star.zeng@intel.com>
Tue, 1 Aug 2017 09:44:02 +0000 (17:44 +0800)
When PiSmmCore links against PeiDxeDebugLibReportStatusCode, the code
flow below will cause a FreePool() assertion issue.

PiSmmCoreMemoryAllocationLibConstructor() ->
SmmInitializeMemoryServices() ->
DEBUG ((DEBUG_INFO, "SmmAddMemoryRegion\n")) in SmmAddMemoryRegion() ->
DebugPrint() -> REPORT_STATUS_CODE_EX() -> ReportStatusCodeEx() ->
AllocatePool()/FreePool(PiSmmCoreMemoryAllocLib) ->
ASSERT() at Head = CR (Buffer, POOL_HEAD, Data, POOL_HEAD_SIGNATURE)
  in CoreFreePoolI() of DxeCore Pool.c

It is because at the point of FreePool() in the code flow above,
mSmmCoreMemoryAllocLibSmramRanges/mSmmCoreMemoryAllocLibSmramRangeCount
are not been initialized yet, the FreePool() will be directed to
gBS->FreePool(), that is wrong.

This patch is to temporarily use BootServicesData to hold the
SmramRanges data before calling SmmInitializeMemoryServices().

Cc: Liming Gao <liming.gao@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Star Zeng <star.zeng@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/MemoryAllocationLib.c

index 96cb275cc9d7206474b5545ddd8bb3cc4d840654..4216a12d18f557bcb2edb3169b88f1520d63ac53 100644 (file)
@@ -1068,20 +1068,44 @@ PiSmmCoreMemoryAllocationLibConstructor (
   IN EFI_SYSTEM_TABLE  *SystemTable\r
   )\r
 {\r
+  EFI_STATUS             Status;\r
   SMM_CORE_PRIVATE_DATA  *SmmCorePrivate;\r
   UINTN                  Size;\r
+  VOID                   *BootServicesData;\r
 \r
   SmmCorePrivate = (SMM_CORE_PRIVATE_DATA *)ImageHandle;\r
+\r
   //\r
-  // Initialize memory service using free SMRAM\r
+  // The FreePool()/FreePages() will need use SmramRanges data to know whether\r
+  // the buffer to free is in SMRAM range or not. And there may be FreePool()/\r
+  // FreePages() indrectly during calling SmmInitializeMemoryServices(), but\r
+  // no SMRAM could be allocated before calling SmmInitializeMemoryServices(),\r
+  // so temporarily use BootServicesData to hold the SmramRanges data.\r
   //\r
-  SmmInitializeMemoryServices (SmmCorePrivate->SmramRangeCount, SmmCorePrivate->SmramRanges);\r
-\r
   mSmmCoreMemoryAllocLibSmramRangeCount = SmmCorePrivate->SmramRangeCount;\r
   Size = mSmmCoreMemoryAllocLibSmramRangeCount * sizeof (EFI_SMRAM_DESCRIPTOR);\r
-  mSmmCoreMemoryAllocLibSmramRanges = (EFI_SMRAM_DESCRIPTOR *) AllocatePool (Size);\r
+  Status = gBS->AllocatePool (EfiBootServicesData, Size, (VOID **) &mSmmCoreMemoryAllocLibSmramRanges);\r
+  ASSERT_EFI_ERROR (Status);\r
   ASSERT (mSmmCoreMemoryAllocLibSmramRanges != NULL);\r
   CopyMem (mSmmCoreMemoryAllocLibSmramRanges, SmmCorePrivate->SmramRanges, Size);\r
 \r
+  //\r
+  // Initialize memory service using free SMRAM\r
+  //\r
+  SmmInitializeMemoryServices (SmmCorePrivate->SmramRangeCount, SmmCorePrivate->SmramRanges);\r
+\r
+  //\r
+  // Move the SmramRanges data from BootServicesData to SMRAM.\r
+  //\r
+  BootServicesData = mSmmCoreMemoryAllocLibSmramRanges;\r
+  mSmmCoreMemoryAllocLibSmramRanges = (EFI_SMRAM_DESCRIPTOR *) AllocateCopyPool (Size, (VOID *) BootServicesData);\r
+  ASSERT (mSmmCoreMemoryAllocLibSmramRanges != NULL);\r
+\r
+  //\r
+  // Free the temporarily used BootServicesData.\r
+  //\r
+  Status = gBS->FreePool (BootServicesData);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
   return EFI_SUCCESS;\r
 }\r