diff --git a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c b/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c index 9377f620c5..0c0ca61872 100644 --- a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c +++ b/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c @@ -1037,12 +1037,17 @@ AdjustPoolHeadA ( 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 EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NoPages, + IN UINTN Size ) { if ((Memory == 0) || ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) != 0)) { @@ -1053,9 +1058,12 @@ AdjustPoolHeadF ( } // - // Pool head is put near the tail Guard + // 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 & ~EFI_PAGE_MASK); + return (VOID *)(UINTN)(Memory + Size - EFI_PAGES_TO_SIZE (NoPages)); } /** diff --git a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.h b/MdeModulePkg/Core/Dxe/Mem/HeapGuard.h index 9a32b4dd51..24b4206c0e 100644 --- a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.h +++ b/MdeModulePkg/Core/Dxe/Mem/HeapGuard.h @@ -378,12 +378,17 @@ AdjustPoolHeadA ( 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 EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NoPages, + IN UINTN Size ); /** diff --git a/MdeModulePkg/Core/Dxe/Mem/Pool.c b/MdeModulePkg/Core/Dxe/Mem/Pool.c index b20cbfdedb..716dd045f9 100644 --- a/MdeModulePkg/Core/Dxe/Mem/Pool.c +++ b/MdeModulePkg/Core/Dxe/Mem/Pool.c @@ -783,7 +783,7 @@ CoreFreePoolI ( 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); + Head = AdjustPoolHeadF ((EFI_PHYSICAL_ADDRESS)(UINTN)Head, NoPages, Size); CoreFreePoolPagesWithGuard ( Pool->MemoryType, (EFI_PHYSICAL_ADDRESS)(UINTN)Head,