Skip to content

Commit

Permalink
MdeModulePkg: Moved CoreFreePoolPagesWithGuard() to Page.c and
Browse files Browse the repository at this point in the history
AdjustPoolHeadA(), AdjustPoolHeadF() to MemoryPoolLib.
  • Loading branch information
Mikhail Krichanov committed Feb 27, 2024
1 parent 07ae06e commit 92e3ebc
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 197 deletions.
2 changes: 0 additions & 2 deletions MdeModulePkg/Core/Dxe/DxeMain.inf
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,6 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfileDriverPath ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPageType ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPoolType ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdFwVolDxeMaxEncapsulationDepth ## CONSUMES
Expand Down
65 changes: 0 additions & 65 deletions MdeModulePkg/Core/Dxe/Mem/HeapGuard.c
Original file line number Diff line number Diff line change
Expand Up @@ -913,71 +913,6 @@ AdjustMemoryA (
}
}

/**
Adjust the pool head position to make sure the Guard page is adjavent to
pool tail or pool head.
@param[in] Memory Base address of memory allocated.
@param[in] NoPages Number of pages actually allocated.
@param[in] Size Size of memory requested.
(plus pool head/tail overhead)
@return Address of pool head.
**/
VOID *
AdjustPoolHeadA (
IN EFI_PHYSICAL_ADDRESS Memory,
IN UINTN NoPages,
IN UINTN Size
)
{
if ((Memory == 0) || ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) != 0)) {
//
// Pool head is put near the head Guard
//
return (VOID *)(UINTN)Memory;
}

//
// Pool head is put near the tail Guard
//
Size = ALIGN_VALUE (Size, 8);
return (VOID *)(UINTN)(Memory + EFI_PAGES_TO_SIZE (NoPages) - Size);
}

/**
Get the page base address according to pool head address.
@param[in] Memory Head address of pool to free.
@param[in] NoPages Number of pages actually allocated.
@param[in] Size Size of memory requested.
(plus pool head/tail overhead)
@return Address of pool head.
**/
VOID *
AdjustPoolHeadF (
IN EFI_PHYSICAL_ADDRESS Memory,
IN UINTN NoPages,
IN UINTN Size
)
{
if ((Memory == 0) || ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) != 0)) {
//
// Pool head is put near the head Guard
//
return (VOID *)(UINTN)Memory;
}

//
// Pool head is put near the tail Guard. We need to exactly undo the addition done in AdjustPoolHeadA
// because we may not have allocated the pool head on the first allocated page, since we are aligned to
// the tail and on some architectures, the runtime page allocation granularity is > one page. So we allocate
// more pages than we need and put the pool head somewhere past the first page.
//
return (VOID *)(UINTN)(Memory + Size - EFI_PAGES_TO_SIZE (NoPages));
}

/**
Allocate or free guarded memory.
Expand Down
35 changes: 0 additions & 35 deletions MdeModulePkg/Core/Dxe/Mem/HeapGuard.h
Original file line number Diff line number Diff line change
Expand Up @@ -333,41 +333,6 @@ DumpGuardedMemoryBitmap (
VOID
);

/**
Adjust the pool head position to make sure the Guard page is adjavent to
pool tail or pool head.
@param[in] Memory Base address of memory allocated.
@param[in] NoPages Number of pages actually allocated.
@param[in] Size Size of memory requested.
(plus pool head/tail overhead)
@return Address of pool head.
**/
VOID *
AdjustPoolHeadA (
IN EFI_PHYSICAL_ADDRESS Memory,
IN UINTN NoPages,
IN UINTN Size
);

/**
Get the page base address according to pool head address.
@param[in] Memory Head address of pool to free.
@param[in] NoPages Number of pages actually allocated.
@param[in] Size Size of memory requested.
(plus pool head/tail overhead)
@return Address of pool head.
**/
VOID *
AdjustPoolHeadF (
IN EFI_PHYSICAL_ADDRESS Memory,
IN UINTN NoPages,
IN UINTN Size
);

/**
Notify function used to set all Guard pages after CPU Arch Protocol installed.
**/
Expand Down
35 changes: 35 additions & 0 deletions MdeModulePkg/Core/Dxe/Mem/Page.c
Original file line number Diff line number Diff line change
Expand Up @@ -2130,6 +2130,41 @@ CoreFreePoolPagesI (
);
}

/**
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
**/
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. Used by the pool functions to allocate pages
to back pool allocation requests.
Expand Down
66 changes: 7 additions & 59 deletions MdeModulePkg/Library/MemoryPoolLib/InternalPool.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,53 +55,18 @@ InstallMemoryAttributesTableOnMemoryAllocation (
);

/**
Adjust the pool head position to make sure the Guard page is adjavent to
pool tail or pool head.
Internal function. Frees guarded pool pages.
@param[in] Memory Base address of memory allocated.
@param[in] NoPages Number of pages actually allocated.
@param[in] Size Size of memory requested.
(plus pool head/tail overhead)
@return Address of pool head.
**/
VOID *
AdjustPoolHeadA (
IN EFI_PHYSICAL_ADDRESS Memory,
IN UINTN NoPages,
IN UINTN Size
);

/**
Adjust the start address and number of pages to free according to Guard.
The purpose of this function is to keep the shared Guard page with adjacent
memory block if it's still in guard, or free it if no more sharing. Another
is to reserve pages as Guard pages in partial page free situation.
@param[in,out] Memory Base address of memory to free.
@param[in,out] NumberOfPages Size of memory to free.
@return VOID.
**/
VOID
AdjustMemoryF (
IN OUT EFI_PHYSICAL_ADDRESS *Memory,
IN OUT UINTN *NumberOfPages
);

/**
Unset head Guard and tail Guard for the given memory range.
@param[in] Memory Base address of memory to unset guard for.
@param[in] NumberOfPages Memory size in 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
@return VOID.
**/
VOID
UnsetGuardForMemory (
CoreFreePoolPagesWithGuard (
IN EFI_MEMORY_TYPE PoolType,
IN EFI_PHYSICAL_ADDRESS Memory,
IN UINTN NumberOfPages
IN UINTN NoPages
);

/**
Expand All @@ -118,23 +83,6 @@ IsMemoryGuarded (
IN EFI_PHYSICAL_ADDRESS Address
);

/**
Get the page base address according to pool head address.
@param[in] Memory Head address of pool to free.
@param[in] NoPages Number of pages actually allocated.
@param[in] Size Size of memory requested.
(plus pool head/tail overhead)
@return Address of pool head.
**/
VOID *
AdjustPoolHeadF (
IN EFI_PHYSICAL_ADDRESS Memory,
IN UINTN NoPages,
IN UINTN Size
);

/**
Internal function. Used by the pool functions to allocate pages
to back pool allocation requests.
Expand Down
103 changes: 67 additions & 36 deletions MdeModulePkg/Library/MemoryPoolLib/Pool.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,73 @@ POOL mPoolHead[EfiMaxMemoryType];
//
LIST_ENTRY mPoolHeadList = INITIALIZE_LIST_HEAD_VARIABLE (mPoolHeadList);

/**
Adjust the pool head position to make sure the Guard page is adjavent to
pool tail or pool head.
@param[in] Memory Base address of memory allocated.
@param[in] NoPages Number of pages actually allocated.
@param[in] Size Size of memory requested.
(plus pool head/tail overhead)
@return Address of pool head.
**/
STATIC
VOID *
AdjustPoolHeadA (
IN EFI_PHYSICAL_ADDRESS Memory,
IN UINTN NoPages,
IN UINTN Size
)
{
if ((Memory == 0) || ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) != 0)) {
//
// Pool head is put near the head Guard
//
return (VOID *)(UINTN)Memory;
}

//
// Pool head is put near the tail Guard
//
Size = ALIGN_VALUE (Size, 8);
return (VOID *)(UINTN)(Memory + EFI_PAGES_TO_SIZE (NoPages) - Size);
}

/**
Get the page base address according to pool head address.
@param[in] Memory Head address of pool to free.
@param[in] NoPages Number of pages actually allocated.
@param[in] Size Size of memory requested.
(plus pool head/tail overhead)
@return Address of pool head.
**/
STATIC
VOID *
AdjustPoolHeadF (
IN EFI_PHYSICAL_ADDRESS Memory,
IN UINTN NoPages,
IN UINTN Size
)
{
if ((Memory == 0) || ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) != 0)) {
//
// Pool head is put near the head Guard
//
return (VOID *)(UINTN)Memory;
}

//
// Pool head is put near the tail Guard. We need to exactly undo the addition done in AdjustPoolHeadA
// because we may not have allocated the pool head on the first allocated page, since we are aligned to
// the tail and on some architectures, the runtime page allocation granularity is > one page. So we allocate
// more pages than we need and put the pool head somewhere past the first page.
//
return (VOID *)(UINTN)(Memory + Size - EFI_PAGES_TO_SIZE (NoPages));
}

/**
Get pool size table index from the specified size.
Expand Down Expand Up @@ -558,42 +625,6 @@ CoreFreePool (
return Status;
}

/**
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
Expand Down

0 comments on commit 92e3ebc

Please sign in to comment.