TianoCore EDK2 master
Loading...
Searching...
No Matches
SmmCpuMemoryManagement.c
Go to the documentation of this file.
1
8#include "PiSmmCpuCommon.h"
9
10BOOLEAN mIsShadowStack = FALSE;
11BOOLEAN m5LevelPagingNeeded = FALSE;
12PAGING_MODE mPagingMode = PagingModeMax;
13
14//
15// Global variable to keep track current available memory used as page table.
16//
17PAGE_TABLE_POOL *mPageTablePool = NULL;
18
19//
20// If memory used by SMM page table has been mareked as ReadOnly.
21//
22BOOLEAN mIsReadOnlyPageTable = FALSE;
23
30VOID
32 OUT BOOLEAN *WriteProtect
33 )
34{
35 IA32_CR0 Cr0;
36
37 Cr0.UintN = AsmReadCr0 ();
38 *WriteProtect = (Cr0.Bits.WP != 0);
39 if (*WriteProtect) {
40 Cr0.Bits.WP = 0;
41 AsmWriteCr0 (Cr0.UintN);
42 }
43}
44
51VOID
53 IN BOOLEAN WriteProtect
54 )
55{
56 IA32_CR0 Cr0;
57
58 if (WriteProtect) {
59 Cr0.UintN = AsmReadCr0 ();
60 Cr0.Bits.WP = 1;
61 AsmWriteCr0 (Cr0.UintN);
62 }
63}
64
82BOOLEAN
84 IN UINTN PoolPages
85 )
86{
87 VOID *Buffer;
88 BOOLEAN WriteProtect;
89 BOOLEAN CetEnabled;
90
91 //
92 // Always reserve at least PAGE_TABLE_POOL_UNIT_PAGES, including one page for
93 // header.
94 //
95 PoolPages += 1; // Add one page for header.
96 PoolPages = ((PoolPages - 1) / PAGE_TABLE_POOL_UNIT_PAGES + 1) *
97 PAGE_TABLE_POOL_UNIT_PAGES;
98 Buffer = AllocateAlignedPages (PoolPages, PAGE_TABLE_POOL_ALIGNMENT);
99 if (Buffer == NULL) {
100 DEBUG ((DEBUG_ERROR, "ERROR: Out of aligned pages\r\n"));
101 return FALSE;
102 }
103
104 //
105 // Link all pools into a list for easier track later.
106 //
107 if (mPageTablePool == NULL) {
108 mPageTablePool = Buffer;
109 mPageTablePool->NextPool = mPageTablePool;
110 } else {
111 ((PAGE_TABLE_POOL *)Buffer)->NextPool = mPageTablePool->NextPool;
112 mPageTablePool->NextPool = Buffer;
113 mPageTablePool = Buffer;
114 }
115
116 //
117 // Reserve one page for pool header.
118 //
119 mPageTablePool->FreePages = PoolPages - 1;
120 mPageTablePool->Offset = EFI_PAGES_TO_SIZE (1);
121
122 //
123 // If page table memory has been marked as RO, mark the new pool pages as read-only.
124 //
125 if (mIsReadOnlyPageTable) {
126 WRITE_UNPROTECT_RO_PAGES (WriteProtect, CetEnabled);
127
128 SmmSetMemoryAttributes ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, EFI_PAGES_TO_SIZE (PoolPages), EFI_MEMORY_RO);
129
130 WRITE_PROTECT_RO_PAGES (WriteProtect, CetEnabled);
131 }
132
133 return TRUE;
134}
135
151VOID *
153 IN UINTN Pages
154 )
155{
156 VOID *Buffer;
157
158 if (Pages == 0) {
159 return NULL;
160 }
161
162 //
163 // Renew the pool if necessary.
164 //
165 if ((mPageTablePool == NULL) ||
166 (Pages > mPageTablePool->FreePages))
167 {
168 if (!InitializePageTablePool (Pages)) {
169 return NULL;
170 }
171 }
172
173 Buffer = (UINT8 *)mPageTablePool + mPageTablePool->Offset;
174
175 mPageTablePool->Offset += EFI_PAGES_TO_SIZE (Pages);
176 mPageTablePool->FreePages -= Pages;
177
178 return Buffer;
179}
180
191VOID *
193 IN UINTN PageTableBase,
194 IN BOOLEAN Enable5LevelPaging,
195 IN PHYSICAL_ADDRESS Address,
196 OUT PAGE_ATTRIBUTE *PageAttribute
197 )
198{
199 UINTN Index1;
200 UINTN Index2;
201 UINTN Index3;
202 UINTN Index4;
203 UINTN Index5;
204 UINT64 *L1PageTable;
205 UINT64 *L2PageTable;
206 UINT64 *L3PageTable;
207 UINT64 *L4PageTable;
208 UINT64 *L5PageTable;
209
210 Index5 = ((UINTN)RShiftU64 (Address, 48)) & PAGING_PAE_INDEX_MASK;
211 Index4 = ((UINTN)RShiftU64 (Address, 39)) & PAGING_PAE_INDEX_MASK;
212 Index3 = ((UINTN)Address >> 30) & PAGING_PAE_INDEX_MASK;
213 Index2 = ((UINTN)Address >> 21) & PAGING_PAE_INDEX_MASK;
214 Index1 = ((UINTN)Address >> 12) & PAGING_PAE_INDEX_MASK;
215
216 if (sizeof (UINTN) == sizeof (UINT64)) {
217 if (Enable5LevelPaging) {
218 L5PageTable = (UINT64 *)PageTableBase;
219 if (L5PageTable[Index5] == 0) {
220 *PageAttribute = PageNone;
221 return NULL;
222 }
223
224 L4PageTable = (UINT64 *)(UINTN)(L5PageTable[Index5] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64);
225 } else {
226 L4PageTable = (UINT64 *)PageTableBase;
227 }
228
229 if (L4PageTable[Index4] == 0) {
230 *PageAttribute = PageNone;
231 return NULL;
232 }
233
234 L3PageTable = (UINT64 *)(UINTN)(L4PageTable[Index4] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64);
235 } else {
236 L3PageTable = (UINT64 *)PageTableBase;
237 }
238
239 if (L3PageTable[Index3] == 0) {
240 *PageAttribute = PageNone;
241 return NULL;
242 }
243
244 if ((L3PageTable[Index3] & IA32_PG_PS) != 0) {
245 // 1G
246 *PageAttribute = Page1G;
247 return &L3PageTable[Index3];
248 }
249
250 L2PageTable = (UINT64 *)(UINTN)(L3PageTable[Index3] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64);
251 if (L2PageTable[Index2] == 0) {
252 *PageAttribute = PageNone;
253 return NULL;
254 }
255
256 if ((L2PageTable[Index2] & IA32_PG_PS) != 0) {
257 // 2M
258 *PageAttribute = Page2M;
259 return &L2PageTable[Index2];
260 }
261
262 // 4k
263 L1PageTable = (UINT64 *)(UINTN)(L2PageTable[Index2] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64);
264 if ((L1PageTable[Index1] == 0) && (Address != 0)) {
265 *PageAttribute = PageNone;
266 return NULL;
267 }
268
269 *PageAttribute = Page4K;
270 return &L1PageTable[Index1];
271}
272
280UINT64
282 IN UINT64 *PageEntry
283 )
284{
285 UINT64 Attributes;
286
287 Attributes = 0;
288 if ((*PageEntry & IA32_PG_P) == 0) {
289 Attributes |= EFI_MEMORY_RP;
290 }
291
292 if ((*PageEntry & IA32_PG_RW) == 0) {
293 Attributes |= EFI_MEMORY_RO;
294 }
295
296 if ((*PageEntry & IA32_PG_NX) != 0) {
297 Attributes |= EFI_MEMORY_XP;
298 }
299
300 return Attributes;
301}
302
330RETURN_STATUS
332 IN UINTN PageTableBase,
333 IN PAGING_MODE PagingMode,
334 IN PHYSICAL_ADDRESS BaseAddress,
335 IN UINT64 Length,
336 IN UINT64 Attributes,
337 IN BOOLEAN IsSet,
338 OUT BOOLEAN *IsModified OPTIONAL
339 )
340{
341 RETURN_STATUS Status;
342 IA32_MAP_ATTRIBUTE PagingAttribute;
343 IA32_MAP_ATTRIBUTE PagingAttrMask;
344 UINTN PageTableBufferSize;
345 VOID *PageTableBuffer;
346 EFI_PHYSICAL_ADDRESS MaximumSupportMemAddress;
347 IA32_MAP_ENTRY *Map;
348 UINTN Count;
349 UINTN Index;
350 UINT64 OverlappedRangeBase;
351 UINT64 OverlappedRangeLimit;
352
353 ASSERT (Attributes != 0);
354 ASSERT ((Attributes & ~EFI_MEMORY_ATTRIBUTE_MASK) == 0);
355
356 ASSERT ((BaseAddress & (SIZE_4KB - 1)) == 0);
357 ASSERT ((Length & (SIZE_4KB - 1)) == 0);
358 ASSERT (PageTableBase != 0);
359
360 if (Length == 0) {
362 }
363
364 MaximumSupportMemAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)(LShiftU64 (1, mPhysicalAddressBits) - 1);
365 if (BaseAddress > MaximumSupportMemAddress) {
366 return RETURN_UNSUPPORTED;
367 }
368
369 if (Length > MaximumSupportMemAddress) {
370 return RETURN_UNSUPPORTED;
371 }
372
373 if ((Length != 0) && (BaseAddress > MaximumSupportMemAddress - (Length - 1))) {
374 return RETURN_UNSUPPORTED;
375 }
376
377 if (IsModified != NULL) {
378 *IsModified = FALSE;
379 }
380
381 PagingAttribute.Uint64 = 0;
382 PagingAttribute.Uint64 = mAddressEncMask | BaseAddress;
383 PagingAttrMask.Uint64 = 0;
384
385 if ((Attributes & EFI_MEMORY_RO) != 0) {
386 PagingAttrMask.Bits.ReadWrite = 1;
387 if (IsSet) {
388 PagingAttribute.Bits.ReadWrite = 0;
389 PagingAttrMask.Bits.Dirty = 1;
390 if (mIsShadowStack) {
391 // Environment setup
392 // ReadOnly page need set Dirty bit for shadow stack
393 PagingAttribute.Bits.Dirty = 1;
394 // Clear user bit for supervisor shadow stack
395 PagingAttribute.Bits.UserSupervisor = 0;
396 PagingAttrMask.Bits.UserSupervisor = 1;
397 } else {
398 // Runtime update
399 // Clear dirty bit for non shadow stack, to protect RO page.
400 PagingAttribute.Bits.Dirty = 0;
401 }
402 } else {
403 PagingAttribute.Bits.ReadWrite = 1;
404 }
405 }
406
407 if ((Attributes & EFI_MEMORY_XP) != 0) {
408 if (mXdSupported) {
409 PagingAttribute.Bits.Nx = IsSet ? 1 : 0;
410 PagingAttrMask.Bits.Nx = 1;
411 }
412 }
413
414 if ((Attributes & EFI_MEMORY_RP) != 0) {
415 if (IsSet) {
416 PagingAttribute.Bits.Present = 0;
417 //
418 // When map a range to non-present, all attributes except Present should not be provided.
419 //
420 PagingAttrMask.Uint64 = 0;
421 PagingAttrMask.Bits.Present = 1;
422 } else {
423 //
424 // When map range to present range, provide all attributes.
425 //
426 PagingAttribute.Bits.Present = 1;
427 PagingAttrMask.Uint64 = MAX_UINT64;
428
429 //
430 // By default memory is Ring 3 accessble.
431 //
432 PagingAttribute.Bits.UserSupervisor = 1;
433
435 if (((Attributes & EFI_MEMORY_RO) == 0) || (((Attributes & EFI_MEMORY_XP) == 0) && (mXdSupported))) {
436 //
437 // When mapping a range to present and EFI_MEMORY_RO or EFI_MEMORY_XP is not specificed,
438 // check if [BaseAddress, BaseAddress + Length] contains present range.
439 // Existing Present range in [BaseAddress, BaseAddress + Length] is set to NX disable or ReadOnly.
440 //
441 Count = 0;
442 Map = NULL;
443 Status = PageTableParse (PageTableBase, mPagingMode, NULL, &Count);
444
445 while (Status == RETURN_BUFFER_TOO_SMALL) {
446 if (Map != NULL) {
447 FreePool (Map);
448 }
449
450 Map = AllocatePool (Count * sizeof (IA32_MAP_ENTRY));
451 ASSERT (Map != NULL);
452 Status = PageTableParse (PageTableBase, mPagingMode, Map, &Count);
453 }
454
455 ASSERT_RETURN_ERROR (Status);
456 for (Index = 0; Index < Count; Index++) {
457 if (Map[Index].LinearAddress >= BaseAddress + Length) {
458 break;
459 }
460
461 if ((BaseAddress < Map[Index].LinearAddress + Map[Index].Length) && (BaseAddress + Length > Map[Index].LinearAddress)) {
462 OverlappedRangeBase = MAX (BaseAddress, Map[Index].LinearAddress);
463 OverlappedRangeLimit = MIN (BaseAddress + Length, Map[Index].LinearAddress + Map[Index].Length);
464
465 if (((Attributes & EFI_MEMORY_RO) == 0) && (Map[Index].Attribute.Bits.ReadWrite == 1)) {
466 DEBUG ((DEBUG_ERROR, "SMM ConvertMemoryPageAttributes: [0x%lx, 0x%lx] is set from ReadWrite to ReadOnly\n", OverlappedRangeBase, OverlappedRangeLimit));
467 }
468
469 if (((Attributes & EFI_MEMORY_XP) == 0) && (mXdSupported) && (Map[Index].Attribute.Bits.Nx == 1)) {
470 DEBUG ((DEBUG_ERROR, "SMM ConvertMemoryPageAttributes: [0x%lx, 0x%lx] is set from NX enabled to NX disabled\n", OverlappedRangeBase, OverlappedRangeLimit));
471 }
472 }
473 }
474
475 FreePool (Map);
476 }
477
479 }
480 }
481
482 if (PagingAttrMask.Uint64 == 0) {
483 return RETURN_SUCCESS;
484 }
485
486 PageTableBufferSize = 0;
487 Status = PageTableMap (&PageTableBase, PagingMode, NULL, &PageTableBufferSize, BaseAddress, Length, &PagingAttribute, &PagingAttrMask, IsModified);
488
489 if (Status == RETURN_BUFFER_TOO_SMALL) {
490 PageTableBuffer = AllocatePageTableMemory (EFI_SIZE_TO_PAGES (PageTableBufferSize));
491 ASSERT (PageTableBuffer != NULL);
492 Status = PageTableMap (&PageTableBase, PagingMode, PageTableBuffer, &PageTableBufferSize, BaseAddress, Length, &PagingAttribute, &PagingAttrMask, IsModified);
493 }
494
495 if (Status == RETURN_INVALID_PARAMETER) {
496 //
497 // The only reason that PageTableMap returns RETURN_INVALID_PARAMETER here is to modify other attributes
498 // of a non-present range but remains the non-present range still as non-present.
499 //
500 DEBUG ((DEBUG_ERROR, "SMM ConvertMemoryPageAttributes: Only change EFI_MEMORY_XP/EFI_MEMORY_RO for non-present range in [0x%lx, 0x%lx] is not permitted\n", BaseAddress, BaseAddress + Length));
501 }
502
503 ASSERT_RETURN_ERROR (Status);
504 ASSERT (PageTableBufferSize == 0);
505
506 return RETURN_SUCCESS;
507}
508
514VOID
515EFIAPI
517 IN OUT VOID *Buffer
518 )
519{
520 CpuFlushTlb ();
521}
522
526VOID
528 VOID
529 )
530{
534 0,
535 NULL,
536 NULL,
537 NULL
538 );
539}
540
567 IN UINTN PageTableBase,
568 IN PAGING_MODE PagingMode,
569 IN EFI_PHYSICAL_ADDRESS BaseAddress,
570 IN UINT64 Length,
571 IN UINT64 Attributes
572 )
573{
574 EFI_STATUS Status;
575 BOOLEAN IsModified;
576
577 Status = ConvertMemoryPageAttributes (PageTableBase, PagingMode, BaseAddress, Length, Attributes, TRUE, &IsModified);
578 if (!EFI_ERROR (Status)) {
579 if (IsModified) {
580 //
581 // Flush TLB as last step
582 //
584 }
585 }
586
587 return Status;
588}
589
616 IN UINTN PageTableBase,
617 IN PAGING_MODE PagingMode,
618 IN EFI_PHYSICAL_ADDRESS BaseAddress,
619 IN UINT64 Length,
620 IN UINT64 Attributes
621 )
622{
623 EFI_STATUS Status;
624 BOOLEAN IsModified;
625
626 Status = ConvertMemoryPageAttributes (PageTableBase, PagingMode, BaseAddress, Length, Attributes, FALSE, &IsModified);
627 if (!EFI_ERROR (Status)) {
628 if (IsModified) {
629 //
630 // Flush TLB as last step
631 //
633 }
634 }
635
636 return Status;
637}
638
663 IN EFI_PHYSICAL_ADDRESS BaseAddress,
664 IN UINT64 Length,
665 IN UINT64 Attributes
666 )
667{
668 UINTN PageTableBase;
669
670 PageTableBase = AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64;
671 return SmmSetMemoryAttributesEx (PageTableBase, mPagingMode, BaseAddress, Length, Attributes);
672}
673
698 IN EFI_PHYSICAL_ADDRESS BaseAddress,
699 IN UINT64 Length,
700 IN UINT64 Attributes
701 )
702{
703 UINTN PageTableBase;
704
705 PageTableBase = AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64;
706 return SmmClearMemoryAttributesEx (PageTableBase, mPagingMode, BaseAddress, Length, Attributes);
707}
708
720 IN UINTN Cr3,
721 IN EFI_PHYSICAL_ADDRESS BaseAddress,
722 IN UINT64 Length
723 )
724{
725 EFI_STATUS Status;
726
727 mIsShadowStack = TRUE;
728 Status = SmmSetMemoryAttributesEx (Cr3, mPagingMode, BaseAddress, Length, EFI_MEMORY_RO);
729 mIsShadowStack = FALSE;
730
731 return Status;
732}
733
746EFIAPI
748 IN EFI_GUID *TableGuid,
749 OUT VOID **Table
750 )
751{
752 UINTN Index;
753
754 ASSERT (TableGuid != NULL);
755 ASSERT (Table != NULL);
756
757 *Table = NULL;
758 for (Index = 0; Index < gMmst->NumberOfTableEntries; Index++) {
759 if (CompareGuid (TableGuid, &(gMmst->MmConfigurationTable[Index].VendorGuid))) {
760 *Table = gMmst->MmConfigurationTable[Index].VendorTable;
761 return EFI_SUCCESS;
762 }
763 }
764
765 return EFI_NOT_FOUND;
766}
767
771VOID
773 VOID
774 )
775{
776 UINTN Index;
777 UINTN TileCodeSize;
778 UINTN TileDataSize;
779 UINTN TileSize;
780 UINTN PageTableBase;
781
782 TileCodeSize = GetSmiHandlerSize ();
783 TileCodeSize = ALIGN_VALUE (TileCodeSize, SIZE_4KB);
784 TileDataSize = (SMRAM_SAVE_STATE_MAP_OFFSET - SMM_PSD_OFFSET) + sizeof (SMRAM_SAVE_STATE_MAP);
785 TileDataSize = ALIGN_VALUE (TileDataSize, SIZE_4KB);
786 TileSize = TileDataSize + TileCodeSize - 1;
787 TileSize = 2 * GetPowerOfTwo32 ((UINT32)TileSize);
788 PageTableBase = AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64;
789
790 DEBUG ((DEBUG_INFO, "PatchSmmSaveStateMap:\n"));
791 for (Index = 0; Index < mMaxNumberOfCpus - 1; Index++) {
792 //
793 // Code
794 //
796 PageTableBase,
797 mPagingMode,
798 mCpuHotPlugData.SmBase[Index] + SMM_HANDLER_OFFSET,
799 TileCodeSize,
800 EFI_MEMORY_RO,
801 TRUE,
802 NULL
803 );
805 PageTableBase,
806 mPagingMode,
807 mCpuHotPlugData.SmBase[Index] + SMM_HANDLER_OFFSET,
808 TileCodeSize,
809 EFI_MEMORY_XP,
810 FALSE,
811 NULL
812 );
813
814 //
815 // Data
816 //
818 PageTableBase,
819 mPagingMode,
820 mCpuHotPlugData.SmBase[Index] + SMM_HANDLER_OFFSET + TileCodeSize,
821 TileSize - TileCodeSize,
822 EFI_MEMORY_RO,
823 FALSE,
824 NULL
825 );
827 PageTableBase,
828 mPagingMode,
829 mCpuHotPlugData.SmBase[Index] + SMM_HANDLER_OFFSET + TileCodeSize,
830 TileSize - TileCodeSize,
831 EFI_MEMORY_XP,
832 TRUE,
833 NULL
834 );
835 }
836
837 //
838 // Code
839 //
841 PageTableBase,
842 mPagingMode,
843 mCpuHotPlugData.SmBase[mMaxNumberOfCpus - 1] + SMM_HANDLER_OFFSET,
844 TileCodeSize,
845 EFI_MEMORY_RO,
846 TRUE,
847 NULL
848 );
850 PageTableBase,
851 mPagingMode,
852 mCpuHotPlugData.SmBase[mMaxNumberOfCpus - 1] + SMM_HANDLER_OFFSET,
853 TileCodeSize,
854 EFI_MEMORY_XP,
855 FALSE,
856 NULL
857 );
858
859 //
860 // Data
861 //
863 PageTableBase,
864 mPagingMode,
865 mCpuHotPlugData.SmBase[mMaxNumberOfCpus - 1] + SMM_HANDLER_OFFSET + TileCodeSize,
866 SIZE_32KB - TileCodeSize,
867 EFI_MEMORY_RO,
868 FALSE,
869 NULL
870 );
872 PageTableBase,
873 mPagingMode,
874 mCpuHotPlugData.SmBase[mMaxNumberOfCpus - 1] + SMM_HANDLER_OFFSET + TileCodeSize,
875 SIZE_32KB - TileCodeSize,
876 EFI_MEMORY_XP,
877 TRUE,
878 NULL
879 );
880
882}
883
887VOID
889 VOID
890 )
891{
892 EFI_PHYSICAL_ADDRESS BaseAddress;
893 UINTN Size;
894
895 //
896 // GDT
897 //
898 DEBUG ((DEBUG_INFO, "PatchGdtIdtMap - GDT:\n"));
899
900 BaseAddress = mGdtBuffer;
901 Size = ALIGN_VALUE (mGdtBufferSize, SIZE_4KB);
902 //
903 // The range should have been set to RO
904 // if it is allocated with EfiRuntimeServicesCode.
905 //
907 BaseAddress,
908 Size,
909 EFI_MEMORY_XP
910 );
911
912 //
913 // IDT
914 //
915 DEBUG ((DEBUG_INFO, "PatchGdtIdtMap - IDT:\n"));
916
917 BaseAddress = gcSmiIdtr.Base;
918 Size = ALIGN_VALUE (gcSmiIdtr.Limit + 1, SIZE_4KB);
919 //
920 // The range should have been set to RO
921 // if it is allocated with EfiRuntimeServicesCode.
922 //
924 BaseAddress,
925 Size,
926 EFI_MEMORY_XP
927 );
928}
929
939VOID
941 UINT64 Base,
942 UINT64 Limit,
943 UINT64 Attribute,
944 IA32_MAP_ENTRY *Map,
945 UINTN Count
946 )
947{
948 UINTN Index;
949 UINT64 NonPresentRangeStart;
950
951 NonPresentRangeStart = 0;
952 for (Index = 0; Index < Count; Index++) {
953 if ((Map[Index].LinearAddress > NonPresentRangeStart) &&
954 (Base < Map[Index].LinearAddress) && (Limit > NonPresentRangeStart))
955 {
956 //
957 // We should NOT set attributes for non-present ragne.
958 //
959 //
960 // There is a non-present ( [NonPresentStart, Map[Index].LinearAddress] ) range before current Map[Index]
961 // and it is overlapped with [Base, Limit].
962 //
963 if (Base < NonPresentRangeStart) {
965 Base,
966 NonPresentRangeStart - Base,
967 Attribute
968 );
969 }
970
971 Base = Map[Index].LinearAddress;
972 }
973
974 NonPresentRangeStart = Map[Index].LinearAddress + Map[Index].Length;
975 if (NonPresentRangeStart >= Limit) {
976 break;
977 }
978 }
979
980 Limit = MIN (NonPresentRangeStart, Limit);
981
982 if (Base < Limit) {
983 //
984 // There is no non-present range in current [Base, Limit] anymore.
985 //
987 Base,
988 Limit - Base,
989 Attribute
990 );
991 }
992}
993
1000VOID
1002 EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable
1003 )
1004{
1005 EFI_MEMORY_DESCRIPTOR *MemoryMap;
1006 EFI_MEMORY_DESCRIPTOR *MemoryMapStart;
1007 UINTN MemoryMapEntryCount;
1008 UINTN DescriptorSize;
1009 UINTN Index;
1010 UINTN PageTable;
1011 EFI_STATUS Status;
1012 IA32_MAP_ENTRY *Map;
1013 UINTN Count;
1014 UINT64 MemoryAttribute;
1015 BOOLEAN WriteProtect;
1016 BOOLEAN CetEnabled;
1017
1018 ASSERT (MemoryAttributesTable != NULL);
1019
1021
1022 DEBUG ((DEBUG_INFO, "MemoryAttributesTable:\n"));
1023 DEBUG ((DEBUG_INFO, " Version - 0x%08x\n", MemoryAttributesTable->Version));
1024 DEBUG ((DEBUG_INFO, " NumberOfEntries - 0x%08x\n", MemoryAttributesTable->NumberOfEntries));
1025 DEBUG ((DEBUG_INFO, " DescriptorSize - 0x%08x\n", MemoryAttributesTable->DescriptorSize));
1026
1027 MemoryMapEntryCount = MemoryAttributesTable->NumberOfEntries;
1028 DescriptorSize = MemoryAttributesTable->DescriptorSize;
1029 MemoryMapStart = (EFI_MEMORY_DESCRIPTOR *)(MemoryAttributesTable + 1);
1030 MemoryMap = MemoryMapStart;
1031 for (Index = 0; Index < MemoryMapEntryCount; Index++) {
1032 DEBUG ((DEBUG_INFO, "Entry (0x%x)\n", MemoryMap));
1033 DEBUG ((DEBUG_INFO, " Type - 0x%x\n", MemoryMap->Type));
1034 DEBUG ((DEBUG_INFO, " PhysicalStart - 0x%016lx\n", MemoryMap->PhysicalStart));
1035 DEBUG ((DEBUG_INFO, " VirtualStart - 0x%016lx\n", MemoryMap->VirtualStart));
1036 DEBUG ((DEBUG_INFO, " NumberOfPages - 0x%016lx\n", MemoryMap->NumberOfPages));
1037 DEBUG ((DEBUG_INFO, " Attribute - 0x%016lx\n", MemoryMap->Attribute));
1038 MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, DescriptorSize);
1039 }
1040
1041 Count = 0;
1042 Map = NULL;
1043 PageTable = AsmReadCr3 ();
1044 Status = PageTableParse (PageTable, mPagingMode, NULL, &Count);
1045 while (Status == RETURN_BUFFER_TOO_SMALL) {
1046 if (Map != NULL) {
1047 FreePool (Map);
1048 }
1049
1050 Map = AllocatePool (Count * sizeof (IA32_MAP_ENTRY));
1051 ASSERT (Map != NULL);
1052 Status = PageTableParse (PageTable, mPagingMode, Map, &Count);
1053 }
1054
1055 ASSERT_RETURN_ERROR (Status);
1056
1057 WRITE_UNPROTECT_RO_PAGES (WriteProtect, CetEnabled);
1058
1059 MemoryMap = MemoryMapStart;
1060 for (Index = 0; Index < MemoryMapEntryCount; Index++) {
1061 DEBUG ((DEBUG_VERBOSE, "SetAttribute: Memory Entry - 0x%lx, 0x%x\n", MemoryMap->PhysicalStart, MemoryMap->NumberOfPages));
1062 MemoryAttribute = MemoryMap->Attribute & EFI_MEMORY_ACCESS_MASK;
1063 if (MemoryAttribute == 0) {
1064 if (MemoryMap->Type == EfiRuntimeServicesCode) {
1065 MemoryAttribute = EFI_MEMORY_RO;
1066 } else {
1067 ASSERT ((MemoryMap->Type == EfiRuntimeServicesData) || (MemoryMap->Type == EfiConventionalMemory));
1068 //
1069 // Set other type memory as NX.
1070 //
1071 MemoryAttribute = EFI_MEMORY_XP;
1072 }
1073 }
1074
1075 //
1076 // There may exist non-present range overlaps with the MemoryMap range.
1077 // Do not change other attributes of non-present range while still remaining it as non-present
1078 //
1080 MemoryMap->PhysicalStart,
1081 MemoryMap->PhysicalStart + EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages),
1082 MemoryAttribute,
1083 Map,
1084 Count
1085 );
1086
1087 MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, DescriptorSize);
1088 }
1089
1090 WRITE_PROTECT_RO_PAGES (WriteProtect, CetEnabled);
1091
1092 FreePool (Map);
1093
1095 PatchGdtIdtMap ();
1096
1098}
1099
1124EFIAPI
1127 IN EFI_PHYSICAL_ADDRESS BaseAddress,
1128 IN UINT64 Length,
1129 IN UINT64 Attributes
1130 )
1131{
1132 return SmmSetMemoryAttributes (BaseAddress, Length, Attributes);
1133}
1134
1159EFIAPI
1162 IN EFI_PHYSICAL_ADDRESS BaseAddress,
1163 IN UINT64 Length,
1164 IN UINT64 Attributes
1165 )
1166{
1167 return SmmClearMemoryAttributes (BaseAddress, Length, Attributes);
1168}
1169
1181VOID
1183 IN OUT UINTN *PageTable,
1184 IN PAGING_MODE PagingMode,
1185 IN UINT64 LinearAddress,
1186 IN UINT64 Length,
1187 IN IA32_MAP_ATTRIBUTE MapAttribute,
1188 IN IA32_MAP_ATTRIBUTE MapMask
1189 )
1190{
1191 RETURN_STATUS Status;
1192 UINTN PageTableBufferSize;
1193 VOID *PageTableBuffer;
1194
1195 PageTableBufferSize = 0;
1196
1197 Status = PageTableMap (
1198 PageTable,
1199 PagingMode,
1200 NULL,
1201 &PageTableBufferSize,
1202 LinearAddress,
1203 Length,
1204 &MapAttribute,
1205 &MapMask,
1206 NULL
1207 );
1208 if (Status == RETURN_BUFFER_TOO_SMALL) {
1209 PageTableBuffer = AllocatePageTableMemory (EFI_SIZE_TO_PAGES (PageTableBufferSize));
1210 ASSERT (PageTableBuffer != NULL);
1211 Status = PageTableMap (
1212 PageTable,
1213 PagingMode,
1214 PageTableBuffer,
1215 &PageTableBufferSize,
1216 LinearAddress,
1217 Length,
1218 &MapAttribute,
1219 &MapMask,
1220 NULL
1221 );
1222 }
1223
1224 ASSERT (Status == RETURN_SUCCESS);
1225 ASSERT (PageTableBufferSize == 0);
1226}
1227
1237UINTN
1239 IN PAGING_MODE PagingMode,
1240 IN UINT8 PhysicalAddressBits
1241 )
1242{
1243 UINTN PageTable;
1244 UINTN Index;
1245 MM_CPU_MEMORY_REGION *MemoryRegion;
1246 UINTN MemoryRegionCount;
1247 IA32_MAP_ATTRIBUTE MapAttribute;
1248 IA32_MAP_ATTRIBUTE MapMask;
1249 RETURN_STATUS Status;
1250 UINTN GuardPage;
1251
1252 PageTable = 0;
1253 MemoryRegion = NULL;
1254 MemoryRegionCount = 0;
1255 MapMask.Uint64 = MAX_UINT64;
1256
1257 //
1258 // 1. Create NonMmram MemoryRegion
1259 //
1260 CreateNonMmramMemMap (PhysicalAddressBits, &MemoryRegion, &MemoryRegionCount);
1261 ASSERT (MemoryRegion != NULL && MemoryRegionCount != 0);
1262
1263 //
1264 // 2. Gen NonMmram MemoryRegion PageTable
1265 //
1266 for (Index = 0; Index < MemoryRegionCount; Index++) {
1267 ASSERT (MemoryRegion[Index].Base % SIZE_4KB == 0);
1268 ASSERT (MemoryRegion[Index].Length % EFI_PAGE_SIZE == 0);
1269
1270 //
1271 // Set the MapAttribute
1272 //
1273 MapAttribute.Uint64 = mAddressEncMask|MemoryRegion[Index].Base;
1274 MapAttribute.Bits.Present = 1;
1275 MapAttribute.Bits.ReadWrite = 1;
1276 MapAttribute.Bits.UserSupervisor = 1;
1277 MapAttribute.Bits.Accessed = 1;
1278 MapAttribute.Bits.Dirty = 1;
1279
1280 //
1281 // Update the MapAttribute according MemoryRegion[Index].Attribute
1282 //
1283 if ((MemoryRegion[Index].Attribute & EFI_MEMORY_RO) != 0) {
1284 MapAttribute.Bits.ReadWrite = 0;
1285 }
1286
1287 if ((MemoryRegion[Index].Attribute & EFI_MEMORY_XP) != 0) {
1288 if (mXdSupported) {
1289 MapAttribute.Bits.Nx = 1;
1290 }
1291 }
1292
1293 GenPageTable (&PageTable, PagingMode, MemoryRegion[Index].Base, (UINTN)MemoryRegion[Index].Length, MapAttribute, MapMask);
1294 }
1295
1296 //
1297 // Free the MemoryRegion after usage
1298 //
1299 if (MemoryRegion != NULL) {
1300 FreePool (MemoryRegion);
1301 }
1302
1303 //
1304 // 3. Gen MMRAM Range PageTable
1305 //
1306 for (Index = 0; Index < mSmmCpuSmramRangeCount; Index++) {
1307 ASSERT (mSmmCpuSmramRanges[Index].CpuStart % SIZE_4KB == 0);
1308 ASSERT (mSmmCpuSmramRanges[Index].PhysicalSize % EFI_PAGE_SIZE == 0);
1309
1310 //
1311 // Set the MapAttribute
1312 //
1313 MapAttribute.Uint64 = mAddressEncMask|mSmmCpuSmramRanges[Index].CpuStart;
1314 MapAttribute.Bits.Present = 1;
1315 MapAttribute.Bits.ReadWrite = 1;
1316 MapAttribute.Bits.UserSupervisor = 1;
1317 MapAttribute.Bits.Accessed = 1;
1318 MapAttribute.Bits.Dirty = 1;
1319
1320 GenPageTable (&PageTable, PagingMode, mSmmCpuSmramRanges[Index].CpuStart, mSmmCpuSmramRanges[Index].PhysicalSize, MapAttribute, MapMask);
1321 }
1322
1323 if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
1324 //
1325 // Mark the 4KB guard page between known good stack and smm stack as non-present
1326 //
1327 for (Index = 0; Index < gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; Index++) {
1328 GuardPage = mSmmStackArrayBase + EFI_PAGE_SIZE + Index * (mSmmStackSize + mSmmShadowStackSize);
1329 Status = ConvertMemoryPageAttributes (PageTable, PagingMode, GuardPage, SIZE_4KB, EFI_MEMORY_RP, TRUE, NULL);
1330 ASSERT (Status == RETURN_SUCCESS);
1331 }
1332 }
1333
1334 if ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT1) != 0) {
1335 //
1336 // Mark [0, 4k] as non-present
1337 //
1338 Status = ConvertMemoryPageAttributes (PageTable, PagingMode, 0, SIZE_4KB, EFI_MEMORY_RP, TRUE, NULL);
1339 ASSERT (Status == RETURN_SUCCESS);
1340 }
1341
1342 return (UINTN)PageTable;
1343}
1344
1367EFIAPI
1370 IN EFI_PHYSICAL_ADDRESS BaseAddress,
1371 IN UINT64 Length,
1372 OUT UINT64 *Attributes
1373 )
1374{
1375 EFI_PHYSICAL_ADDRESS Address;
1376 UINT64 *PageEntry;
1377 UINT64 MemAttr;
1378 PAGE_ATTRIBUTE PageAttr;
1379 INT64 Size;
1380 UINTN PageTableBase;
1381 BOOLEAN EnablePML5Paging;
1382 IA32_CR4 Cr4;
1383
1384 if ((Length < SIZE_4KB) || (Attributes == NULL)) {
1385 return EFI_INVALID_PARAMETER;
1386 }
1387
1388 Size = (INT64)Length;
1389 MemAttr = (UINT64)-1;
1390
1391 PageTableBase = AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64;
1392 Cr4.UintN = AsmReadCr4 ();
1393 EnablePML5Paging = (BOOLEAN)(Cr4.Bits.LA57 == 1);
1394
1395 do {
1396 PageEntry = GetPageTableEntry (PageTableBase, EnablePML5Paging, BaseAddress, &PageAttr);
1397 if ((PageEntry == NULL) || (PageAttr == PageNone)) {
1398 return EFI_UNSUPPORTED;
1399 }
1400
1401 //
1402 // If the memory range is cross page table boundary, make sure they
1403 // share the same attribute. Return EFI_NO_MAPPING if not.
1404 //
1405 *Attributes = GetAttributesFromPageEntry (PageEntry);
1406 if ((MemAttr != (UINT64)-1) && (*Attributes != MemAttr)) {
1407 return EFI_NO_MAPPING;
1408 }
1409
1410 switch (PageAttr) {
1411 case Page4K:
1412 Address = *PageEntry & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64;
1413 Size -= (SIZE_4KB - (BaseAddress - Address));
1414 BaseAddress += (SIZE_4KB - (BaseAddress - Address));
1415 break;
1416
1417 case Page2M:
1418 Address = *PageEntry & ~mAddressEncMask & PAGING_2M_ADDRESS_MASK_64;
1419 Size -= SIZE_2MB - (BaseAddress - Address);
1420 BaseAddress += SIZE_2MB - (BaseAddress - Address);
1421 break;
1422
1423 case Page1G:
1424 Address = *PageEntry & ~mAddressEncMask & PAGING_1G_ADDRESS_MASK_64;
1425 Size -= SIZE_1GB - (BaseAddress - Address);
1426 BaseAddress += SIZE_1GB - (BaseAddress - Address);
1427 break;
1428
1429 default:
1430 return EFI_UNSUPPORTED;
1431 }
1432
1433 MemAttr = *Attributes;
1434 } while (Size > 0);
1435
1436 return EFI_SUCCESS;
1437}
1438
1442VOID
1444 VOID
1445 )
1446{
1447 PAGE_TABLE_POOL *HeadPool;
1448 PAGE_TABLE_POOL *Pool;
1449 UINT64 PoolSize;
1450 EFI_PHYSICAL_ADDRESS Address;
1451 UINTN PageTableBase;
1452
1453 if (mPageTablePool == NULL) {
1454 return;
1455 }
1456
1457 PageTableBase = AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64;
1458
1459 //
1460 // ConvertMemoryPageAttributes might update mPageTablePool. It's safer to
1461 // remember original one in advance.
1462 //
1463 HeadPool = mPageTablePool;
1464 Pool = HeadPool;
1465 do {
1466 Address = (EFI_PHYSICAL_ADDRESS)(UINTN)Pool;
1467 PoolSize = Pool->Offset + EFI_PAGES_TO_SIZE (Pool->FreePages);
1468 //
1469 // Set entire pool including header, used-memory and left free-memory as ReadOnly in SMM page table.
1470 //
1471 ConvertMemoryPageAttributes (PageTableBase, mPagingMode, Address, PoolSize, EFI_MEMORY_RO, TRUE, NULL);
1472 Pool = Pool->NextPool;
1473 } while (Pool != HeadPool);
1474}
1475
1482BOOLEAN
1484 VOID
1485 )
1486{
1487 //
1488 // Don't mark page table memory as read-only if
1489 // - SMM heap guard feature enabled; or
1490 // BIT2: SMM page guard enabled
1491 // BIT3: SMM pool guard enabled
1492 // - SMM profile feature enabled
1493 //
1494 if (((PcdGet8 (PcdHeapGuardPropertyMask) & (BIT3 | BIT2)) != 0) ||
1495 mSmmProfileEnabled)
1496 {
1497 return FALSE;
1498 }
1499
1500 return TRUE;
1501}
1502
1506VOID
1508 VOID
1509 )
1510{
1511 BOOLEAN WriteProtect;
1512 BOOLEAN CetEnabled;
1513
1514 if (!IfReadOnlyPageTableNeeded ()) {
1515 return;
1516 }
1517
1519 DEBUG ((DEBUG_INFO, "SetPageTableAttributes\n"));
1520
1521 //
1522 // Disable write protection, because we need mark page table to be write protected.
1523 // We need *write* page table memory, to mark itself to be *read only*.
1524 //
1525 WRITE_UNPROTECT_RO_PAGES (WriteProtect, CetEnabled);
1526
1527 // Set memory used by page table as Read Only.
1528 DEBUG ((DEBUG_INFO, "Start...\n"));
1530
1531 //
1532 // Enable write protection, after page table attribute updated.
1533 //
1534 WRITE_PROTECT_RO_PAGES (TRUE, CetEnabled);
1535
1536 mIsReadOnlyPageTable = TRUE;
1537
1538 //
1539 // Flush TLB after mark all page table pool as read only.
1540 //
1541 FlushTlbForAll ();
1543}
UINT64 UINTN
UINT32 EFIAPI GetPowerOfTwo32(IN UINT32 Operand)
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: RShiftU64.c:28
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: LShiftU64.c:28
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
VOID EFIAPI CpuFlushTlb(VOID)
RETURN_STATUS EFIAPI PageTableMap(IN OUT UINTN *PageTable OPTIONAL, IN PAGING_MODE PagingMode, IN VOID *Buffer, IN OUT UINTN *BufferSize, IN UINT64 LinearAddress, IN UINT64 Length, IN IA32_MAP_ATTRIBUTE *Attribute, IN IA32_MAP_ATTRIBUTE *Mask, OUT BOOLEAN *IsModified OPTIONAL)
RETURN_STATUS EFIAPI PageTableParse(IN UINTN PageTable, IN PAGING_MODE PagingMode, IN IA32_MAP_ENTRY *Map, IN OUT UINTN *MapCount)
VOID EFIAPI FreePool(IN VOID *Buffer)
UINTN EFIAPI AsmReadCr3(VOID)
UINTN EFIAPI AsmReadCr0(VOID)
UINTN EFIAPI AsmWriteCr0(UINTN Cr0)
UINTN EFIAPI AsmReadCr4(VOID)
#define NULL
Definition: Base.h:319
#define RETURN_BUFFER_TOO_SMALL
Definition: Base.h:1093
#define MIN(a, b)
Definition: Base.h:1007
#define RETURN_UNSUPPORTED
Definition: Base.h:1081
#define ALIGN_VALUE(Value, Alignment)
Definition: Base.h:948
#define RETURN_SUCCESS
Definition: Base.h:1066
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define RETURN_INVALID_PARAMETER
Definition: Base.h:1076
#define MAX(a, b)
Definition: Base.h:992
#define ASSERT_RETURN_ERROR(StatusParameter)
Definition: DebugLib.h:493
#define DEBUG_CODE_BEGIN()
Definition: DebugLib.h:564
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define DEBUG_CODE_END()
Definition: DebugLib.h:578
#define SMM_HANDLER_OFFSET
#define SMRAM_SAVE_STATE_MAP_OFFSET
VOID CreateNonMmramMemMap(IN UINT8 PhysicalAddressBits, OUT MM_CPU_MEMORY_REGION **MemoryRegion, OUT UINTN *MemoryRegionCount)
#define PcdGet8(TokenName)
Definition: PcdLib.h:336
#define FeaturePcdGet(TokenName)
Definition: PcdLib.h:50
#define PERF_FUNCTION_END()
#define PERF_FUNCTION_BEGIN()
EFI_STATUS(EFIAPI * EFI_AP_PROCEDURE2)(IN VOID *ProcedureArgument)
Definition: PiMultiPhase.h:214
UINTN EFIAPI GetSmiHandlerSize(VOID)
#define WRITE_UNPROTECT_RO_PAGES(Wp, Cet)
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
VOID *EFIAPI AllocateAlignedPages(IN UINTN Pages, IN UINTN Alignment)
UINTN GenSmmPageTable(IN PAGING_MODE PagingMode, IN UINT8 PhysicalAddressBits)
EFI_STATUS SmmSetMemoryAttributes(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Attributes)
EFI_STATUS SmmClearMemoryAttributesEx(IN UINTN PageTableBase, IN PAGING_MODE PagingMode, IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Attributes)
VOID * GetPageTableEntry(IN UINTN PageTableBase, IN BOOLEAN Enable5LevelPaging, IN PHYSICAL_ADDRESS Address, OUT PAGE_ATTRIBUTE *PageAttribute)
EFI_STATUS EFIAPI SmmGetSystemConfigurationTable(IN EFI_GUID *TableGuid, OUT VOID **Table)
RETURN_STATUS ConvertMemoryPageAttributes(IN UINTN PageTableBase, IN PAGING_MODE PagingMode, IN PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Attributes, IN BOOLEAN IsSet, OUT BOOLEAN *IsModified OPTIONAL)
BOOLEAN IfReadOnlyPageTableNeeded(VOID)
VOID EFIAPI FlushTlbOnCurrentProcessor(IN OUT VOID *Buffer)
UINT64 GetAttributesFromPageEntry(IN UINT64 *PageEntry)
EFI_STATUS SmmSetMemoryAttributesEx(IN UINTN PageTableBase, IN PAGING_MODE PagingMode, IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Attributes)
EFI_STATUS SetShadowStack(IN UINTN Cr3, IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length)
VOID SmmWriteUnprotectReadOnlyPage(OUT BOOLEAN *WriteProtect)
VOID * AllocatePageTableMemory(IN UINTN Pages)
EFI_STATUS EFIAPI EdkiiSmmSetMemoryAttributes(IN EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This, IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Attributes)
VOID GenPageTable(IN OUT UINTN *PageTable, IN PAGING_MODE PagingMode, IN UINT64 LinearAddress, IN UINT64 Length, IN IA32_MAP_ATTRIBUTE MapAttribute, IN IA32_MAP_ATTRIBUTE MapMask)
VOID FlushTlbForAll(VOID)
EFI_STATUS EFIAPI EdkiiSmmGetMemoryAttributes(IN EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This, IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, OUT UINT64 *Attributes)
VOID SetMemMapAttributes(EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable)
VOID SmmWriteProtectReadOnlyPage(IN BOOLEAN WriteProtect)
BOOLEAN InitializePageTablePool(IN UINTN PoolPages)
VOID PatchGdtIdtMap(VOID)
VOID PatchSmmSaveStateMap(VOID)
VOID SetPageTableAttributes(VOID)
VOID SetMemMapWithNonPresentRange(UINT64 Base, UINT64 Limit, UINT64 Attribute, IA32_MAP_ENTRY *Map, UINTN Count)
EFI_STATUS EFIAPI EdkiiSmmClearMemoryAttributes(IN EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This, IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Attributes)
VOID EnablePageTableProtection(VOID)
EFI_STATUS SmmClearMemoryAttributes(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Attributes)
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
#define EFI_PAGES_TO_SIZE(Pages)
Definition: UefiBaseType.h:213
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_STATUS InternalSmmStartupAllAPs(IN EFI_AP_PROCEDURE2 Procedure, IN UINTN TimeoutInMicroseconds, IN OUT VOID *ProcedureArguments OPTIONAL, IN OUT MM_COMPLETION *Token, IN OUT EFI_STATUS *CPUStatus)
Definition: MpService.c:1252
@ EfiConventionalMemory
@ EfiRuntimeServicesCode
@ EfiRuntimeServicesData
EFI_CONFIGURATION_TABLE * MmConfigurationTable
Definition: PiMmCis.h:322
UINTN NumberOfTableEntries
Definition: PiMmCis.h:317
EFI_VIRTUAL_ADDRESS VirtualStart
Definition: UefiSpec.h:161
EFI_PHYSICAL_ADDRESS PhysicalStart
Definition: UefiSpec.h:155
EFI_PHYSICAL_ADDRESS CpuStart
Definition: PiMultiPhase.h:127
Definition: Base.h:213
EFI_PHYSICAL_ADDRESS Base