X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FCore%2FPiSmmCore%2FPool.c;h=48850413881cd0ea3d6defa7c1033e0cb102f904;hp=ebb9f8c49ee97e86ba7ebab07f7614e93c935590;hb=9917def3294bac4d14cd86ba382652aa41c6c1d6;hpb=861c8dff2f506d602f8612ace12d244c29e63f31
diff --git a/MdeModulePkg/Core/PiSmmCore/Pool.c b/MdeModulePkg/Core/PiSmmCore/Pool.c
index ebb9f8c49e..4885041388 100644
--- a/MdeModulePkg/Core/PiSmmCore/Pool.c
+++ b/MdeModulePkg/Core/PiSmmCore/Pool.c
@@ -1,14 +1,14 @@
/** @file
SMM Memory pool management functions.
- Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.
- This program and the accompanying materials are licensed and made available
- under the terms and conditions of the BSD License which accompanies this
- distribution. The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php
+ Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License which accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
@@ -16,7 +16,7 @@
LIST_ENTRY mSmmPoolLists[SmmPoolTypeMax][MAX_POOL_INDEX];
//
-// To cache the SMRAM base since when Loading modules At fixed address feature is enabled,
+// To cache the SMRAM base since when Loading modules At fixed address feature is enabled,
// all module is assigned an offset relative the SMRAM base in build time.
//
GLOBAL_REMOVE_IF_UNREFERENCED EFI_PHYSICAL_ADDRESS gLoadModuleAtFixAddressSmramBase = 0;
@@ -144,7 +144,9 @@ InternalAllocPoolByIndex (
Status = EFI_SUCCESS;
Hdr = NULL;
if (PoolIndex == MAX_POOL_INDEX) {
- Status = SmmInternalAllocatePages (AllocateAnyPages, PoolType, EFI_SIZE_TO_PAGES (MAX_POOL_SIZE << 1), &Address);
+ Status = SmmInternalAllocatePages (AllocateAnyPages, PoolType,
+ EFI_SIZE_TO_PAGES (MAX_POOL_SIZE << 1),
+ &Address, FALSE);
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}
@@ -185,18 +187,19 @@ InternalAllocPoolByIndex (
Internal Function. Free a pool by specified PoolIndex.
@param FreePoolHdr The pool to free.
+ @param PoolTail The pointer to the pool tail.
@retval EFI_SUCCESS Pool successfully freed.
**/
EFI_STATUS
InternalFreePoolByIndex (
- IN FREE_POOL_HEADER *FreePoolHdr
+ IN FREE_POOL_HEADER *FreePoolHdr,
+ IN POOL_TAIL *PoolTail
)
{
UINTN PoolIndex;
SMM_POOL_TYPE SmmPoolType;
- POOL_TAIL *PoolTail;
ASSERT ((FreePoolHdr->Header.Size & (FreePoolHdr->Header.Size - 1)) == 0);
ASSERT (((UINTN)FreePoolHdr & (FreePoolHdr->Header.Size - 1)) == 0);
@@ -208,7 +211,6 @@ InternalFreePoolByIndex (
FreePoolHdr->Header.Signature = 0;
FreePoolHdr->Header.Available = TRUE;
FreePoolHdr->Header.Type = 0;
- PoolTail = HEAD_TO_TAIL(&FreePoolHdr->Header);
PoolTail->Signature = 0;
PoolTail->Size = 0;
ASSERT (PoolIndex < MAX_POOL_INDEX);
@@ -243,6 +245,9 @@ SmmInternalAllocatePool (
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS Address;
UINTN PoolIndex;
+ BOOLEAN HasPoolTail;
+ BOOLEAN NeedGuard;
+ UINTN NoPages;
Address = 0;
@@ -251,25 +256,47 @@ SmmInternalAllocatePool (
return EFI_INVALID_PARAMETER;
}
+ NeedGuard = IsPoolTypeToGuard (PoolType);
+ HasPoolTail = !(NeedGuard &&
+ ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) == 0));
+
//
// Adjust the size by the pool header & tail overhead
//
Size += POOL_OVERHEAD;
- if (Size > MAX_POOL_SIZE) {
- Size = EFI_SIZE_TO_PAGES (Size);
- Status = SmmInternalAllocatePages (AllocateAnyPages, PoolType, Size, &Address);
+ if (Size > MAX_POOL_SIZE || NeedGuard) {
+ if (!HasPoolTail) {
+ Size -= sizeof (POOL_TAIL);
+ }
+
+ NoPages = EFI_SIZE_TO_PAGES (Size);
+ Status = SmmInternalAllocatePages (AllocateAnyPages, PoolType, NoPages,
+ &Address, NeedGuard);
if (EFI_ERROR (Status)) {
return Status;
}
+ if (NeedGuard) {
+ ASSERT (VerifyMemoryGuard (Address, NoPages) == TRUE);
+ Address = (EFI_PHYSICAL_ADDRESS)(UINTN)AdjustPoolHeadA (
+ Address,
+ NoPages,
+ Size
+ );
+ }
+
PoolHdr = (POOL_HEADER*)(UINTN)Address;
PoolHdr->Signature = POOL_HEAD_SIGNATURE;
- PoolHdr->Size = EFI_PAGES_TO_SIZE (Size);
+ PoolHdr->Size = EFI_PAGES_TO_SIZE (NoPages);
PoolHdr->Available = FALSE;
PoolHdr->Type = PoolType;
- PoolTail = HEAD_TO_TAIL(PoolHdr);
- PoolTail->Signature = POOL_TAIL_SIGNATURE;
- PoolTail->Size = PoolHdr->Size;
+
+ if (HasPoolTail) {
+ PoolTail = HEAD_TO_TAIL (PoolHdr);
+ PoolTail->Signature = POOL_TAIL_SIGNATURE;
+ PoolTail->Size = PoolHdr->Size;
+ }
+
*Buffer = PoolHdr + 1;
return Status;
}
@@ -341,28 +368,47 @@ SmmInternalFreePool (
{
FREE_POOL_HEADER *FreePoolHdr;
POOL_TAIL *PoolTail;
+ BOOLEAN HasPoolTail;
+ BOOLEAN MemoryGuarded;
if (Buffer == NULL) {
return EFI_INVALID_PARAMETER;
}
+ MemoryGuarded = IsHeapGuardEnabled () &&
+ IsMemoryGuarded ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer);
+ HasPoolTail = !(MemoryGuarded &&
+ ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) == 0));
+
FreePoolHdr = (FREE_POOL_HEADER*)((POOL_HEADER*)Buffer - 1);
ASSERT (FreePoolHdr->Header.Signature == POOL_HEAD_SIGNATURE);
ASSERT (!FreePoolHdr->Header.Available);
- PoolTail = HEAD_TO_TAIL(&FreePoolHdr->Header);
- ASSERT (PoolTail->Signature == POOL_TAIL_SIGNATURE);
- ASSERT (FreePoolHdr->Header.Size == PoolTail->Size);
-
if (FreePoolHdr->Header.Signature != POOL_HEAD_SIGNATURE) {
return EFI_INVALID_PARAMETER;
}
- if (PoolTail->Signature != POOL_TAIL_SIGNATURE) {
- return EFI_INVALID_PARAMETER;
+ if (HasPoolTail) {
+ PoolTail = HEAD_TO_TAIL (&FreePoolHdr->Header);
+ ASSERT (PoolTail->Signature == POOL_TAIL_SIGNATURE);
+ ASSERT (FreePoolHdr->Header.Size == PoolTail->Size);
+ if (PoolTail->Signature != POOL_TAIL_SIGNATURE) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (FreePoolHdr->Header.Size != PoolTail->Size) {
+ return EFI_INVALID_PARAMETER;
+ }
+ } else {
+ PoolTail = NULL;
}
- if (FreePoolHdr->Header.Size != PoolTail->Size) {
- return EFI_INVALID_PARAMETER;
+ if (MemoryGuarded) {
+ Buffer = AdjustPoolHeadF ((EFI_PHYSICAL_ADDRESS)(UINTN)FreePoolHdr);
+ return SmmInternalFreePages (
+ (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer,
+ EFI_SIZE_TO_PAGES (FreePoolHdr->Header.Size),
+ TRUE
+ );
}
if (FreePoolHdr->Header.Size > MAX_POOL_SIZE) {
@@ -370,10 +416,11 @@ SmmInternalFreePool (
ASSERT ((FreePoolHdr->Header.Size & EFI_PAGE_MASK) == 0);
return SmmInternalFreePages (
(EFI_PHYSICAL_ADDRESS)(UINTN)FreePoolHdr,
- EFI_SIZE_TO_PAGES (FreePoolHdr->Header.Size)
+ EFI_SIZE_TO_PAGES (FreePoolHdr->Header.Size),
+ FALSE
);
}
- return InternalFreePoolByIndex (FreePoolHdr);
+ return InternalFreePoolByIndex (FreePoolHdr, PoolTail);
}
/**