#define EFI_MEMORY_INITIALIZED 0x0200000000000000ULL\r
#define EFI_MEMORY_TESTED 0x0400000000000000ULL\r
\r
-#define NEXT_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \\r
- ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) + (Size)))\r
-\r
#define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \\r
((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size)))\r
\r
EFI_GCD_MEMORY_SPACE_DESCRIPTOR *mGcdMemSpace = NULL;\r
UINTN mGcdMemNumberOfDesc = 0;\r
\r
+EFI_MEMORY_ATTRIBUTES_TABLE *mUefiMemoryAttributesTable = NULL;\r
+\r
PAGE_ATTRIBUTE_TABLE mPageAttributeTable[] = {\r
{Page4K, SIZE_4KB, PAGING_4K_ADDRESS_MASK_64},\r
{Page2M, SIZE_2MB, PAGING_2M_ADDRESS_MASK_64},\r
gBS->FreePool (MemSpaceMap);\r
}\r
\r
+/**\r
+ Get UEFI MemoryAttributesTable.\r
+**/\r
+VOID\r
+GetUefiMemoryAttributesTable (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable;\r
+ UINTN MemoryAttributesTableSize;\r
+\r
+ Status = EfiGetSystemConfigurationTable (&gEfiMemoryAttributesTableGuid, (VOID **)&MemoryAttributesTable);\r
+ if (!EFI_ERROR (Status)) {\r
+ MemoryAttributesTableSize = sizeof(EFI_MEMORY_ATTRIBUTES_TABLE) + MemoryAttributesTable->DescriptorSize * MemoryAttributesTable->NumberOfEntries;\r
+ mUefiMemoryAttributesTable = AllocateCopyPool (MemoryAttributesTableSize, MemoryAttributesTable);\r
+ ASSERT (mUefiMemoryAttributesTable != NULL);\r
+ }\r
+}\r
+\r
/**\r
This function caches the UEFI memory map information.\r
**/\r
// Get additional information from GCD memory map.\r
//\r
GetGcdMemoryMap ();\r
+\r
+ //\r
+ // Get UEFI memory attributes table.\r
+ //\r
+ GetUefiMemoryAttributesTable ();\r
}\r
\r
/**\r
EFI_MEMORY_DESCRIPTOR *MemoryMap;\r
UINTN MemoryMapEntryCount;\r
UINTN Index;\r
+ EFI_MEMORY_DESCRIPTOR *Entry;\r
\r
DEBUG ((DEBUG_INFO, "SetUefiMemMapAttributes\n"));\r
\r
//\r
// Do not free mGcdMemSpace, it will be checked in IsSmmCommBufferForbiddenAddress().\r
//\r
+\r
+ //\r
+ // Set UEFI runtime memory with EFI_MEMORY_RO as not present.\r
+ //\r
+ if (mUefiMemoryAttributesTable != NULL) {\r
+ Entry = (EFI_MEMORY_DESCRIPTOR *)(mUefiMemoryAttributesTable + 1);\r
+ for (Index = 0; Index < mUefiMemoryAttributesTable->NumberOfEntries; Index++) {\r
+ if (Entry->Type == EfiRuntimeServicesCode || Entry->Type == EfiRuntimeServicesData) {\r
+ if ((Entry->Attribute & EFI_MEMORY_RO) != 0) {\r
+ Status = SmmSetMemoryAttributes (\r
+ Entry->PhysicalStart,\r
+ EFI_PAGES_TO_SIZE((UINTN)Entry->NumberOfPages),\r
+ EFI_MEMORY_RP\r
+ );\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "UefiMemoryAttribute protection: 0x%lx - 0x%lx %r\n",\r
+ Entry->PhysicalStart,\r
+ Entry->PhysicalStart + (UINT64)EFI_PAGES_TO_SIZE((UINTN)Entry->NumberOfPages),\r
+ Status\r
+ ));\r
+ }\r
+ }\r
+ Entry = NEXT_MEMORY_DESCRIPTOR (Entry, mUefiMemoryAttributesTable->DescriptorSize);\r
+ }\r
+ }\r
+ //\r
+ // Do not free mUefiMemoryAttributesTable, it will be checked in IsSmmCommBufferForbiddenAddress().\r
+ //\r
}\r
\r
/**\r
EFI_MEMORY_DESCRIPTOR *MemoryMap;\r
UINTN MemoryMapEntryCount;\r
UINTN Index;\r
+ EFI_MEMORY_DESCRIPTOR *Entry;\r
\r
if (mUefiMemoryMap != NULL) {\r
MemoryMap = mUefiMemoryMap;\r
}\r
}\r
\r
+ if (mUefiMemoryAttributesTable != NULL) {\r
+ Entry = (EFI_MEMORY_DESCRIPTOR *)(mUefiMemoryAttributesTable + 1);\r
+ for (Index = 0; Index < mUefiMemoryAttributesTable->NumberOfEntries; Index++) {\r
+ if (Entry->Type == EfiRuntimeServicesCode || Entry->Type == EfiRuntimeServicesData) {\r
+ if ((Entry->Attribute & EFI_MEMORY_RO) != 0) {\r
+ if ((Address >= Entry->PhysicalStart) &&\r
+ (Address < Entry->PhysicalStart + LShiftU64 (Entry->NumberOfPages, EFI_PAGE_SHIFT))) {\r
+ return TRUE;\r
+ }\r
+ Entry = NEXT_MEMORY_DESCRIPTOR (Entry, mUefiMemoryAttributesTable->DescriptorSize);\r
+ }\r
+ }\r
+ }\r
+ }\r
return FALSE;\r
}\r
\r