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>
IN EFI_SYSTEM_TABLE *SystemTable\r
)\r
{\r
IN EFI_SYSTEM_TABLE *SystemTable\r
)\r
{\r
SMM_CORE_PRIVATE_DATA *SmmCorePrivate;\r
UINTN Size;\r
SMM_CORE_PRIVATE_DATA *SmmCorePrivate;\r
UINTN Size;\r
+ VOID *BootServicesData;\r
\r
SmmCorePrivate = (SMM_CORE_PRIVATE_DATA *)ImageHandle;\r
\r
SmmCorePrivate = (SMM_CORE_PRIVATE_DATA *)ImageHandle;\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
- SmmInitializeMemoryServices (SmmCorePrivate->SmramRangeCount, SmmCorePrivate->SmramRanges);\r
-\r
mSmmCoreMemoryAllocLibSmramRangeCount = SmmCorePrivate->SmramRangeCount;\r
Size = mSmmCoreMemoryAllocLibSmramRangeCount * sizeof (EFI_SMRAM_DESCRIPTOR);\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
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
return EFI_SUCCESS;\r
}\r