\r
#include "DxeMain.h"\r
#include "Imem.h"\r
+#include "HeapGuard.h"
\r
//\r
// Entry for tracking the memory regions for each memory type to coalesce similar memory types\r
//\r
// The list is empty, to allocate one page to refuel the list\r
//\r
- FreeDescriptorEntries = CoreAllocatePoolPages (EfiBootServicesData,\r
+ FreeDescriptorEntries = CoreAllocatePoolPages (
+ EfiBootServicesData,
EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION_GRANULARITY),\r
- DEFAULT_PAGE_ALLOCATION_GRANULARITY);\r
+ DEFAULT_PAGE_ALLOCATION_GRANULARITY,
+ FALSE
+ );
if (FreeDescriptorEntries != NULL) {\r
//\r
// Enque the free memmory map entries into the list\r
//\r
CoreAddRange (MemType, Start, RangeEnd, Attribute);\r
if (ChangingType && (MemType == EfiConventionalMemory)) {\r
- //\r
- // Avoid calling DEBUG_CLEAR_MEMORY() for an address of 0 because this\r
- // macro will ASSERT() if address is 0. Instead, CoreAddRange() guarantees\r
- // that the page starting at address 0 is always filled with zeros.\r
- //\r
if (Start == 0) {\r
+ //
+ // Avoid calling DEBUG_CLEAR_MEMORY() for an address of 0 because this
+ // macro will ASSERT() if address is 0. Instead, CoreAddRange()
+ // guarantees that the page starting at address 0 is always filled
+ // with zeros.
+ //
if (RangeEnd > EFI_PAGE_SIZE) {\r
DEBUG_CLEAR_MEMORY ((VOID *)(UINTN) EFI_PAGE_SIZE, (UINTN) (RangeEnd - EFI_PAGE_SIZE + 1));\r
}\r
} else {\r
- DEBUG_CLEAR_MEMORY ((VOID *)(UINTN) Start, (UINTN) (RangeEnd - Start + 1));\r
+ //
+ // If Heap Guard is enabled, the page at the top and/or bottom of
+ // this memory block to free might be inaccessible. Skipping them
+ // to avoid page fault exception.
+ //
+ UINT64 StartToClear;
+ UINT64 EndToClear;
+
+ StartToClear = Start;
+ EndToClear = RangeEnd;
+ if (PcdGet8 (PcdHeapGuardPropertyMask) & (BIT1|BIT0)) {
+ if (IsGuardPage(StartToClear)) {
+ StartToClear += EFI_PAGE_SIZE;
+ }
+ if (IsGuardPage (EndToClear)) {
+ EndToClear -= EFI_PAGE_SIZE;
+ }
+ ASSERT (EndToClear > StartToClear);
+ }
+
+ DEBUG_CLEAR_MEMORY(
+ (VOID *)(UINTN)StartToClear,
+ (UINTN)(EndToClear - StartToClear + 1)
+ );
}\r
}\r
\r
@param NewType The type of memory the range is going to be\r
turned into\r
@param Alignment Bits to align with\r
+ @param NeedGuard Flag to indicate Guard page is needed or not
\r
@return The base address of the range, or 0 if the range was not found\r
\r
IN UINT64 MinAddress,\r
IN UINT64 NumberOfPages,\r
IN EFI_MEMORY_TYPE NewType,\r
- IN UINTN Alignment\r
+ IN UINTN Alignment,
+ IN BOOLEAN NeedGuard
)\r
{\r
UINT64 NumberOfBytes;\r
// If this is the best match so far remember it\r
//\r
if (DescEnd > Target) {\r
+ if (NeedGuard) {
+ DescEnd = AdjustMemoryS (
+ DescEnd + 1 - DescNumberOfBytes,
+ DescNumberOfBytes,
+ NumberOfBytes
+ );
+ if (DescEnd == 0) {
+ continue;
+ }
+ }
+
Target = DescEnd;\r
}\r
}\r
@param NewType The type of memory the range is going to be\r
turned into\r
@param Alignment Bits to align with\r
+ @param NeedGuard Flag to indicate Guard page is needed or not
\r
@return The base address of the range, or 0 if the range was not found.\r
\r
IN UINT64 MaxAddress,\r
IN UINT64 NoPages,\r
IN EFI_MEMORY_TYPE NewType,\r
- IN UINTN Alignment\r
+ IN UINTN Alignment,
+ IN BOOLEAN NeedGuard
)\r
{\r
UINT64 Start;\r
mMemoryTypeStatistics[NewType].BaseAddress, \r
NoPages, \r
NewType, \r
- Alignment\r
+ Alignment,
+ NeedGuard
);\r
if (Start != 0) {\r
return Start;\r
// Attempt to find free pages in the default allocation bin\r
//\r
if (MaxAddress >= mDefaultMaximumAddress) {\r
- Start = CoreFindFreePagesI (mDefaultMaximumAddress, 0, NoPages, NewType, Alignment);\r
+ Start = CoreFindFreePagesI (mDefaultMaximumAddress, 0, NoPages, NewType,
+ Alignment, NeedGuard);
if (Start != 0) {\r
if (Start < mDefaultBaseAddress) {\r
mDefaultBaseAddress = Start;\r
// address range. If this allocation fails, then there are not enough \r
// resources anywhere to satisfy the request.\r
//\r
- Start = CoreFindFreePagesI (MaxAddress, 0, NoPages, NewType, Alignment);\r
+ Start = CoreFindFreePagesI (MaxAddress, 0, NoPages, NewType, Alignment,
+ NeedGuard);
if (Start != 0) {\r
return Start;\r
}\r
//\r
// If any memory resources were promoted, then re-attempt the allocation\r
//\r
- return FindFreePages (MaxAddress, NoPages, NewType, Alignment);\r
+ return FindFreePages (MaxAddress, NoPages, NewType, Alignment, NeedGuard);
}\r
\r
\r
@param NumberOfPages The number of pages to allocate\r
@param Memory A pointer to receive the base allocated memory\r
address\r
+ @param NeedGuard Flag to indicate Guard page is needed or not
\r
@return Status. On success, Memory is filled in with the base address allocated\r
@retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in\r
IN EFI_ALLOCATE_TYPE Type,\r
IN EFI_MEMORY_TYPE MemoryType,\r
IN UINTN NumberOfPages,\r
- IN OUT EFI_PHYSICAL_ADDRESS *Memory\r
+ IN OUT EFI_PHYSICAL_ADDRESS *Memory,
+ IN BOOLEAN NeedGuard
)\r
{\r
EFI_STATUS Status;\r
// If not a specific address, then find an address to allocate\r
//\r
if (Type != AllocateAddress) {\r
- Start = FindFreePages (MaxAddress, NumberOfPages, MemoryType, Alignment);\r
+ Start = FindFreePages (MaxAddress, NumberOfPages, MemoryType, Alignment,
+ NeedGuard);
if (Start == 0) {\r
Status = EFI_OUT_OF_RESOURCES;\r
goto Done;\r
//\r
// Convert pages from FreeMemory to the requested type\r
//\r
- Status = CoreConvertPages (Start, NumberOfPages, MemoryType);\r
+ if (NeedGuard) {
+ Status = CoreConvertPagesWithGuard(Start, NumberOfPages, MemoryType);
+ } else {
+ Status = CoreConvertPages(Start, NumberOfPages, MemoryType);
+ }
\r
Done:\r
CoreReleaseMemoryLock ();\r
\r
if (!EFI_ERROR (Status)) {\r
+ if (NeedGuard) {
+ SetGuardForMemory (Start, NumberOfPages);
+ }
*Memory = Start;\r
}\r
\r
)\r
{\r
EFI_STATUS Status;\r
+ BOOLEAN NeedGuard;
\r
- Status = CoreInternalAllocatePages (Type, MemoryType, NumberOfPages, Memory);\r
+ NeedGuard = IsPageTypeToGuard (MemoryType, Type) && !mOnGuarding;
+ Status = CoreInternalAllocatePages (Type, MemoryType, NumberOfPages, Memory,
+ NeedGuard);
if (!EFI_ERROR (Status)) {\r
CoreUpdateProfile (\r
(EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0),\r
LIST_ENTRY *Link;\r
MEMORY_MAP *Entry;\r
UINTN Alignment;\r
+ BOOLEAN IsGuarded;
\r
//\r
// Free the range\r
//\r
// Find the entry that the covers the range\r
//\r
+ IsGuarded = FALSE;
Entry = NULL;\r
for (Link = gMemoryMap.ForwardLink; Link != &gMemoryMap; Link = Link->ForwardLink) {\r
Entry = CR(Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);\r
*MemoryType = Entry->Type;\r
}\r
\r
- Status = CoreConvertPages (Memory, NumberOfPages, EfiConventionalMemory);\r
-\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
+ IsGuarded = IsPageTypeToGuard (Entry->Type, AllocateAnyPages) &&
+ IsMemoryGuarded (Memory);
+ if (IsGuarded) {
+ Status = CoreConvertPagesWithGuard (Memory, NumberOfPages,
+ EfiConventionalMemory);
+ } else {
+ Status = CoreConvertPages (Memory, NumberOfPages, EfiConventionalMemory);
}\r
\r
Done:\r
CoreReleaseMemoryLock ();\r
+ if (IsGuarded) {
+ UnsetGuardForMemory(Memory, NumberOfPages);
+ }
return Status;\r
}\r
\r
\r
*MemoryMapSize = BufferSize;\r
\r
+ DEBUG_CODE (
+ if (PcdGet8 (PcdHeapGuardPropertyMask) & (BIT1|BIT0)) {
+ DumpGuardedMemoryBitmap ();
+ }
+ );
+
return Status;\r
}\r
\r
@param PoolType The type of memory for the new pool pages\r
@param NumberOfPages No of pages to allocate\r
@param Alignment Bits to align.\r
+ @param NeedGuard Flag to indicate Guard page is needed or not
\r
@return The allocated memory, or NULL\r
\r
CoreAllocatePoolPages (\r
IN EFI_MEMORY_TYPE PoolType,\r
IN UINTN NumberOfPages,\r
- IN UINTN Alignment\r
+ IN UINTN Alignment,
+ IN BOOLEAN NeedGuard
)\r
{\r
UINT64 Start;\r
//\r
// Find the pages to convert\r
//\r
- Start = FindFreePages (MAX_ADDRESS, NumberOfPages, PoolType, Alignment);\r
+ Start = FindFreePages (MAX_ADDRESS, NumberOfPages, PoolType, Alignment,
+ NeedGuard);
\r
//\r
// Convert it to boot services data\r
if (Start == 0) {\r
DEBUG ((DEBUG_ERROR | DEBUG_PAGE, "AllocatePoolPages: failed to allocate %d pages\n", (UINT32)NumberOfPages));\r
} else {\r
- CoreConvertPages (Start, NumberOfPages, PoolType);\r
+ if (NeedGuard) {
+ CoreConvertPagesWithGuard (Start, NumberOfPages, PoolType);
+ } else {
+ CoreConvertPages (Start, NumberOfPages, PoolType);
+ }
}\r
\r
return (VOID *)(UINTN) Start;\r