IN EFI_MEMORY_TYPE NewType\r
)\r
{\r
+ UINT64 OldStart;\r
+ UINTN OldPages;\r
+\r
if (NewType == EfiConventionalMemory) {\r
+ OldStart = Start;\r
+ OldPages = NumberOfPages;\r
+\r
AdjustMemoryF (&Start, &NumberOfPages);\r
if (NumberOfPages == 0) {\r
return EFI_SUCCESS;\r
}\r
+\r
+ //\r
+ // It's safe to unset Guard page inside memory lock because there should\r
+ // be no memory allocation occurred in updating memory page attribute at\r
+ // this point. And unsetting Guard page before free will prevent Guard\r
+ // page just freed back to pool from being allocated right away before\r
+ // marking it usable (from non-present to present).\r
+ //\r
+ UnsetGuardForMemory (OldStart, OldPages);\r
} else {\r
AdjustMemoryA (&Start, &NumberOfPages);\r
}\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
- //\r
- // Avoid calling DEBUG_CLEAR_MEMORY() for an address of 0 because this\r
- // macro will ASSERT() if address is 0. Instead, CoreAddRange()\r
- // guarantees that the page starting at address 0 is always filled\r
- // with zeros.\r
- //\r
if (RangeEnd > EFI_PAGE_SIZE) {\r
DEBUG_CLEAR_MEMORY ((VOID *)(UINTN) EFI_PAGE_SIZE, (UINTN) (RangeEnd - EFI_PAGE_SIZE + 1));\r
}\r
} else {\r
- //\r
- // If Heap Guard is enabled, the page at the top and/or bottom of\r
- // this memory block to free might be inaccessible. Skipping them\r
- // to avoid page fault exception.\r
- //\r
- UINT64 StartToClear;\r
- UINT64 EndToClear;\r
-\r
- StartToClear = Start;\r
- EndToClear = RangeEnd + 1;\r
- if (PcdGet8 (PcdHeapGuardPropertyMask) & (BIT1|BIT0)) {\r
- if (IsGuardPage(StartToClear)) {\r
- StartToClear += EFI_PAGE_SIZE;\r
- }\r
- if (IsGuardPage (EndToClear - 1)) {\r
- EndToClear -= EFI_PAGE_SIZE;\r
- }\r
- }\r
-\r
- if (EndToClear > StartToClear) {\r
- DEBUG_CLEAR_MEMORY(\r
- (VOID *)(UINTN)StartToClear,\r
- (UINTN)(EndToClear - StartToClear)\r
- );\r
- }\r
+ DEBUG_CLEAR_MEMORY ((VOID *)(UINTN) Start, (UINTN) (RangeEnd - Start + 1));\r
}\r
}\r
\r
\r
Done:\r
CoreReleaseMemoryLock ();\r
- if (IsGuarded) {\r
- UnsetGuardForMemory(Memory, NumberOfPages);\r
- }\r
return Status;\r
}\r
\r
\r
AdjustMemoryF (&Memory, &NoPages);\r
if (NoPages > 0) {\r
+ //\r
+ // It's safe to unset Guard page inside memory lock because there should\r
+ // be no memory allocation occurred in updating memory page attribute at\r
+ // this point. And unsetting Guard page before free will prevent Guard\r
+ // page just freed back to pool from being allocated right away before\r
+ // marking it usable (from non-present to present).\r
+ //\r
+ UnsetGuardForMemory (MemoryGuarded, NoPagesGuarded);\r
CoreFreePoolPagesI (PoolType, Memory, NoPages);\r
}\r
-\r
- UnsetGuardForMemory (MemoryGuarded, NoPagesGuarded);\r
}\r
\r
/**\r