diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index c6f028e613..a8fe5f1975 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -194,8 +194,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 diff --git a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c b/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c index 8d173026f3..60d04e9597 100644 --- a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c +++ b/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c @@ -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. diff --git a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.h b/MdeModulePkg/Core/Dxe/Mem/HeapGuard.h index 7289549ee8..e9d4031c0f 100644 --- a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.h +++ b/MdeModulePkg/Core/Dxe/Mem/HeapGuard.h @@ -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. **/ diff --git a/MdeModulePkg/Core/Dxe/Mem/Page.c b/MdeModulePkg/Core/Dxe/Mem/Page.c index 0148592d6c..b868ae7e31 100644 --- a/MdeModulePkg/Core/Dxe/Mem/Page.c +++ b/MdeModulePkg/Core/Dxe/Mem/Page.c @@ -2248,6 +2248,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. diff --git a/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h b/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h index a8dfc1b5ce..b0bb574f21 100644 --- a/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h +++ b/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h @@ -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) + @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 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. - - @return VOID. -**/ -VOID -UnsetGuardForMemory ( +CoreFreePoolPagesWithGuard ( + IN EFI_MEMORY_TYPE PoolType, IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NumberOfPages + IN UINTN NoPages ); /** @@ -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. diff --git a/MdeModulePkg/Library/MemoryPoolLib/Pool.c b/MdeModulePkg/Library/MemoryPoolLib/Pool.c index 9e8fb90904..a35fa80058 100644 --- a/MdeModulePkg/Library/MemoryPoolLib/Pool.c +++ b/MdeModulePkg/Library/MemoryPoolLib/Pool.c @@ -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. @@ -569,42 +636,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