\r
#include "DxeMain.h"\r
#include "Imem.h"\r
+#include "HeapGuard.h"
\r
STATIC EFI_LOCK mPoolMemoryLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY);\r
\r
}\r
}\r
\r
- Pool = CoreAllocatePoolI (EfiBootServicesData, sizeof (POOL));\r
+ Pool = CoreAllocatePoolI (EfiBootServicesData, sizeof (POOL), FALSE);
if (Pool == NULL) {\r
return NULL;\r
}\r
OUT VOID **Buffer\r
)\r
{\r
- EFI_STATUS Status;\r
+ EFI_STATUS Status;
+ BOOLEAN NeedGuard;
\r
//\r
// If it's not a valid type, fail it\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
+ NeedGuard = IsPoolTypeToGuard (PoolType) && !mOnGuarding;
+
//\r
// Acquire the memory lock and make the allocation\r
//\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
- *Buffer = CoreAllocatePoolI (PoolType, Size);\r
+ *Buffer = CoreAllocatePoolI (PoolType, Size, NeedGuard);
CoreReleaseLock (&mPoolMemoryLock);\r
return (*Buffer != NULL) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;\r
}\r
return Status;\r
}\r
\r
+/**\r
+ Internal function. Used by the pool functions to allocate pages\r
+ to back pool allocation requests.\r
+\r
+ @param PoolType The type of memory for the new pool pages\r
+ @param NoPages No of pages to allocate\r
+ @param Granularity Bits to align.\r
+ @param NeedGuard Flag to indicate Guard page is needed or not
+\r
+ @return The allocated memory, or NULL\r
+\r
+**/\r
STATIC\r
VOID *\r
CoreAllocatePoolPagesI (\r
IN EFI_MEMORY_TYPE PoolType,\r
IN UINTN NoPages,\r
- IN UINTN Granularity\r
+ IN UINTN Granularity,
+ IN BOOLEAN NeedGuard
)\r
{\r
VOID *Buffer;\r
return NULL;\r
}\r
\r
- Buffer = CoreAllocatePoolPages (PoolType, NoPages, Granularity);\r
+ Buffer = CoreAllocatePoolPages (PoolType, NoPages, Granularity, NeedGuard);
CoreReleaseMemoryLock ();\r
\r
if (Buffer != NULL) {\r
- ApplyMemoryProtectionPolicy (EfiConventionalMemory, PoolType,\r
+ if (NeedGuard) {
+ SetGuardForMemory ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, NoPages);
+ }
+ ApplyMemoryProtectionPolicy(EfiConventionalMemory, PoolType,
(EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, EFI_PAGES_TO_SIZE (NoPages));\r
}\r
return Buffer;\r
\r
@param PoolType Type of pool to allocate\r
@param Size The amount of pool to allocate\r
+ @param NeedGuard Flag to indicate Guard page is needed or not
\r
@return The allocate pool, or NULL\r
\r
VOID *\r
CoreAllocatePoolI (\r
IN EFI_MEMORY_TYPE PoolType,\r
- IN UINTN Size\r
+ IN UINTN Size,
+ IN BOOLEAN NeedGuard
)\r
{\r
POOL *Pool;\r
UINTN Offset, MaxOffset;\r
UINTN NoPages;\r
UINTN Granularity;\r
+ BOOLEAN HasPoolTail;
\r
ASSERT_LOCKED (&mPoolMemoryLock);\r
\r
PoolType == EfiRuntimeServicesCode ||\r
PoolType == EfiRuntimeServicesData) {\r
\r
- Granularity = EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT;\r
+ Granularity = RUNTIME_PAGE_ALLOCATION_GRANULARITY;\r
} else {\r
- Granularity = DEFAULT_PAGE_ALLOCATION;\r
+ Granularity = DEFAULT_PAGE_ALLOCATION_GRANULARITY;\r
}\r
\r
//\r
// Adjust the size by the pool header & tail overhead\r
//\r
\r
+ HasPoolTail = !(NeedGuard &&
+ ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) == 0));
+
//\r
// Adjusting the Size to be of proper alignment so that\r
// we don't get an unaligned access fault later when\r
// If allocation is over max size, just allocate pages for the request\r
// (slow)\r
//\r
- if (Index >= SIZE_TO_LIST (Granularity)) {\r
- NoPages = EFI_SIZE_TO_PAGES(Size) + EFI_SIZE_TO_PAGES (Granularity) - 1;\r
+ 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;
NoPages &= ~(UINTN)(EFI_SIZE_TO_PAGES (Granularity) - 1);\r
- Head = CoreAllocatePoolPagesI (PoolType, NoPages, Granularity);\r
+ Head = CoreAllocatePoolPagesI (PoolType, NoPages, Granularity, NeedGuard);
+ if (NeedGuard) {
+ Head = AdjustPoolHeadA ((EFI_PHYSICAL_ADDRESS)(UINTN)Head, NoPages, Size);
+ }
goto Done;\r
}\r
\r
//\r
// Get another page\r
//\r
- NewPage = CoreAllocatePoolPagesI (PoolType, EFI_SIZE_TO_PAGES (Granularity), Granularity);\r
+ NewPage = CoreAllocatePoolPagesI (PoolType, EFI_SIZE_TO_PAGES (Granularity),
+ Granularity, NeedGuard);
if (NewPage == NULL) {\r
goto Done;\r
}\r
\r
if (Head != NULL) {\r
\r
+ //
+ // Account the allocation
+ //
+ Pool->Used += Size;
+
//\r
// If we have a pool buffer, fill in the header & tail info\r
//\r
Head->Signature = POOL_HEAD_SIGNATURE;\r
Head->Size = Size;\r
Head->Type = (EFI_MEMORY_TYPE) PoolType;\r
- Tail = HEAD_TO_TAIL (Head);\r
- Tail->Signature = POOL_TAIL_SIGNATURE;\r
- Tail->Size = Size;\r
Buffer = Head->Data;\r
- DEBUG_CLEAR_MEMORY (Buffer, Size - POOL_OVERHEAD);\r
+
+ 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);
\r
DEBUG ((\r
DEBUG_POOL,\r
"AllocatePoolI: Type %x, Addr %p (len %lx) %,ld\n", PoolType,\r
Buffer,\r
- (UINT64)(Size - POOL_OVERHEAD),\r
+ (UINT64)Size,
(UINT64) Pool->Used\r
));\r
\r
- //\r
- // Account the allocation\r
- //\r
- Pool->Used += Size;\r
\r
} else {\r
DEBUG ((DEBUG_ERROR | DEBUG_POOL, "AllocatePool: failed to allocate %ld bytes\n", (UINT64) Size));\r
return Status;\r
}\r
\r
+/**\r
+ Internal function. Frees pool pages allocated via CoreAllocatePoolPagesI().\r
+\r
+ @param PoolType The type of memory for the pool pages\r
+ @param Memory The base address to free\r
+ @param NoPages The number of pages to free\r
+\r
+**/\r
STATIC\r
VOID\r
CoreFreePoolPagesI (\r
(EFI_PHYSICAL_ADDRESS)(UINTN)Memory, EFI_PAGES_TO_SIZE (NoPages));\r
}\r
\r
+/**
+ 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);
+}
+
/**\r
Internal function to free a pool entry.\r
Caller must have the memory lock held\r
UINTN Offset;\r
BOOLEAN AllFree;\r
UINTN Granularity;\r
+ BOOLEAN IsGuarded;
+ BOOLEAN HasPoolTail;
\r
ASSERT(Buffer != NULL);\r
//\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- Tail = HEAD_TO_TAIL (Head);\r
- ASSERT(Tail != NULL);\r
-\r
- //\r
- // Debug\r
- //\r
- ASSERT (Tail->Signature == POOL_TAIL_SIGNATURE);\r
- ASSERT (Head->Size == Tail->Size);\r
- ASSERT_LOCKED (&mPoolMemoryLock);\r
-\r
- if (Tail->Signature != POOL_TAIL_SIGNATURE) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (Head->Size != Tail->Size) {\r
- return EFI_INVALID_PARAMETER;\r
+ IsGuarded = IsPoolTypeToGuard (Head->Type) &&
+ IsMemoryGuarded ((EFI_PHYSICAL_ADDRESS)(UINTN)Head);
+ HasPoolTail = !(IsGuarded &&
+ ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) == 0));
+\r
+ if (HasPoolTail) {
+ Tail = HEAD_TO_TAIL (Head);
+ ASSERT (Tail != NULL);
+\r
+ //
+ // Debug
+ //
+ ASSERT (Tail->Signature == POOL_TAIL_SIGNATURE);
+ ASSERT (Head->Size == Tail->Size);
+\r
+ if (Tail->Signature != POOL_TAIL_SIGNATURE) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Head->Size != Tail->Size) {
+ return EFI_INVALID_PARAMETER;
+ }
}\r
\r
+ ASSERT_LOCKED (&mPoolMemoryLock);
+
//\r
// Determine the pool type and account for it\r
//\r
Head->Type == EfiRuntimeServicesCode ||\r
Head->Type == EfiRuntimeServicesData) {\r
\r
- Granularity = EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT;\r
+ Granularity = RUNTIME_PAGE_ALLOCATION_GRANULARITY;\r
} else {\r
- Granularity = DEFAULT_PAGE_ALLOCATION;\r
+ Granularity = DEFAULT_PAGE_ALLOCATION_GRANULARITY;\r
}\r
\r
if (PoolType != NULL) {\r
//\r
// If it's not on the list, it must be pool pages\r
//\r
- if (Index >= SIZE_TO_LIST (Granularity)) {\r
+ if (Index >= SIZE_TO_LIST (Granularity) || IsGuarded) {
\r
//\r
// Return the memory pages back to free memory\r
//\r
- NoPages = EFI_SIZE_TO_PAGES(Size) + EFI_SIZE_TO_PAGES (Granularity) - 1;\r
+ NoPages = EFI_SIZE_TO_PAGES (Size) + EFI_SIZE_TO_PAGES (Granularity) - 1;
NoPages &= ~(UINTN)(EFI_SIZE_TO_PAGES (Granularity) - 1);\r
- CoreFreePoolPagesI (Pool->MemoryType, (EFI_PHYSICAL_ADDRESS) (UINTN) Head, NoPages);\r
+ 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
+ );
+ }
\r
} else {\r
\r