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); } /**