X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FCore%2FDxe%2FMem%2FPool.c;h=734fc94bf6129ad20f3e8846c9cf13aaee7266ab;hp=77ca5671dcfea69d08273d18c8823f871c8d32e3;hb=9d510e61fceee7b92955ef9a3c20343752d8ce3f;hpb=235a4490c8ce8b6dbac49e6ae3559cb73d6bf620
diff --git a/MdeModulePkg/Core/Dxe/Mem/Pool.c b/MdeModulePkg/Core/Dxe/Mem/Pool.c
index 77ca5671dc..734fc94bf6 100644
--- a/MdeModulePkg/Core/Dxe/Mem/Pool.c
+++ b/MdeModulePkg/Core/Dxe/Mem/Pool.c
@@ -1,20 +1,14 @@
/** @file
UEFI Memory pool management functions.
-Copyright (c) 2006 - 2016, 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.
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "DxeMain.h"
#include "Imem.h"
-#include "HeapGuard.h"
+#include "HeapGuard.h"
STATIC EFI_LOCK mPoolMemoryLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY);
@@ -26,7 +20,8 @@ typedef struct {
} POOL_FREE;
-#define POOL_HEAD_SIGNATURE SIGNATURE_32('p','h','d','0')
+#define POOL_HEAD_SIGNATURE SIGNATURE_32('p','h','d','0')
+#define POOLPAGE_HEAD_SIGNATURE SIGNATURE_32('p','h','d','1')
typedef struct {
UINT32 Signature;
UINT32 Reserved;
@@ -170,7 +165,7 @@ LookupPoolHead (
}
}
- Pool = CoreAllocatePoolI (EfiBootServicesData, sizeof (POOL), FALSE);
+ Pool = CoreAllocatePoolI (EfiBootServicesData, sizeof (POOL), FALSE);
if (Pool == NULL) {
return NULL;
}
@@ -215,8 +210,8 @@ CoreInternalAllocatePool (
OUT VOID **Buffer
)
{
- EFI_STATUS Status;
- BOOLEAN NeedGuard;
+ EFI_STATUS Status;
+ BOOLEAN NeedGuard;
//
// If it's not a valid type, fail it
@@ -240,8 +235,8 @@ CoreInternalAllocatePool (
return EFI_OUT_OF_RESOURCES;
}
- NeedGuard = IsPoolTypeToGuard (PoolType) && !mOnGuarding;
-
+ NeedGuard = IsPoolTypeToGuard (PoolType) && !mOnGuarding;
+
//
// Acquire the memory lock and make the allocation
//
@@ -250,7 +245,7 @@ CoreInternalAllocatePool (
return EFI_OUT_OF_RESOURCES;
}
- *Buffer = CoreAllocatePoolI (PoolType, Size, NeedGuard);
+ *Buffer = CoreAllocatePoolI (PoolType, Size, NeedGuard);
CoreReleaseLock (&mPoolMemoryLock);
return (*Buffer != NULL) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;
}
@@ -302,7 +297,7 @@ CoreAllocatePool (
@param PoolType The type of memory for the new pool pages
@param NoPages No of pages to allocate
@param Granularity Bits to align.
- @param NeedGuard Flag to indicate Guard page is needed or not
+ @param NeedGuard Flag to indicate Guard page is needed or not
@return The allocated memory, or NULL
@@ -312,8 +307,8 @@ VOID *
CoreAllocatePoolPagesI (
IN EFI_MEMORY_TYPE PoolType,
IN UINTN NoPages,
- IN UINTN Granularity,
- IN BOOLEAN NeedGuard
+ IN UINTN Granularity,
+ IN BOOLEAN NeedGuard
)
{
VOID *Buffer;
@@ -324,14 +319,14 @@ CoreAllocatePoolPagesI (
return NULL;
}
- Buffer = CoreAllocatePoolPages (PoolType, NoPages, Granularity, NeedGuard);
+ Buffer = CoreAllocatePoolPages (PoolType, NoPages, Granularity, NeedGuard);
CoreReleaseMemoryLock ();
if (Buffer != NULL) {
- if (NeedGuard) {
- SetGuardForMemory ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, NoPages);
- }
- ApplyMemoryProtectionPolicy(EfiConventionalMemory, PoolType,
+ if (NeedGuard) {
+ SetGuardForMemory ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, NoPages);
+ }
+ ApplyMemoryProtectionPolicy(EfiConventionalMemory, PoolType,
(EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, EFI_PAGES_TO_SIZE (NoPages));
}
return Buffer;
@@ -343,7 +338,7 @@ CoreAllocatePoolPagesI (
@param PoolType Type of pool to allocate
@param Size The amount of pool to allocate
- @param NeedGuard Flag to indicate Guard page is needed or not
+ @param NeedGuard Flag to indicate Guard page is needed or not
@return The allocate pool, or NULL
@@ -351,8 +346,8 @@ CoreAllocatePoolPagesI (
VOID *
CoreAllocatePoolI (
IN EFI_MEMORY_TYPE PoolType,
- IN UINTN Size,
- IN BOOLEAN NeedGuard
+ IN UINTN Size,
+ IN BOOLEAN NeedGuard
)
{
POOL *Pool;
@@ -366,7 +361,8 @@ CoreAllocatePoolI (
UINTN Offset, MaxOffset;
UINTN NoPages;
UINTN Granularity;
- BOOLEAN HasPoolTail;
+ BOOLEAN HasPoolTail;
+ BOOLEAN PageAsPool;
ASSERT_LOCKED (&mPoolMemoryLock);
@@ -384,9 +380,10 @@ CoreAllocatePoolI (
// Adjust the size by the pool header & tail overhead
//
- HasPoolTail = !(NeedGuard &&
- ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) == 0));
-
+ HasPoolTail = !(NeedGuard &&
+ ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) == 0));
+ PageAsPool = (IsHeapGuardEnabled (GUARD_HEAP_TYPE_FREED) && !mOnGuarding);
+
//
// Adjusting the Size to be of proper alignment so that
// we don't get an unaligned access fault later when
@@ -406,16 +403,16 @@ CoreAllocatePoolI (
// If allocation is over max size, just allocate pages for the request
// (slow)
//
- if (Index >= SIZE_TO_LIST (Granularity) || NeedGuard) {
- if (!HasPoolTail) {
- Size -= sizeof (POOL_TAIL);
- }
- NoPages = EFI_SIZE_TO_PAGES (Size) + EFI_SIZE_TO_PAGES (Granularity) - 1;
+ if (Index >= SIZE_TO_LIST (Granularity) || NeedGuard || PageAsPool) {
+ if (!HasPoolTail) {
+ Size -= sizeof (POOL_TAIL);
+ }
+ NoPages = EFI_SIZE_TO_PAGES (Size) + EFI_SIZE_TO_PAGES (Granularity) - 1;
NoPages &= ~(UINTN)(EFI_SIZE_TO_PAGES (Granularity) - 1);
- Head = CoreAllocatePoolPagesI (PoolType, NoPages, Granularity, NeedGuard);
- if (NeedGuard) {
- Head = AdjustPoolHeadA ((EFI_PHYSICAL_ADDRESS)(UINTN)Head, NoPages, Size);
- }
+ Head = CoreAllocatePoolPagesI (PoolType, NoPages, Granularity, NeedGuard);
+ if (NeedGuard) {
+ Head = AdjustPoolHeadA ((EFI_PHYSICAL_ADDRESS)(UINTN)Head, NoPages, Size);
+ }
goto Done;
}
@@ -443,8 +440,8 @@ CoreAllocatePoolI (
//
// Get another page
//
- NewPage = CoreAllocatePoolPagesI (PoolType, EFI_SIZE_TO_PAGES (Granularity),
- Granularity, NeedGuard);
+ NewPage = CoreAllocatePoolPagesI (PoolType, EFI_SIZE_TO_PAGES (Granularity),
+ Granularity, NeedGuard);
if (NewPage == NULL) {
goto Done;
}
@@ -490,36 +487,36 @@ Done:
if (Head != NULL) {
- //
- // Account the allocation
- //
- Pool->Used += Size;
-
+ //
+ // Account the allocation
+ //
+ Pool->Used += Size;
+
//
// If we have a pool buffer, fill in the header & tail info
//
- Head->Signature = POOL_HEAD_SIGNATURE;
+ Head->Signature = (PageAsPool) ? POOLPAGE_HEAD_SIGNATURE : POOL_HEAD_SIGNATURE;
Head->Size = Size;
Head->Type = (EFI_MEMORY_TYPE) PoolType;
Buffer = Head->Data;
-
- if (HasPoolTail) {
- Tail = HEAD_TO_TAIL (Head);
- Tail->Signature = POOL_TAIL_SIGNATURE;
- Tail->Size = Size;
-
- Size -= POOL_OVERHEAD;
- } else {
- Size -= SIZE_OF_POOL_HEAD;
- }
-
- DEBUG_CLEAR_MEMORY (Buffer, Size);
+
+ if (HasPoolTail) {
+ Tail = HEAD_TO_TAIL (Head);
+ Tail->Signature = POOL_TAIL_SIGNATURE;
+ Tail->Size = Size;
+
+ Size -= POOL_OVERHEAD;
+ } else {
+ Size -= SIZE_OF_POOL_HEAD;
+ }
+
+ DEBUG_CLEAR_MEMORY (Buffer, Size);
DEBUG ((
DEBUG_POOL,
"AllocatePoolI: Type %x, Addr %p (len %lx) %,ld\n", PoolType,
Buffer,
- (UINT64)Size,
+ (UINT64)Size,
(UINT64) Pool->Used
));
@@ -615,38 +612,47 @@ CoreFreePoolPagesI (
CoreFreePoolPages (Memory, NoPages);
CoreReleaseMemoryLock ();
+ GuardFreedPagesChecked (Memory, NoPages);
ApplyMemoryProtectionPolicy (PoolType, EfiConventionalMemory,
(EFI_PHYSICAL_ADDRESS)(UINTN)Memory, EFI_PAGES_TO_SIZE (NoPages));
}
-/**
- Internal function. Frees guarded pool pages.
-
- @param PoolType The type of memory for the pool pages
- @param Memory The base address to free
- @param NoPages The number of pages to free
-
-**/
-STATIC
-VOID
-CoreFreePoolPagesWithGuard (
- IN EFI_MEMORY_TYPE PoolType,
- IN EFI_PHYSICAL_ADDRESS Memory,
- IN UINTN NoPages
- )
-{
- EFI_PHYSICAL_ADDRESS MemoryGuarded;
- UINTN NoPagesGuarded;
-
- MemoryGuarded = Memory;
- NoPagesGuarded = NoPages;
-
- AdjustMemoryF (&Memory, &NoPages);
- CoreFreePoolPagesI (PoolType, Memory, NoPages);
-
- UnsetGuardForMemory (MemoryGuarded, NoPagesGuarded);
-}
-
+/**
+ Internal function. Frees guarded pool pages.
+
+ @param PoolType The type of memory for the pool pages
+ @param Memory The base address to free
+ @param NoPages The number of pages to free
+
+**/
+STATIC
+VOID
+CoreFreePoolPagesWithGuard (
+ IN EFI_MEMORY_TYPE PoolType,
+ IN EFI_PHYSICAL_ADDRESS Memory,
+ IN UINTN NoPages
+ )
+{
+ EFI_PHYSICAL_ADDRESS MemoryGuarded;
+ UINTN NoPagesGuarded;
+
+ MemoryGuarded = Memory;
+ NoPagesGuarded = NoPages;
+
+ AdjustMemoryF (&Memory, &NoPages);
+ //
+ // It's safe to unset Guard page inside memory lock because there should
+ // be no memory allocation occurred in updating memory page attribute at
+ // this point. And unsetting Guard page before free will prevent Guard
+ // page just freed back to pool from being allocated right away before
+ // marking it usable (from non-present to present).
+ //
+ UnsetGuardForMemory (MemoryGuarded, NoPagesGuarded);
+ if (NoPages > 0) {
+ CoreFreePoolPagesI (PoolType, Memory, NoPages);
+ }
+}
+
/**
Internal function to free a pool entry.
Caller must have the memory lock held
@@ -675,46 +681,51 @@ CoreFreePoolI (
UINTN Offset;
BOOLEAN AllFree;
UINTN Granularity;
- BOOLEAN IsGuarded;
- BOOLEAN HasPoolTail;
+ BOOLEAN IsGuarded;
+ BOOLEAN HasPoolTail;
+ BOOLEAN PageAsPool;
ASSERT(Buffer != NULL);
//
// Get the head & tail of the pool entry
//
- Head = CR (Buffer, POOL_HEAD, Data, POOL_HEAD_SIGNATURE);
+ Head = BASE_CR (Buffer, POOL_HEAD, Data);
ASSERT(Head != NULL);
- if (Head->Signature != POOL_HEAD_SIGNATURE) {
+ if (Head->Signature != POOL_HEAD_SIGNATURE &&
+ Head->Signature != POOLPAGE_HEAD_SIGNATURE) {
+ ASSERT (Head->Signature == POOL_HEAD_SIGNATURE ||
+ Head->Signature == POOLPAGE_HEAD_SIGNATURE);
return EFI_INVALID_PARAMETER;
}
- IsGuarded = IsPoolTypeToGuard (Head->Type) &&
- IsMemoryGuarded ((EFI_PHYSICAL_ADDRESS)(UINTN)Head);
- HasPoolTail = !(IsGuarded &&
- ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) == 0));
-
- if (HasPoolTail) {
- Tail = HEAD_TO_TAIL (Head);
- ASSERT (Tail != NULL);
-
- //
- // Debug
- //
- ASSERT (Tail->Signature == POOL_TAIL_SIGNATURE);
- ASSERT (Head->Size == Tail->Size);
-
- if (Tail->Signature != POOL_TAIL_SIGNATURE) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (Head->Size != Tail->Size) {
- return EFI_INVALID_PARAMETER;
- }
+ IsGuarded = IsPoolTypeToGuard (Head->Type) &&
+ IsMemoryGuarded ((EFI_PHYSICAL_ADDRESS)(UINTN)Head);
+ HasPoolTail = !(IsGuarded &&
+ ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) == 0));
+ PageAsPool = (Head->Signature == POOLPAGE_HEAD_SIGNATURE);
+
+ if (HasPoolTail) {
+ Tail = HEAD_TO_TAIL (Head);
+ ASSERT (Tail != NULL);
+
+ //
+ // Debug
+ //
+ ASSERT (Tail->Signature == POOL_TAIL_SIGNATURE);
+ ASSERT (Head->Size == Tail->Size);
+
+ if (Tail->Signature != POOL_TAIL_SIGNATURE) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Head->Size != Tail->Size) {
+ return EFI_INVALID_PARAMETER;
+ }
}
- ASSERT_LOCKED (&mPoolMemoryLock);
-
+ ASSERT_LOCKED (&mPoolMemoryLock);
+
//
// Determine the pool type and account for it
//
@@ -749,27 +760,27 @@ CoreFreePoolI (
//
// If it's not on the list, it must be pool pages
//
- if (Index >= SIZE_TO_LIST (Granularity) || IsGuarded) {
+ if (Index >= SIZE_TO_LIST (Granularity) || IsGuarded || PageAsPool) {
//
// Return the memory pages back to free memory
//
- NoPages = EFI_SIZE_TO_PAGES (Size) + EFI_SIZE_TO_PAGES (Granularity) - 1;
+ NoPages = EFI_SIZE_TO_PAGES (Size) + EFI_SIZE_TO_PAGES (Granularity) - 1;
NoPages &= ~(UINTN)(EFI_SIZE_TO_PAGES (Granularity) - 1);
- if (IsGuarded) {
- Head = AdjustPoolHeadF ((EFI_PHYSICAL_ADDRESS)(UINTN)Head);
- CoreFreePoolPagesWithGuard (
- Pool->MemoryType,
- (EFI_PHYSICAL_ADDRESS)(UINTN)Head,
- NoPages
- );
- } else {
- CoreFreePoolPagesI (
- Pool->MemoryType,
- (EFI_PHYSICAL_ADDRESS)(UINTN)Head,
- NoPages
- );
- }
+ if (IsGuarded) {
+ Head = AdjustPoolHeadF ((EFI_PHYSICAL_ADDRESS)(UINTN)Head);
+ CoreFreePoolPagesWithGuard (
+ Pool->MemoryType,
+ (EFI_PHYSICAL_ADDRESS)(UINTN)Head,
+ NoPages
+ );
+ } else {
+ CoreFreePoolPagesI (
+ Pool->MemoryType,
+ (EFI_PHYSICAL_ADDRESS)(UINTN)Head,
+ NoPages
+ );
+ }
} else {