/** @file\r
SMM Memory pool management functions.\r
\r
- Copyright (c) 2009 - 2017, 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
\r
LIST_ENTRY mSmmPoolLists[SmmPoolTypeMax][MAX_POOL_INDEX];\r
//\r
-// To cache the SMRAM base since when Loading modules At fixed address feature is enabled, \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
EFI_STATUS Status;\r
FREE_POOL_HEADER *Hdr;\r
+ POOL_TAIL *Tail;\r
EFI_PHYSICAL_ADDRESS Address;\r
SMM_POOL_TYPE SmmPoolType;\r
\r
Status = EFI_SUCCESS;\r
Hdr = NULL;\r
if (PoolIndex == MAX_POOL_INDEX) {\r
- Status = SmmInternalAllocatePages (AllocateAnyPages, PoolType, EFI_SIZE_TO_PAGES (MAX_POOL_SIZE << 1), &Address);\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 {\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
- Hdr->Header.Type = PoolType;\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
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
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[SmmPoolType][PoolIndex], &FreePoolHdr->Link);\r
return EFI_SUCCESS;\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
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 = SmmInternalAllocatePages (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
)\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 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