35 = GUARDED_HEAP_MAP_TABLE_DEPTH_SHIFTS;
37 = GUARDED_HEAP_MAP_TABLE_DEPTH_MASKS;
67 StartBit = (
UINTN)GUARDED_HEAP_MAP_ENTRY_BIT_INDEX (Address);
68 EndBit = (StartBit + BitNumber - 1) % GUARDED_HEAP_MAP_ENTRY_BITS;
70 if ((StartBit + BitNumber) >= GUARDED_HEAP_MAP_ENTRY_BITS) {
71 Msbs = (GUARDED_HEAP_MAP_ENTRY_BITS - StartBit) %
72 GUARDED_HEAP_MAP_ENTRY_BITS;
73 Lsbs = (EndBit + 1) % GUARDED_HEAP_MAP_ENTRY_BITS;
74 Qwords = (BitNumber - Msbs) / GUARDED_HEAP_MAP_ENTRY_BITS;
89 Qwords * GUARDED_HEAP_MAP_ENTRY_BYTES,
123 StartBit = (
UINTN)GUARDED_HEAP_MAP_ENTRY_BIT_INDEX (Address);
124 EndBit = (StartBit + BitNumber - 1) % GUARDED_HEAP_MAP_ENTRY_BITS;
126 if ((StartBit + BitNumber) >= GUARDED_HEAP_MAP_ENTRY_BITS) {
127 Msbs = (GUARDED_HEAP_MAP_ENTRY_BITS - StartBit) %
128 GUARDED_HEAP_MAP_ENTRY_BITS;
129 Lsbs = (EndBit + 1) % GUARDED_HEAP_MAP_ENTRY_BITS;
130 Qwords = (BitNumber - Msbs) / GUARDED_HEAP_MAP_ENTRY_BITS;
138 *BitMap &= ~LShiftU64 (
LShiftU64 (1, Msbs) - 1, StartBit);
143 SetMem64 ((
VOID *)BitMap, Qwords * GUARDED_HEAP_MAP_ENTRY_BYTES, 0);
178 ASSERT (BitNumber <= GUARDED_HEAP_MAP_ENTRY_BITS);
180 StartBit = (
UINTN)GUARDED_HEAP_MAP_ENTRY_BIT_INDEX (Address);
181 EndBit = (StartBit + BitNumber - 1) % GUARDED_HEAP_MAP_ENTRY_BITS;
183 if ((StartBit + BitNumber) > GUARDED_HEAP_MAP_ENTRY_BITS) {
184 Msbs = GUARDED_HEAP_MAP_ENTRY_BITS - StartBit;
185 Lsbs = (EndBit + 1) % GUARDED_HEAP_MAP_ENTRY_BITS;
191 if ((StartBit == 0) && (BitNumber == GUARDED_HEAP_MAP_ENTRY_BITS)) {
226 if (EFI_ERROR (Status)) {
246 IN BOOLEAN AllocMapUnit,
260 while (AllocMapUnit &&
261 mMapLevel < GUARDED_HEAP_MAP_TABLE_DEPTH &&
264 mLevelShift[GUARDED_HEAP_MAP_TABLE_DEPTH - mMapLevel - 1]
267 if (mGuardedMemoryMap != 0) {
268 Size = (mLevelMask[GUARDED_HEAP_MAP_TABLE_DEPTH - mMapLevel - 1] + 1)
269 * GUARDED_HEAP_MAP_ENTRY_BYTES;
271 if (MapMemory == 0) {
272 ASSERT (MapMemory != 0);
278 *(UINT64 *)(
UINTN)MapMemory = mGuardedMemoryMap;
279 mGuardedMemoryMap = MapMemory;
285 GuardMap = &mGuardedMemoryMap;
286 for (Level = GUARDED_HEAP_MAP_TABLE_DEPTH - mMapLevel;
287 Level < GUARDED_HEAP_MAP_TABLE_DEPTH;
290 if (*GuardMap == 0) {
296 Size = (mLevelMask[Level] + 1) * GUARDED_HEAP_MAP_ENTRY_BYTES;
298 ASSERT (MapMemory != 0);
301 *GuardMap = MapMemory;
305 Index &= mLevelMask[Level];
306 GuardMap = (UINT64 *)(
UINTN)((*GuardMap) + Index *
sizeof (UINT64));
309 BitsToUnitEnd = GUARDED_HEAP_MAP_BITS - GUARDED_HEAP_MAP_BIT_INDEX (Address);
312 return BitsToUnitEnd;
334 while (NumberOfPages > 0) {
336 ASSERT (BitMap !=
NULL);
338 if (NumberOfPages > BitsToUnitEnd) {
340 Bits = BitsToUnitEnd;
342 Bits = NumberOfPages;
345 SetBits (Address, Bits, BitMap);
347 NumberOfPages -= Bits;
371 while (NumberOfPages > 0) {
373 ASSERT (BitMap !=
NULL);
375 if (NumberOfPages > BitsToUnitEnd) {
377 Bits = BitsToUnitEnd;
379 Bits = NumberOfPages;
384 NumberOfPages -= Bits;
409 ASSERT (NumberOfPages <= GUARDED_HEAP_MAP_ENTRY_BITS);
413 while (NumberOfPages > 0) {
416 if (NumberOfPages > BitsToUnitEnd) {
418 Bits = BitsToUnitEnd;
420 Bits = NumberOfPages;
423 if (BitMap !=
NULL) {
428 NumberOfPages -= Bits;
451 if (GuardMap !=
NULL) {
454 GUARDED_HEAP_MAP_ENTRY_BIT_INDEX (Address)
486 return ((BitMap == BIT0) || (BitMap == BIT2) || (BitMap == (BIT2 | BIT0)));
523 if (mSmmMemoryAttribute !=
NULL) {
525 Status = mSmmMemoryAttribute->SetMemoryAttributes (
553 if (mSmmMemoryAttribute !=
NULL) {
555 Status = mSmmMemoryAttribute->ClearMemoryAttributes (
559 EFI_MEMORY_RP|EFI_MEMORY_RO|EFI_MEMORY_XP
567 Status = mSmmMemoryAttribute->SetMemoryAttributes (
601 if ( ((
PcdGet8 (PcdHeapGuardPropertyMask) & PageOrPool) == 0)
609 if ((PageOrPool & GUARD_HEAP_TYPE_POOL) != 0) {
610 ConfigBit |=
PcdGet64 (PcdHeapGuardPoolType);
613 if ((PageOrPool & GUARD_HEAP_TYPE_PAGE) != 0) {
614 ConfigBit |=
PcdGet64 (PcdHeapGuardPageType);
621 }
else if (MemoryType == EfiMaxMemoryType) {
622 TestBit = (UINT64)-1;
627 return ((ConfigBit & TestBit) != 0);
682 GUARD_HEAP_TYPE_POOL|GUARD_HEAP_TYPE_PAGE
739 if (NumberOfPages == 0) {
757 if ((GuardBitmap & BIT1) == 0) {
761 if ((GuardBitmap & BIT0) == 0) {
790 if ((GuardBitmap & BIT0) == 0) {
794 if ((GuardBitmap & BIT1) == 0) {
839 if ((Memory ==
NULL) || (NumberOfPages ==
NULL) || (*NumberOfPages == 0)) {
844 PagesToFree = *NumberOfPages;
849 if (mSmmMemoryAttribute !=
NULL) {
851 mSmmMemoryAttribute->GetMemoryAttributes (
857 if ((Attributes & EFI_MEMORY_RO) != 0) {
858 mSmmMemoryAttribute->ClearMemoryAttributes (
881 if ((GuardBitmap & BIT1) == 0) {
885 if ((GuardBitmap & BIT0) == 0) {
916 if ((GuardBitmap & BIT0) == 0) {
920 if ((GuardBitmap & BIT1) == 0) {
927 }
else if (PagesToFree > 0) {
936 *NumberOfPages = PagesToFree;
957 if ((Memory == 0) || ((
PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) != 0)) {
983 if ((Memory == 0) || ((
PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) != 0)) {
993 return (
VOID *)(
UINTN)(Memory & ~EFI_PAGE_MASK);
1022 for (Node = FreePageList->BackLink; Node != FreePageList;
1023 Node = Node->BackLink)
1026 if ((Pages->NumberOfPages >= NumberOfPages) &&
1032 PagesToAlloc = NumberOfPages;
1042 HeadGuard = (
UINTN)Pages +
1053 if (Pages->NumberOfPages < PagesToAlloc) {
1061 if (HeadGuard == 0) {
1063 Address += EFI_PAGE_SIZE;
1089 IN BOOLEAN AddRegion
1095 if (((Memory & EFI_PAGE_MASK) != 0) || (Memory == 0) || (NumberOfPages == 0)) {
1096 return EFI_INVALID_PARAMETER;
1099 MemoryToFree = Memory;
1100 PagesToFree = NumberOfPages;
1104 if (PagesToFree == 0) {
1119 UINTN Entries[GUARDED_HEAP_MAP_TABLE_DEPTH];
1120 UINTN Shifts[GUARDED_HEAP_MAP_TABLE_DEPTH];
1121 UINTN Indices[GUARDED_HEAP_MAP_TABLE_DEPTH];
1122 UINT64 Tables[GUARDED_HEAP_MAP_TABLE_DEPTH];
1123 UINT64 Addresses[GUARDED_HEAP_MAP_TABLE_DEPTH];
1131 if ((mGuardedMemoryMap == 0) ||
1133 (mMapLevel > GUARDED_HEAP_MAP_TABLE_DEPTH))
1138 CopyMem (Entries, mLevelMask,
sizeof (Entries));
1139 CopyMem (Shifts, mLevelShift,
sizeof (Shifts));
1141 SetMem (Tables,
sizeof (Tables), 0);
1142 SetMem (Addresses,
sizeof (Addresses), 0);
1143 SetMem (Indices,
sizeof (Indices), 0);
1145 Level = GUARDED_HEAP_MAP_TABLE_DEPTH - mMapLevel;
1146 Tables[Level] = mGuardedMemoryMap;
1155 if (Indices[Level] > Entries[Level]) {
1159 TableEntry = ((UINT64 *)(
UINTN)(Tables[Level]))[Indices[Level]];
1160 Address = Addresses[Level];
1162 if (TableEntry == 0) {
1164 }
else if (Level < GUARDED_HEAP_MAP_TABLE_DEPTH - 1) {
1166 Tables[Level] = TableEntry;
1167 Addresses[Level] = Address;
1173 while (Index < GUARDED_HEAP_MAP_ENTRY_BITS) {
1174 if ((TableEntry & 1) == 1) {
1178 GuardPage = Address - EFI_PAGE_SIZE;
1184 GuardPage = Address;
1192 if (GuardPage != 0) {
1196 if (TableEntry == 0) {
1201 Address += EFI_PAGE_SIZE;
1207 if (Level < (GUARDED_HEAP_MAP_TABLE_DEPTH - (
INTN)mMapLevel)) {
1211 Indices[Level] += 1;
1212 Address = (Level == 0) ? 0 : Addresses[Level - 1];
1213 Addresses[Level] = Address |
LShiftU64 (Indices[Level], Shifts[Level]);
1227 if (mSmmMemoryAttribute ==
NULL) {
1229 &gEdkiiSmmMemoryAttributeProtocolGuid,
1231 (
VOID **)&mSmmMemoryAttribute
1233 if (!EFI_ERROR (Status)) {
1250 OUT CHAR8 *BinString
1255 if (BinString ==
NULL) {
1259 for (Index = 64; Index > 0; --Index) {
1260 BinString[Index - 1] =
'0' + (Value & 1);
1264 BinString[64] =
'\0';
1276 UINTN Entries[GUARDED_HEAP_MAP_TABLE_DEPTH];
1277 UINTN Shifts[GUARDED_HEAP_MAP_TABLE_DEPTH];
1278 UINTN Indices[GUARDED_HEAP_MAP_TABLE_DEPTH];
1279 UINT64 Tables[GUARDED_HEAP_MAP_TABLE_DEPTH];
1280 UINT64 Addresses[GUARDED_HEAP_MAP_TABLE_DEPTH];
1285 CHAR8 String[GUARDED_HEAP_MAP_ENTRY_BITS + 1];
1289 if ((mGuardedMemoryMap == 0) ||
1291 (mMapLevel > GUARDED_HEAP_MAP_TABLE_DEPTH))
1296 Ruler1 =
" 3 2 1 0";
1297 Ruler2 =
"FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210";
1300 HEAP_GUARD_DEBUG_LEVEL,
1301 "============================="
1302 " Guarded Memory Bitmap "
1303 "==============================\r\n"
1305 DEBUG ((HEAP_GUARD_DEBUG_LEVEL,
" %a\r\n", Ruler1));
1306 DEBUG ((HEAP_GUARD_DEBUG_LEVEL,
" %a\r\n", Ruler2));
1308 CopyMem (Entries, mLevelMask,
sizeof (Entries));
1309 CopyMem (Shifts, mLevelShift,
sizeof (Shifts));
1311 SetMem (Indices,
sizeof (Indices), 0);
1312 SetMem (Tables,
sizeof (Tables), 0);
1313 SetMem (Addresses,
sizeof (Addresses), 0);
1315 Level = GUARDED_HEAP_MAP_TABLE_DEPTH - mMapLevel;
1316 Tables[Level] = mGuardedMemoryMap;
1321 if (Indices[Level] > Entries[Level]) {
1327 HEAP_GUARD_DEBUG_LEVEL,
1328 "========================================="
1329 "=========================================\r\n"
1332 TableEntry = ((UINT64 *)(
UINTN)Tables[Level])[Indices[Level]];
1333 Address = Addresses[Level];
1335 if (TableEntry == 0) {
1336 if (Level == GUARDED_HEAP_MAP_TABLE_DEPTH - 1) {
1337 if (RepeatZero == 0) {
1339 DEBUG ((HEAP_GUARD_DEBUG_LEVEL,
"%016lx: %a\r\n", Address, String));
1340 }
else if (RepeatZero == 1) {
1341 DEBUG ((HEAP_GUARD_DEBUG_LEVEL,
"... : ...\r\n"));
1346 }
else if (Level < GUARDED_HEAP_MAP_TABLE_DEPTH - 1) {
1348 Tables[Level] = TableEntry;
1349 Addresses[Level] = Address;
1357 DEBUG ((HEAP_GUARD_DEBUG_LEVEL,
"%016lx: %a\r\n", Address, String));
1361 if (Level < (GUARDED_HEAP_MAP_TABLE_DEPTH - (
INTN)mMapLevel)) {
1365 Indices[Level] += 1;
1366 Address = (Level == 0) ? 0 : Addresses[Level - 1];
1367 Addresses[Level] = Address |
LShiftU64 (Indices[Level], Shifts[Level]);
1390 if (mSmmMemoryAttribute ==
NULL) {
1395 Address = BaseAddress - EFI_PAGE_SIZE;
1396 Status = mSmmMemoryAttribute->GetMemoryAttributes (
1397 mSmmMemoryAttribute,
1402 if (EFI_ERROR (Status) || ((Attribute & EFI_MEMORY_RP) == 0)) {
1405 "Head Guard is not set at: %016lx (%016lX)!!!\r\n",
1415 Status = mSmmMemoryAttribute->GetMemoryAttributes (
1416 mSmmMemoryAttribute,
1421 if (EFI_ERROR (Status) || ((Attribute & EFI_MEMORY_RP) == 0)) {
1424 "Tail Guard is not set at: %016lx (%016lX)!!!\r\n",
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
VOID *EFIAPI SetMem64(OUT VOID *Buffer, IN UINTN Length, IN UINT64 Value)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI SetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)
VOID SetGuardForMemory(IN EFI_PHYSICAL_ADDRESS Memory, IN UINTN NumberOfPages)
UINTN EFIAPI GetGuardMapBit(IN EFI_PHYSICAL_ADDRESS Address)
VOID AdjustMemoryF(IN OUT EFI_PHYSICAL_ADDRESS *Memory, IN OUT UINTN *NumberOfPages)
VOID * AdjustPoolHeadF(IN EFI_PHYSICAL_ADDRESS Memory, IN UINTN NoPages, IN UINTN Size)
VOID SetAllGuardPages(VOID)
VOID EFIAPI DumpGuardedMemoryBitmap(VOID)
STATIC UINT64 GetBits(IN EFI_PHYSICAL_ADDRESS Address, IN UINTN BitNumber, IN UINT64 *BitMap)
BOOLEAN EFIAPI IsGuardPage(IN EFI_PHYSICAL_ADDRESS Address)
STATIC VOID ClearBits(IN EFI_PHYSICAL_ADDRESS Address, IN UINTN BitNumber, IN UINT64 *BitMap)
VOID EFIAPI SetGuardPage(IN EFI_PHYSICAL_ADDRESS BaseAddress)
VOID EFIAPI UnsetGuardPage(IN EFI_PHYSICAL_ADDRESS BaseAddress)
VOID Uint64ToBinString(IN UINT64 Value, OUT CHAR8 *BinString)
UINT64 GetGuardedMemoryBits(IN EFI_PHYSICAL_ADDRESS Address, IN UINTN NumberOfPages)
BOOLEAN IsHeapGuardEnabled(UINT8 GuardType)
VOID UnsetGuardForMemory(IN EFI_PHYSICAL_ADDRESS Memory, IN UINTN NumberOfPages)
STATIC VOID SetBits(IN EFI_PHYSICAL_ADDRESS Address, IN UINTN BitNumber, IN UINT64 *BitMap)
BOOLEAN IsPoolTypeToGuard(IN EFI_MEMORY_TYPE MemoryType)
VOID EFIAPI ClearGuardedMemoryBits(IN EFI_PHYSICAL_ADDRESS Address, IN UINTN NumberOfPages)
BOOLEAN EFIAPI IsMemoryGuarded(IN EFI_PHYSICAL_ADDRESS Address)
VOID EFIAPI SetGuardedMemoryBits(IN EFI_PHYSICAL_ADDRESS Address, IN UINTN NumberOfPages)
BOOLEAN IsPageTypeToGuard(IN EFI_MEMORY_TYPE MemoryType, IN EFI_ALLOCATE_TYPE AllocateType)
UINTN FindGuardedMemoryMap(IN EFI_PHYSICAL_ADDRESS Address, IN BOOLEAN AllocMapUnit, OUT UINT64 **BitMap)
VOID * AdjustPoolHeadA(IN EFI_PHYSICAL_ADDRESS Memory, IN UINTN NoPages, IN UINTN Size)
BOOLEAN IsMemoryTypeToGuard(IN EFI_MEMORY_TYPE MemoryType, IN EFI_ALLOCATE_TYPE AllocateType, IN UINT8 PageOrPool)
VOID CoreFreeMemoryMapStack(VOID)
EFI_STATUS EFIAPI SmmLocateProtocol(IN EFI_GUID *Protocol, IN VOID *Registration OPTIONAL, OUT VOID **Interface)
UINTN InternalAllocPagesOnOneNode(IN OUT FREE_PAGE_LIST *Pages, IN UINTN NumberOfPages, IN UINTN MaxAddress)
EFI_STATUS SmmInternalFreePagesEx(IN EFI_PHYSICAL_ADDRESS Memory, IN UINTN NumberOfPages, IN BOOLEAN AddRegion)
VOID ConvertSmmMemoryMapEntry(IN EFI_MEMORY_TYPE Type, IN EFI_PHYSICAL_ADDRESS Memory, IN UINTN NumberOfPages, IN BOOLEAN AddRegion)
EFI_STATUS EFIAPI SmmInternalAllocatePages(IN EFI_ALLOCATE_TYPE Type, IN EFI_MEMORY_TYPE MemoryType, IN UINTN NumberOfPages, OUT EFI_PHYSICAL_ADDRESS *Memory, IN BOOLEAN NeedGuard)
#define ALIGN_VALUE(Value, Alignment)
#define GLOBAL_REMOVE_IF_UNREFERENCED
#define BASE_CR(Record, TYPE, Field)
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG(Expression)
#define DEBUG_CODE(Expression)
#define PcdGet64(TokenName)
#define PcdGet8(TokenName)
VOID * PageAlloc(IN UINTN Pages)
BOOLEAN VerifyMemoryGuard(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINTN NumberOfPages)
UINTN InternalAllocMaxAddressWithGuard(IN OUT LIST_ENTRY *FreePageList, IN UINTN NumberOfPages, IN UINTN MaxAddress, IN EFI_MEMORY_TYPE MemoryType)
EFI_STATUS SmmInternalFreePagesExWithGuard(IN EFI_PHYSICAL_ADDRESS Memory, IN UINTN NumberOfPages, IN BOOLEAN AddRegion)
VOID SmmEntryPointMemoryManagementHook(VOID)
UINT64 EFI_PHYSICAL_ADDRESS
#define EFI_PAGES_TO_SIZE(Pages)
#define EFI_SIZE_TO_PAGES(Size)