2 UEFI Memory Protection support.
4 If the UEFI image is page aligned, the image code section is set to read only
5 and the image data section is set to non-executable.
7 1) This policy is applied for all UEFI image including boot service driver,
8 runtime driver or application.
9 2) This policy is applied only if the UEFI image meets the page alignment
11 3) This policy is applied only if the Source UEFI image matches the
12 PcdImageProtectionPolicy definition.
13 4) This policy is not applied to the non-PE image region.
15 The DxeCore calls CpuArchProtocol->SetMemoryAttributes() to protect
16 the image. If the CpuArch protocol is not installed yet, the DxeCore
17 enqueues the protection request. Once the CpuArch is installed, the
18 DxeCore dequeues the protection request and applies policy.
20 Once the image is unloaded, the protection is removed automatically.
22 Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
23 This program and the accompanying materials
24 are licensed and made available under the terms and conditions of the BSD License
25 which accompanies this distribution. The full text of the license may be found at
26 http://opensource.org/licenses/bsd-license.php
28 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
29 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
34 #include <Library/BaseLib.h>
35 #include <Library/BaseMemoryLib.h>
36 #include <Library/MemoryAllocationLib.h>
37 #include <Library/UefiBootServicesTableLib.h>
38 #include <Library/DxeServicesTableLib.h>
39 #include <Library/DebugLib.h>
40 #include <Library/UefiLib.h>
42 #include <Guid/EventGroup.h>
43 #include <Guid/MemoryAttributesTable.h>
44 #include <Guid/PropertiesTable.h>
46 #include <Protocol/FirmwareVolume2.h>
47 #include <Protocol/BlockIo.h>
48 #include <Protocol/SimpleFileSystem.h>
52 #define CACHE_ATTRIBUTE_MASK (EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_WP)
53 #define MEMORY_ATTRIBUTE_MASK (EFI_MEMORY_RP | EFI_MEMORY_XP | EFI_MEMORY_RO)
56 // Image type definitions
58 #define IMAGE_UNKNOWN 0x00000001
59 #define IMAGE_FROM_FV 0x00000002
62 // Protection policy bit definition
64 #define DO_NOT_PROTECT 0x00000000
65 #define PROTECT_IF_ALIGNED_ELSE_ALLOW 0x00000001
67 UINT32 mImageProtectionPolicy
;
70 Sort code section in image record, based upon CodeSegmentBase from low to high.
72 @param ImageRecord image record to be sorted
75 SortImageRecordCodeSection (
76 IN IMAGE_PROPERTIES_RECORD
*ImageRecord
80 Check if code section in image record is valid.
82 @param ImageRecord image record to be checked
84 @retval TRUE image record is valid
85 @retval FALSE image record is invalid
88 IsImageRecordCodeSectionValid (
89 IN IMAGE_PROPERTIES_RECORD
*ImageRecord
95 @param[in] File This is a pointer to the device path of the file that is
98 @return UINT32 Image Type
102 IN CONST EFI_DEVICE_PATH_PROTOCOL
*File
106 EFI_HANDLE DeviceHandle
;
107 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
110 return IMAGE_UNKNOWN
;
114 // First check to see if File is from a Firmware Volume
117 TempDevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) File
;
118 Status
= gBS
->LocateDevicePath (
119 &gEfiFirmwareVolume2ProtocolGuid
,
123 if (!EFI_ERROR (Status
)) {
124 Status
= gBS
->OpenProtocol (
126 &gEfiFirmwareVolume2ProtocolGuid
,
130 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
132 if (!EFI_ERROR (Status
)) {
133 return IMAGE_FROM_FV
;
136 return IMAGE_UNKNOWN
;
140 Get UEFI image protection policy based upon image type.
142 @param[in] ImageType The UEFI image type
144 @return UEFI image protection policy
147 GetProtectionPolicyFromImageType (
151 if ((ImageType
& mImageProtectionPolicy
) == 0) {
152 return DO_NOT_PROTECT
;
154 return PROTECT_IF_ALIGNED_ELSE_ALLOW
;
159 Get UEFI image protection policy based upon loaded image device path.
161 @param[in] LoadedImage The loaded image protocol
162 @param[in] LoadedImageDevicePath The loaded image device path protocol
164 @return UEFI image protection policy
167 GetUefiImageProtectionPolicy (
168 IN EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
,
169 IN EFI_DEVICE_PATH_PROTOCOL
*LoadedImageDevicePath
174 UINT32 ProtectionPolicy
;
180 if (gSmmBase2
!= NULL
) {
181 gSmmBase2
->InSmm (gSmmBase2
, &InSmm
);
190 if (LoadedImage
== gDxeCoreLoadedImage
) {
191 ImageType
= IMAGE_FROM_FV
;
193 ImageType
= GetImageType (LoadedImageDevicePath
);
195 ProtectionPolicy
= GetProtectionPolicyFromImageType (ImageType
);
196 return ProtectionPolicy
;
201 Set UEFI image memory attributes.
203 @param[in] BaseAddress Specified start address
204 @param[in] Length Specified length
205 @param[in] Attributes Specified attributes
208 SetUefiImageMemoryAttributes (
209 IN UINT64 BaseAddress
,
215 EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor
;
216 UINT64 FinalAttributes
;
218 Status
= CoreGetMemorySpaceDescriptor(BaseAddress
, &Descriptor
);
219 ASSERT_EFI_ERROR(Status
);
221 FinalAttributes
= (Descriptor
.Attributes
& CACHE_ATTRIBUTE_MASK
) | (Attributes
& MEMORY_ATTRIBUTE_MASK
);
223 DEBUG ((DEBUG_INFO
, "SetUefiImageMemoryAttributes - 0x%016lx - 0x%016lx (0x%016lx)\n", BaseAddress
, Length
, FinalAttributes
));
225 ASSERT(gCpu
!= NULL
);
226 gCpu
->SetMemoryAttributes (gCpu
, BaseAddress
, Length
, FinalAttributes
);
230 Set UEFI image protection attributes.
232 @param[in] ImageRecord A UEFI image record
233 @param[in] Protect TRUE: Protect the UEFI image.
234 FALSE: Unprotect the UEFI image.
237 SetUefiImageProtectionAttributes (
238 IN IMAGE_PROPERTIES_RECORD
*ImageRecord
,
242 IMAGE_PROPERTIES_RECORD_CODE_SECTION
*ImageRecordCodeSection
;
243 LIST_ENTRY
*ImageRecordCodeSectionLink
;
244 LIST_ENTRY
*ImageRecordCodeSectionEndLink
;
245 LIST_ENTRY
*ImageRecordCodeSectionList
;
250 ImageRecordCodeSectionList
= &ImageRecord
->CodeSegmentList
;
252 CurrentBase
= ImageRecord
->ImageBase
;
253 ImageEnd
= ImageRecord
->ImageBase
+ ImageRecord
->ImageSize
;
255 ImageRecordCodeSectionLink
= ImageRecordCodeSectionList
->ForwardLink
;
256 ImageRecordCodeSectionEndLink
= ImageRecordCodeSectionList
;
257 while (ImageRecordCodeSectionLink
!= ImageRecordCodeSectionEndLink
) {
258 ImageRecordCodeSection
= CR (
259 ImageRecordCodeSectionLink
,
260 IMAGE_PROPERTIES_RECORD_CODE_SECTION
,
262 IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
264 ImageRecordCodeSectionLink
= ImageRecordCodeSectionLink
->ForwardLink
;
266 ASSERT (CurrentBase
<= ImageRecordCodeSection
->CodeSegmentBase
);
267 if (CurrentBase
< ImageRecordCodeSection
->CodeSegmentBase
) {
272 Attribute
= EFI_MEMORY_XP
;
276 SetUefiImageMemoryAttributes (
278 ImageRecordCodeSection
->CodeSegmentBase
- CurrentBase
,
286 Attribute
= EFI_MEMORY_RO
;
290 SetUefiImageMemoryAttributes (
291 ImageRecordCodeSection
->CodeSegmentBase
,
292 ImageRecordCodeSection
->CodeSegmentSize
,
295 CurrentBase
= ImageRecordCodeSection
->CodeSegmentBase
+ ImageRecordCodeSection
->CodeSegmentSize
;
300 ASSERT (CurrentBase
<= ImageEnd
);
301 if (CurrentBase
< ImageEnd
) {
306 Attribute
= EFI_MEMORY_XP
;
310 SetUefiImageMemoryAttributes (
312 ImageEnd
- CurrentBase
,
320 Return if the PE image section is aligned.
322 @param[in] SectionAlignment PE/COFF section alignment
323 @param[in] MemoryType PE/COFF image memory type
325 @retval TRUE The PE image section is aligned.
326 @retval FALSE The PE image section is not aligned.
329 IsMemoryProtectionSectionAligned (
330 IN UINT32 SectionAlignment
,
331 IN EFI_MEMORY_TYPE MemoryType
334 UINT32 PageAlignment
;
336 switch (MemoryType
) {
337 case EfiRuntimeServicesCode
:
338 case EfiACPIMemoryNVS
:
339 PageAlignment
= EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT
;
341 case EfiRuntimeServicesData
:
342 case EfiACPIReclaimMemory
:
344 PageAlignment
= EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT
;
346 case EfiBootServicesCode
:
348 case EfiReservedMemoryType
:
349 PageAlignment
= EFI_PAGE_SIZE
;
353 PageAlignment
= EFI_PAGE_SIZE
;
357 if ((SectionAlignment
& (PageAlignment
- 1)) != 0) {
367 @param[in] ImageRecord A UEFI image record
371 IN IMAGE_PROPERTIES_RECORD
*ImageRecord
374 LIST_ENTRY
*CodeSegmentListHead
;
375 IMAGE_PROPERTIES_RECORD_CODE_SECTION
*ImageRecordCodeSection
;
377 CodeSegmentListHead
= &ImageRecord
->CodeSegmentList
;
378 while (!IsListEmpty (CodeSegmentListHead
)) {
379 ImageRecordCodeSection
= CR (
380 CodeSegmentListHead
->ForwardLink
,
381 IMAGE_PROPERTIES_RECORD_CODE_SECTION
,
383 IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
385 RemoveEntryList (&ImageRecordCodeSection
->Link
);
386 FreePool (ImageRecordCodeSection
);
389 if (ImageRecord
->Link
.ForwardLink
!= NULL
) {
390 RemoveEntryList (&ImageRecord
->Link
);
392 FreePool (ImageRecord
);
396 Protect or unprotect UEFI image common function.
398 @param[in] LoadedImage The loaded image protocol
399 @param[in] LoadedImageDevicePath The loaded image device path protocol
400 @param[in] Protect TRUE: Protect the UEFI image.
401 FALSE: Unprotect the UEFI image.
404 ProtectUefiImageCommon (
405 IN EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
,
406 IN EFI_DEVICE_PATH_PROTOCOL
*LoadedImageDevicePath
,
411 EFI_IMAGE_DOS_HEADER
*DosHdr
;
412 UINT32 PeCoffHeaderOffset
;
413 UINT32 SectionAlignment
;
414 EFI_IMAGE_SECTION_HEADER
*Section
;
415 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr
;
418 IMAGE_PROPERTIES_RECORD
*ImageRecord
;
420 IMAGE_PROPERTIES_RECORD_CODE_SECTION
*ImageRecordCodeSection
;
423 UINT32 ProtectionPolicy
;
425 DEBUG ((DEBUG_INFO
, "ProtectUefiImageCommon - 0x%x\n", LoadedImage
));
426 DEBUG ((DEBUG_INFO
, " - 0x%016lx - 0x%016lx\n", (EFI_PHYSICAL_ADDRESS
)(UINTN
)LoadedImage
->ImageBase
, LoadedImage
->ImageSize
));
432 ProtectionPolicy
= GetUefiImageProtectionPolicy (LoadedImage
, LoadedImageDevicePath
);
433 switch (ProtectionPolicy
) {
436 case PROTECT_IF_ALIGNED_ELSE_ALLOW
:
443 ImageRecord
= AllocateZeroPool (sizeof(*ImageRecord
));
444 if (ImageRecord
== NULL
) {
447 ImageRecord
->Signature
= IMAGE_PROPERTIES_RECORD_SIGNATURE
;
450 // Step 1: record whole region
452 ImageRecord
->ImageBase
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)LoadedImage
->ImageBase
;
453 ImageRecord
->ImageSize
= LoadedImage
->ImageSize
;
455 ImageAddress
= LoadedImage
->ImageBase
;
457 PdbPointer
= PeCoffLoaderGetPdbPointer ((VOID
*) (UINTN
) ImageAddress
);
458 if (PdbPointer
!= NULL
) {
459 DEBUG ((DEBUG_VERBOSE
, " Image - %a\n", PdbPointer
));
463 // Check PE/COFF image
465 DosHdr
= (EFI_IMAGE_DOS_HEADER
*) (UINTN
) ImageAddress
;
466 PeCoffHeaderOffset
= 0;
467 if (DosHdr
->e_magic
== EFI_IMAGE_DOS_SIGNATURE
) {
468 PeCoffHeaderOffset
= DosHdr
->e_lfanew
;
471 Hdr
.Pe32
= (EFI_IMAGE_NT_HEADERS32
*)((UINT8
*) (UINTN
) ImageAddress
+ PeCoffHeaderOffset
);
472 if (Hdr
.Pe32
->Signature
!= EFI_IMAGE_NT_SIGNATURE
) {
473 DEBUG ((DEBUG_VERBOSE
, "Hdr.Pe32->Signature invalid - 0x%x\n", Hdr
.Pe32
->Signature
));
474 // It might be image in SMM.
479 // Get SectionAlignment
481 if (Hdr
.Pe32
->FileHeader
.Machine
== IMAGE_FILE_MACHINE_IA64
&& Hdr
.Pe32
->OptionalHeader
.Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
483 // NOTE: Some versions of Linux ELILO for Itanium have an incorrect magic value
484 // in the PE/COFF Header. If the MachineType is Itanium(IA64) and the
485 // Magic value in the OptionalHeader is EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
486 // then override the magic value to EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
488 Magic
= EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
;
491 // Get the magic value from the PE/COFF Optional Header
493 Magic
= Hdr
.Pe32
->OptionalHeader
.Magic
;
495 if (Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
496 SectionAlignment
= Hdr
.Pe32
->OptionalHeader
.SectionAlignment
;
498 SectionAlignment
= Hdr
.Pe32Plus
->OptionalHeader
.SectionAlignment
;
501 IsAligned
= IsMemoryProtectionSectionAligned (SectionAlignment
, LoadedImage
->ImageCodeType
);
503 DEBUG ((DEBUG_VERBOSE
, "!!!!!!!! ProtectUefiImageCommon - Section Alignment(0x%x) is incorrect !!!!!!!!\n",
505 PdbPointer
= PeCoffLoaderGetPdbPointer ((VOID
*) (UINTN
) ImageAddress
);
506 if (PdbPointer
!= NULL
) {
507 DEBUG ((DEBUG_VERBOSE
, "!!!!!!!! Image - %a !!!!!!!!\n", PdbPointer
));
512 Section
= (EFI_IMAGE_SECTION_HEADER
*) (
513 (UINT8
*) (UINTN
) ImageAddress
+
516 sizeof(EFI_IMAGE_FILE_HEADER
) +
517 Hdr
.Pe32
->FileHeader
.SizeOfOptionalHeader
519 ImageRecord
->CodeSegmentCount
= 0;
520 InitializeListHead (&ImageRecord
->CodeSegmentList
);
521 for (Index
= 0; Index
< Hdr
.Pe32
->FileHeader
.NumberOfSections
; Index
++) {
522 Name
= Section
[Index
].Name
;
525 " Section - '%c%c%c%c%c%c%c%c'\n",
537 // Instead of assuming that a PE/COFF section of type EFI_IMAGE_SCN_CNT_CODE
538 // can always be mapped read-only, classify a section as a code section only
539 // if it has the executable attribute set and the writable attribute cleared.
541 // This adheres more closely to the PE/COFF spec, and avoids issues with
542 // Linux OS loaders that may consist of a single read/write/execute section.
544 if ((Section
[Index
].Characteristics
& (EFI_IMAGE_SCN_MEM_WRITE
| EFI_IMAGE_SCN_MEM_EXECUTE
)) == EFI_IMAGE_SCN_MEM_EXECUTE
) {
545 DEBUG ((DEBUG_VERBOSE
, " VirtualSize - 0x%08x\n", Section
[Index
].Misc
.VirtualSize
));
546 DEBUG ((DEBUG_VERBOSE
, " VirtualAddress - 0x%08x\n", Section
[Index
].VirtualAddress
));
547 DEBUG ((DEBUG_VERBOSE
, " SizeOfRawData - 0x%08x\n", Section
[Index
].SizeOfRawData
));
548 DEBUG ((DEBUG_VERBOSE
, " PointerToRawData - 0x%08x\n", Section
[Index
].PointerToRawData
));
549 DEBUG ((DEBUG_VERBOSE
, " PointerToRelocations - 0x%08x\n", Section
[Index
].PointerToRelocations
));
550 DEBUG ((DEBUG_VERBOSE
, " PointerToLinenumbers - 0x%08x\n", Section
[Index
].PointerToLinenumbers
));
551 DEBUG ((DEBUG_VERBOSE
, " NumberOfRelocations - 0x%08x\n", Section
[Index
].NumberOfRelocations
));
552 DEBUG ((DEBUG_VERBOSE
, " NumberOfLinenumbers - 0x%08x\n", Section
[Index
].NumberOfLinenumbers
));
553 DEBUG ((DEBUG_VERBOSE
, " Characteristics - 0x%08x\n", Section
[Index
].Characteristics
));
556 // Step 2: record code section
558 ImageRecordCodeSection
= AllocatePool (sizeof(*ImageRecordCodeSection
));
559 if (ImageRecordCodeSection
== NULL
) {
562 ImageRecordCodeSection
->Signature
= IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
;
564 ImageRecordCodeSection
->CodeSegmentBase
= (UINTN
)ImageAddress
+ Section
[Index
].VirtualAddress
;
565 ImageRecordCodeSection
->CodeSegmentSize
= ALIGN_VALUE(Section
[Index
].SizeOfRawData
, SectionAlignment
);
567 DEBUG ((DEBUG_VERBOSE
, "ImageCode: 0x%016lx - 0x%016lx\n", ImageRecordCodeSection
->CodeSegmentBase
, ImageRecordCodeSection
->CodeSegmentSize
));
569 InsertTailList (&ImageRecord
->CodeSegmentList
, &ImageRecordCodeSection
->Link
);
570 ImageRecord
->CodeSegmentCount
++;
574 if (ImageRecord
->CodeSegmentCount
== 0) {
575 DEBUG ((DEBUG_ERROR
, "!!!!!!!! ProtectUefiImageCommon - CodeSegmentCount is 0 !!!!!!!!\n"));
576 PdbPointer
= PeCoffLoaderGetPdbPointer ((VOID
*) (UINTN
) ImageAddress
);
577 if (PdbPointer
!= NULL
) {
578 DEBUG ((DEBUG_ERROR
, "!!!!!!!! Image - %a !!!!!!!!\n", PdbPointer
));
586 SortImageRecordCodeSection (ImageRecord
);
588 // Check overlap all section in ImageBase/Size
590 if (!IsImageRecordCodeSectionValid (ImageRecord
)) {
591 DEBUG ((DEBUG_ERROR
, "IsImageRecordCodeSectionValid - FAIL\n"));
596 // Round up the ImageSize, some CPU arch may return EFI_UNSUPPORTED if ImageSize is not aligned.
597 // Given that the loader always allocates full pages, we know the space after the image is not used.
599 ImageRecord
->ImageSize
= ALIGN_VALUE(LoadedImage
->ImageSize
, EFI_PAGE_SIZE
);
602 // CPU ARCH present. Update memory attribute directly.
604 SetUefiImageProtectionAttributes (ImageRecord
, Protect
);
609 FreeImageRecord (ImageRecord
);
618 @param[in] LoadedImage The loaded image protocol
619 @param[in] LoadedImageDevicePath The loaded image device path protocol
623 IN EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
,
624 IN EFI_DEVICE_PATH_PROTOCOL
*LoadedImageDevicePath
627 if (PcdGet32(PcdImageProtectionPolicy
) != 0) {
628 ProtectUefiImageCommon (LoadedImage
, LoadedImageDevicePath
, TRUE
);
633 Unprotect UEFI image.
635 @param[in] LoadedImage The loaded image protocol
636 @param[in] LoadedImageDevicePath The loaded image device path protocol
640 IN EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
,
641 IN EFI_DEVICE_PATH_PROTOCOL
*LoadedImageDevicePath
644 if (PcdGet32(PcdImageProtectionPolicy
) != 0) {
645 ProtectUefiImageCommon (LoadedImage
, LoadedImageDevicePath
, FALSE
);
650 A notification for CPU_ARCH protocol.
652 @param[in] Event Event whose notification function is being invoked.
653 @param[in] Context Pointer to the notification function's context,
654 which is implementation-dependent.
659 MemoryProtectionCpuArchProtocolNotify (
665 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
666 EFI_DEVICE_PATH_PROTOCOL
*LoadedImageDevicePath
;
668 EFI_HANDLE
*HandleBuffer
;
671 DEBUG ((DEBUG_INFO
, "MemoryProtectionCpuArchProtocolNotify:\n"));
672 Status
= CoreLocateProtocol (&gEfiCpuArchProtocolGuid
, NULL
, (VOID
**)&gCpu
);
673 if (EFI_ERROR (Status
)) {
677 Status
= gBS
->LocateHandleBuffer (
679 &gEfiLoadedImageProtocolGuid
,
684 if (EFI_ERROR (Status
) && (NoHandles
== 0)) {
688 for (Index
= 0; Index
< NoHandles
; Index
++) {
689 Status
= gBS
->HandleProtocol (
691 &gEfiLoadedImageProtocolGuid
,
692 (VOID
**)&LoadedImage
694 if (EFI_ERROR(Status
)) {
697 Status
= gBS
->HandleProtocol (
699 &gEfiLoadedImageDevicePathProtocolGuid
,
700 (VOID
**)&LoadedImageDevicePath
702 if (EFI_ERROR(Status
)) {
703 LoadedImageDevicePath
= NULL
;
706 ProtectUefiImage (LoadedImage
, LoadedImageDevicePath
);
709 CoreCloseEvent (Event
);
714 ExitBootServices Callback function for memory protection.
717 MemoryProtectionExitBootServicesCallback (
721 EFI_RUNTIME_IMAGE_ENTRY
*RuntimeImage
;
725 // We need remove the RT protection, because RT relocation need write code segment
726 // at SetVirtualAddressMap(). We cannot assume OS/Loader has taken over page table at that time.
728 // Firmware does not own page tables after ExitBootServices(), so the OS would
729 // have to relax protection of RT code pages across SetVirtualAddressMap(), or
730 // delay setting protections on RT code pages until after SetVirtualAddressMap().
731 // OS may set protection on RT based upon EFI_MEMORY_ATTRIBUTES_TABLE later.
733 if (mImageProtectionPolicy
!= 0) {
734 for (Link
= gRuntime
->ImageHead
.ForwardLink
; Link
!= &gRuntime
->ImageHead
; Link
= Link
->ForwardLink
) {
735 RuntimeImage
= BASE_CR (Link
, EFI_RUNTIME_IMAGE_ENTRY
, Link
);
736 SetUefiImageMemoryAttributes ((UINT64
)(UINTN
)RuntimeImage
->ImageBase
, ALIGN_VALUE(RuntimeImage
->ImageSize
, EFI_PAGE_SIZE
), 0);
742 Initialize Memory Protection support.
746 CoreInitializeMemoryProtection (
754 mImageProtectionPolicy
= PcdGet32(PcdImageProtectionPolicy
);
756 if (mImageProtectionPolicy
!= 0) {
757 Status
= CoreCreateEvent (
760 MemoryProtectionCpuArchProtocolNotify
,
764 ASSERT_EFI_ERROR(Status
);
767 // Register for protocol notifactions on this event
769 Status
= CoreRegisterProtocolNotify (
770 &gEfiCpuArchProtocolGuid
,
774 ASSERT_EFI_ERROR(Status
);