26#define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \
27 ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size)))
29#define IMAGE_PROPERTIES_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('I','P','P','D')
33 UINTN ImageRecordCount;
34 UINTN CodeSegmentCountMax;
39 IMAGE_PROPERTIES_PRIVATE_DATA_SIGNATURE,
45#define EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA BIT0
47UINT64 mMemoryProtectionAttribute = EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA;
74 UINT64 MemoryBlockLength;
78 MemoryMapEntry = MemoryMap;
79 NewMemoryMapEntry = MemoryMap;
81 while ((
UINTN)MemoryMapEntry < (
UINTN)MemoryMapEnd) {
83 NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
87 if (((
UINTN)NextMemoryMapEntry < (
UINTN)MemoryMapEnd) &&
88 (MemoryMapEntry->
Type == NextMemoryMapEntry->
Type) &&
93 if (NewMemoryMapEntry != MemoryMapEntry) {
97 NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);
100 MemoryMapEntry = PREVIOUS_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);
105 MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
106 NewMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NewMemoryMapEntry, DescriptorSize);
109 *MemoryMapSize = (
UINTN)NewMemoryMapEntry - (
UINTN)MemoryMap;
134 MemoryMapEntry = MemoryMap;
136 while ((
UINTN)MemoryMapEntry < (
UINTN)MemoryMapEnd) {
140 switch (MemoryMapEntry->
Type) {
142 MemoryMapEntry->
Attribute = EFI_MEMORY_RO;
146 MemoryMapEntry->
Attribute |= EFI_MEMORY_XP;
151 MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
197 OUT UINT32 *DescriptorVersion
201 UINTN OldMemoryMapSize;
202 UINTN AdditionalRecordCount;
207 if ((mMemoryProtectionAttribute & EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) == 0) {
208 return SmmCoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion);
211 if (MemoryMapSize ==
NULL) {
212 return EFI_INVALID_PARAMETER;
215 AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 3) * mImagePropertiesPrivateData.ImageRecordCount;
217 OldMemoryMapSize = *MemoryMapSize;
218 Status =
SmmCoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion);
219 if (Status == EFI_BUFFER_TOO_SMALL) {
220 *MemoryMapSize = *MemoryMapSize + (*DescriptorSize) * AdditionalRecordCount;
222 if (OldMemoryMapSize - *MemoryMapSize < (*DescriptorSize) * AdditionalRecordCount) {
223 *MemoryMapSize = *MemoryMapSize + (*DescriptorSize) * AdditionalRecordCount;
227 Status = EFI_BUFFER_TOO_SMALL;
232 ASSERT (MemoryMap !=
NULL);
233 SplitTable (MemoryMapSize, MemoryMap, *DescriptorSize, &mImagePropertiesPrivateData.ImageRecordList, AdditionalRecordCount);
267 UINT32 RequiredAlignment;
272 if (ImageRecord ==
NULL) {
280 if (PdbPointer !=
NULL) {
281 DEBUG ((DEBUG_VERBOSE,
"SMM Image - %a\n", PdbPointer));
284 RequiredAlignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY;
292 if (EFI_ERROR (Status)) {
293 if (Status == EFI_ABORTED) {
294 mMemoryProtectionAttribute &=
295 ~((UINT64)EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA);
301 if (ImageRecord->CodeSegmentCount == 0) {
302 mMemoryProtectionAttribute &=
303 ~((UINT64)EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA);
304 DEBUG ((DEBUG_ERROR,
"SMM !!!!!!!! InsertImageRecord - CodeSegmentCount is 0 !!!!!!!!\n"));
305 if (PdbPointer !=
NULL) {
306 DEBUG ((DEBUG_ERROR,
"SMM !!!!!!!! Image - %a !!!!!!!!\n", PdbPointer));
309 Status = EFI_ABORTED;
317 DEBUG ((DEBUG_ERROR,
"SMM IsImageRecordCodeSectionValid - FAIL\n"));
318 Status = EFI_ABORTED;
322 InsertTailList (&mImagePropertiesPrivateData.ImageRecordList, &ImageRecord->Link);
323 mImagePropertiesPrivateData.ImageRecordCount++;
325 if (mImagePropertiesPrivateData.CodeSegmentCountMax < ImageRecord->CodeSegmentCount) {
326 mImagePropertiesPrivateData.CodeSegmentCountMax = ImageRecord->CodeSegmentCount;
332 if (EFI_ERROR (Status) && (ImageRecord !=
NULL)) {
350 UINTN DescriptorSize;
351 UINT32 DescriptorVersion;
354 UINTN RuntimeEntryCount;
357 UINTN MemoryAttributesTableSize;
368 ASSERT (Status == EFI_BUFFER_TOO_SMALL);
371 DEBUG ((DEBUG_VERBOSE,
"MemoryMapSize - 0x%x\n", MemoryMapSize));
373 ASSERT (MemoryMap !=
NULL);
374 DEBUG ((DEBUG_VERBOSE,
"MemoryMap - 0x%x\n", MemoryMap));
383 if (EFI_ERROR (Status)) {
386 }
while (Status == EFI_BUFFER_TOO_SMALL);
391 RuntimeEntryCount = MemoryMapSize/DescriptorSize;
394 ASSERT (MemoryAttributesTable !=
NULL);
395 MemoryAttributesTable->Version = EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE_VERSION;
396 MemoryAttributesTable->NumberOfEntries = (UINT32)RuntimeEntryCount;
397 MemoryAttributesTable->DescriptorSize = (UINT32)DescriptorSize;
398 MemoryAttributesTable->Reserved = 0;
399 DEBUG ((DEBUG_VERBOSE,
"MemoryAttributesTable:\n"));
400 DEBUG ((DEBUG_VERBOSE,
" Version - 0x%08x\n", MemoryAttributesTable->Version));
401 DEBUG ((DEBUG_VERBOSE,
" NumberOfEntries - 0x%08x\n", MemoryAttributesTable->NumberOfEntries));
402 DEBUG ((DEBUG_VERBOSE,
" DescriptorSize - 0x%08x\n", MemoryAttributesTable->DescriptorSize));
404 for (Index = 0; Index < MemoryMapSize/DescriptorSize; Index++) {
405 CopyMem (MemoryAttributesEntry, MemoryMap, DescriptorSize);
406 DEBUG ((DEBUG_VERBOSE,
"Entry (0x%x)\n", MemoryAttributesEntry));
407 DEBUG ((DEBUG_VERBOSE,
" Type - 0x%x\n", MemoryAttributesEntry->
Type));
408 DEBUG ((DEBUG_VERBOSE,
" PhysicalStart - 0x%016lx\n", MemoryAttributesEntry->
PhysicalStart));
409 DEBUG ((DEBUG_VERBOSE,
" VirtualStart - 0x%016lx\n", MemoryAttributesEntry->
VirtualStart));
410 DEBUG ((DEBUG_VERBOSE,
" NumberOfPages - 0x%016lx\n", MemoryAttributesEntry->
NumberOfPages));
411 DEBUG ((DEBUG_VERBOSE,
" Attribute - 0x%016lx\n", MemoryAttributesEntry->
Attribute));
412 MemoryAttributesEntry = NEXT_MEMORY_DESCRIPTOR (MemoryAttributesEntry, DescriptorSize);
414 MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, DescriptorSize);
417 Status =
gSmst->SmmInstallConfigurationTable (
gSmst, &gEdkiiPiSmmMemoryAttributesTableGuid, MemoryAttributesTable, MemoryAttributesTableSize);
438 &gEfiLoadedImageProtocolGuid,
443 if (EFI_ERROR (Status)) {
447 for (Index = 0; Index < NoHandles; Index++) {
448 Status =
gSmst->SmmHandleProtocol (
450 &gEfiLoadedImageProtocolGuid,
451 (
VOID **)&LoadedImage
453 if (EFI_ERROR (Status)) {
457 DEBUG ((DEBUG_VERBOSE,
"LoadedImage - 0x%x 0x%x ", LoadedImage->ImageBase, LoadedImage->ImageSize));
460 PdbPointer = PeCoffLoaderGetPdbPointer (LoadedImage->ImageBase);
461 if (PdbPointer !=
NULL) {
462 DEBUG ((DEBUG_VERBOSE,
"(%a) ", PdbPointer));
465 DEBUG ((DEBUG_VERBOSE,
"\n"));
472 if (HandleBuffer !=
NULL) {
496 DEBUG ((DEBUG_VERBOSE,
"SMM MemoryProtectionAttribute - 0x%016lx\n", mMemoryProtectionAttribute));
497 if ((mMemoryProtectionAttribute & EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) == 0) {
502 if ( mImagePropertiesPrivateData.ImageRecordCount > 0) {
503 DEBUG ((DEBUG_INFO,
"SMM - Total Runtime Image Count - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount));
504 DEBUG ((DEBUG_INFO,
"SMM - Dump Runtime Image Records:\n"));
527 Status =
gSmst->SmmRegisterProtocolNotify (
528 &gEfiSmmEndOfDxeProtocolGuid,
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
#define INITIALIZE_LIST_HEAD_VARIABLE(ListHead)
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID EFIAPI FreePool(IN VOID *Buffer)
EFI_STATUS EFIAPI SplitTable(IN OUT UINTN *MemoryMapSize, IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, IN UINTN DescriptorSize, IN LIST_ENTRY *ImageRecordList, IN UINTN NumberOfAdditionalDescriptors)
VOID EFIAPI DeleteImagePropertiesRecord(IN IMAGE_PROPERTIES_RECORD *ImageRecord)
BOOLEAN EFIAPI IsImageRecordCodeSectionValid(IN IMAGE_PROPERTIES_RECORD *ImageRecord)
EFI_STATUS EFIAPI CreateImagePropertiesRecord(IN CONST VOID *ImageBase, IN CONST UINT64 ImageSize, IN CONST UINT32 *Alignment OPTIONAL, OUT IMAGE_PROPERTIES_RECORD *ImageRecord)
VOID EFIAPI DumpImageRecords(IN LIST_ENTRY *ImageRecordList)
EFI_STATUS EFIAPI SortImageRecord(IN LIST_ENTRY *ImageRecordList)
VOID MergeMemoryMap(IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, IN OUT UINTN *MemoryMapSize, IN UINTN DescriptorSize)
STATIC VOID EnforceMemoryMapAttribute(IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, IN UINTN MemoryMapSize, IN UINTN DescriptorSize)
EFI_STATUS EFIAPI SmmLocateHandleBuffer(IN EFI_LOCATE_SEARCH_TYPE SearchType, IN EFI_GUID *Protocol OPTIONAL, IN VOID *SearchKey OPTIONAL, IN OUT UINTN *NumberHandles, OUT EFI_HANDLE **Buffer)
VOID SmmInstallImageRecord(VOID)
EFI_STATUS EFIAPI SmmInstallMemoryAttributesTable(IN CONST EFI_GUID *Protocol, IN VOID *Interface, IN EFI_HANDLE Handle)
VOID PublishMemoryAttributesTable(VOID)
VOID SmmInsertImageRecord(IN EFI_SMM_DRIVER_ENTRY *DriverEntry)
VOID EFIAPI SmmCoreInitializeMemoryAttributesTable(VOID)
STATIC EFI_STATUS EFIAPI SmmCoreGetMemoryMapMemoryAttributesTable(IN OUT UINTN *MemoryMapSize, IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, OUT UINTN *MapKey, OUT UINTN *DescriptorSize, OUT UINT32 *DescriptorVersion)
EFI_STATUS EFIAPI SmmCoreGetMemoryMap(IN OUT UINTN *MemoryMapSize, IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, OUT UINTN *MapKey, OUT UINTN *DescriptorSize, OUT UINT32 *DescriptorVersion)
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG_CODE_BEGIN()
#define DEBUG(Expression)
EFI_SMM_SYSTEM_TABLE2 * gSmst
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
EFI_STATUS EFIAPI DriverEntry(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
#define EFI_SIZE_TO_PAGES(Size)
EFI_VIRTUAL_ADDRESS VirtualStart
EFI_PHYSICAL_ADDRESS PhysicalStart