MdeModulePkg: Moved CoreFreePoolPagesWithGuard() to Page.c and

AdjustPoolHeadA(), AdjustPoolHeadF() to MemoryPoolLib.
This commit is contained in:
Mikhail Krichanov 2024-02-27 16:09:34 +03:00
parent 3108a4b0f4
commit faa4098dee
6 changed files with 109 additions and 197 deletions

View File

@ -195,8 +195,6 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfileDriverPath ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfileDriverPath ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPageType ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPoolType ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdFwVolDxeMaxEncapsulationDepth ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdFwVolDxeMaxEncapsulationDepth ## CONSUMES

View File

@ -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. Allocate or free guarded memory.

View File

@ -333,41 +333,6 @@ DumpGuardedMemoryBitmap (
VOID 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. Notify function used to set all Guard pages after CPU Arch Protocol installed.
**/ **/

View File

@ -2255,6 +2255,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 Internal function. Used by the pool functions to allocate pages
to back pool allocation requests. to back pool allocation requests.

View File

@ -55,53 +55,18 @@ InstallMemoryAttributesTableOnMemoryAllocation (
); );
/** /**
Adjust the pool head position to make sure the Guard page is adjavent to Internal function. Frees guarded pool pages.
pool tail or pool head.
@param[in] Memory Base address of memory allocated. @param PoolType The type of memory for the pool pages
@param[in] NoPages Number of pages actually allocated. @param Memory The base address to free
@param[in] Size Size of memory requested. @param NoPages The number of pages to free
(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 VOID
AdjustMemoryF ( CoreFreePoolPagesWithGuard (
IN OUT EFI_PHYSICAL_ADDRESS *Memory, IN EFI_MEMORY_TYPE PoolType,
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.
@return VOID.
**/
VOID
UnsetGuardForMemory (
IN EFI_PHYSICAL_ADDRESS Memory, IN EFI_PHYSICAL_ADDRESS Memory,
IN UINTN NumberOfPages IN UINTN NoPages
); );
/** /**
@ -118,23 +83,6 @@ IsMemoryGuarded (
IN EFI_PHYSICAL_ADDRESS Address 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 Internal function. Used by the pool functions to allocate pages
to back pool allocation requests. to back pool allocation requests.

View File

@ -87,6 +87,73 @@ POOL mPoolHead[EfiMaxMemoryType];
// //
LIST_ENTRY mPoolHeadList = INITIALIZE_LIST_HEAD_VARIABLE (mPoolHeadList); 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. Get pool size table index from the specified size.
@ -569,42 +636,6 @@ CoreFreePool (
return Status; 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. Internal function to free a pool entry.
Caller must have the memory lock held Caller must have the memory lock held