diff options
author | Jiewen Yao <jiewen.yao@intel.com> | 2018-01-04 11:07:55 +0800 |
---|---|---|
committer | Jiewen Yao <jiewen.yao@intel.com> | 2018-07-26 23:09:13 +0800 |
commit | aa37a8b6542d1226a7446abb3889d9b99ac2370e (patch) | |
tree | be0f7f86fd4ceb3629cbea2fa7e964b1fe85e597 | |
parent | cec67afa49f6878079d1b2bd58046ca817360ba5 (diff) | |
download | edk2-aa37a8b6542d1226a7446abb3889d9b99ac2370e.tar.gz |
MdeModulePkg/DxeCore: UEFI mem attrib table update.
1) MdeModulePkg/DxeCore: Install UEFI mem attrib table at EndOfDxe.
So that the SMM can consume it to set page protection for
the UEFI runtime page with EFI_MEMORY_RO attribute.
2) MdeModulePkg/DxeCore: Not update RtCode in MemAttrTable after EndOfDxe
We want to provide precise info in MemAttribTable
to both OS and SMM, and SMM only gets the info at EndOfDxe.
So we do not update RtCode entry in EndOfDxe.
The impact is that if 3rd part OPROM is runtime, it cannot be executed
at UEFI runtime phase.
Currently, we do not see compatibility issue, because the only runtime
OPROM we found before in UNDI, and UEFI OS will not use UNDI interface
in OS.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
-rw-r--r-- | MdeModulePkg/Core/Dxe/DxeMain.h | 30 | ||||
-rw-r--r-- | MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 3 | ||||
-rw-r--r-- | MdeModulePkg/Core/Dxe/Mem/Page.c | 14 | ||||
-rw-r--r-- | MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c | 130 | ||||
-rw-r--r-- | MdeModulePkg/Core/Dxe/Misc/PropertiesTable.c | 22 |
5 files changed, 158 insertions, 41 deletions
diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index fefe5bec19..8f9fb2186a 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -276,6 +276,8 @@ extern EFI_RUNTIME_SERVICES *gDxeCoreRT; extern EFI_DXE_SERVICES *gDxeCoreDS;
extern EFI_HANDLE gDxeCoreImageHandle;
+extern BOOLEAN gMemoryMapTerminated;
+
extern EFI_DECOMPRESS_PROTOCOL gEfiDecompress;
extern EFI_RUNTIME_ARCH_PROTOCOL *gRuntime;
@@ -1315,24 +1317,6 @@ CoreFreePages ( );
/**
- Frees previous allocated pages.
-
- @param Memory Base address of memory being freed
- @param NumberOfPages The number of pages to free
-
- @retval EFI_NOT_FOUND Could not find the entry that covers the range
- @retval EFI_INVALID_PARAMETER Address not aligned
- @return EFI_SUCCESS -Pages successfully freed.
-
-**/
-EFI_STATUS
-EFIAPI
-CoreInternalFreePages (
- IN EFI_PHYSICAL_ADDRESS Memory,
- IN UINTN NumberOfPages
- );
-
-/**
This function returns a copy of the current memory map. The map is an array of
memory descriptors, each of which describes a contiguous block of memory.
@@ -2902,6 +2886,16 @@ CoreInitializeMemoryAttributesTable ( );
/**
+ Install MemoryAttributesTable on memory allocation.
+
+ @param[in] MemoryType EFI memory type.
+**/
+VOID
+InstallMemoryAttributesTableOnMemoryAllocation (
+ IN EFI_MEMORY_TYPE MemoryType
+ );
+
+/**
Insert image record.
@param RuntimeImage Runtime image information
diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index 0a34711b22..3a209805ba 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -207,6 +207,7 @@ EFI_SYSTEM_TABLE *gDxeCoreST = NULL; EFI_RUNTIME_SERVICES *gDxeCoreRT = &mEfiRuntimeServicesTableTemplate;
EFI_HANDLE gDxeCoreImageHandle = NULL;
+BOOLEAN gMemoryMapTerminated = FALSE;
//
// EFI Decompress Protocol
@@ -745,6 +746,8 @@ CoreExitBootServices ( return Status;
}
+ gMemoryMapTerminated = TRUE;
+
//
// Notify other drivers that we are exiting boot services.
//
diff --git a/MdeModulePkg/Core/Dxe/Mem/Page.c b/MdeModulePkg/Core/Dxe/Mem/Page.c index 9dbb85da7c..68fca010a1 100644 --- a/MdeModulePkg/Core/Dxe/Mem/Page.c +++ b/MdeModulePkg/Core/Dxe/Mem/Page.c @@ -1310,6 +1310,7 @@ CoreAllocatePages ( Status = CoreInternalAllocatePages (Type, MemoryType, NumberOfPages, Memory);
if (!EFI_ERROR (Status)) {
CoreUpdateProfile ((EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0), MemoryProfileActionAllocatePages, MemoryType, EFI_PAGES_TO_SIZE (NumberOfPages), (VOID *) (UINTN) *Memory);
+ InstallMemoryAttributesTableOnMemoryAllocation (MemoryType);
}
return Status;
}
@@ -1329,7 +1330,8 @@ EFI_STATUS EFIAPI
CoreInternalFreePages (
IN EFI_PHYSICAL_ADDRESS Memory,
- IN UINTN NumberOfPages
+ IN UINTN NumberOfPages,
+ OUT EFI_MEMORY_TYPE *MemoryType OPTIONAL
)
{
EFI_STATUS Status;
@@ -1377,6 +1379,10 @@ CoreInternalFreePages ( NumberOfPages += EFI_SIZE_TO_PAGES (Alignment) - 1;
NumberOfPages &= ~(EFI_SIZE_TO_PAGES (Alignment) - 1);
+ if (MemoryType != NULL) {
+ *MemoryType = Entry->Type;
+ }
+
Status = CoreConvertPages (Memory, NumberOfPages, EfiConventionalMemory);
if (EFI_ERROR (Status)) {
@@ -1406,11 +1412,13 @@ CoreFreePages ( IN UINTN NumberOfPages
)
{
- EFI_STATUS Status;
+ EFI_STATUS Status;
+ EFI_MEMORY_TYPE MemoryType;
- Status = CoreInternalFreePages (Memory, NumberOfPages);
+ Status = CoreInternalFreePages (Memory, NumberOfPages, &MemoryType);
if (!EFI_ERROR (Status)) {
CoreUpdateProfile ((EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0), MemoryProfileActionFreePages, (EFI_MEMORY_TYPE) 0, EFI_PAGES_TO_SIZE (NumberOfPages), (VOID *) (UINTN) Memory);
+ InstallMemoryAttributesTableOnMemoryAllocation (MemoryType);
}
return Status;
}
diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c index 416ed3dca8..5de27f9893 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c @@ -62,7 +62,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/
EFI_STATUS
EFIAPI
-CoreGetMemoryMapPropertiesTable (
+CoreGetMemoryMapWithSeparatedImageSection (
IN OUT UINTN *MemoryMapSize,
IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
OUT UINTN *MapKey,
@@ -71,18 +71,16 @@ CoreGetMemoryMapPropertiesTable ( );
extern EFI_PROPERTIES_TABLE mPropertiesTable;
+EFI_MEMORY_ATTRIBUTES_TABLE *mMemoryAttributesTable = NULL;
+BOOLEAN mMemoryAttributesTableReadyToBoot = FALSE;
/**
Install MemoryAttributesTable.
- @param[in] Event The Event this notify function registered to.
- @param[in] Context Pointer to the context data registered to the Event.
**/
VOID
-EFIAPI
InstallMemoryAttributesTable (
- EFI_EVENT Event,
- VOID *Context
+ VOID
)
{
UINTN MemoryMapSize;
@@ -97,15 +95,32 @@ InstallMemoryAttributesTable ( EFI_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable;
EFI_MEMORY_DESCRIPTOR *MemoryAttributesEntry;
+ if (gMemoryMapTerminated) {
+ //
+ // Directly return after MemoryMap terminated.
+ //
+ return;
+ }
+
if ((mPropertiesTable.MemoryProtectionAttribute & EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) == 0) {
DEBUG ((EFI_D_VERBOSE, "MemoryProtectionAttribute NON_EXECUTABLE_PE_DATA is not set, "));
DEBUG ((EFI_D_VERBOSE, "because Runtime Driver Section Alignment is not %dK.\n", EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT >> 10));
return ;
}
+ if (mMemoryAttributesTable == NULL) {
+ //
+ // InstallConfigurationTable here to occupy one entry for MemoryAttributesTable
+ // before GetMemoryMap below, as InstallConfigurationTable may allocate runtime
+ // memory for the new entry.
+ //
+ Status = gBS->InstallConfigurationTable (&gEfiMemoryAttributesTableGuid, (VOID *) (UINTN) MAX_ADDRESS);
+ ASSERT_EFI_ERROR (Status);
+ }
+
MemoryMapSize = 0;
MemoryMap = NULL;
- Status = CoreGetMemoryMapPropertiesTable (
+ Status = CoreGetMemoryMapWithSeparatedImageSection (
&MemoryMapSize,
MemoryMap,
&MapKey,
@@ -118,7 +133,7 @@ InstallMemoryAttributesTable ( MemoryMap = AllocatePool (MemoryMapSize);
ASSERT (MemoryMap != NULL);
- Status = CoreGetMemoryMapPropertiesTable (
+ Status = CoreGetMemoryMapWithSeparatedImageSection (
&MemoryMapSize,
MemoryMap,
&MapKey,
@@ -174,9 +189,72 @@ InstallMemoryAttributesTable ( }
MemoryMap = NEXT_MEMORY_DESCRIPTOR(MemoryMap, DescriptorSize);
}
+ MemoryMap = MemoryMapStart;
+ FreePool (MemoryMap);
+ //
+ // Update configuratoin table for MemoryAttributesTable.
+ //
Status = gBS->InstallConfigurationTable (&gEfiMemoryAttributesTableGuid, MemoryAttributesTable);
ASSERT_EFI_ERROR (Status);
+
+ if (mMemoryAttributesTable != NULL) {
+ FreePool (mMemoryAttributesTable);
+ }
+ mMemoryAttributesTable = MemoryAttributesTable;
+}
+
+/**
+ Install MemoryAttributesTable on memory allocation.
+
+ @param[in] MemoryType EFI memory type.
+**/
+VOID
+InstallMemoryAttributesTableOnMemoryAllocation (
+ IN EFI_MEMORY_TYPE MemoryType
+ )
+{
+ //
+ // Install MemoryAttributesTable after ReadyToBoot on runtime memory allocation.
+ //
+ if (mMemoryAttributesTableReadyToBoot &&
+ ((MemoryType == EfiRuntimeServicesCode) || (MemoryType == EfiRuntimeServicesData))) {
+ InstallMemoryAttributesTable ();
+ }
+}
+
+/**
+ Install MemoryAttributesTable on ReadyToBoot.
+
+ @param[in] Event The Event this notify function registered to.
+ @param[in] Context Pointer to the context data registered to the Event.
+**/
+VOID
+EFIAPI
+InstallMemoryAttributesTableOnReadyToBoot (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ InstallMemoryAttributesTable ();
+ mMemoryAttributesTableReadyToBoot = TRUE;
+}
+
+/**
+ Install initial MemoryAttributesTable on EndOfDxe.
+ Then SMM can consume this information.
+
+ @param[in] Event The Event this notify function registered to.
+ @param[in] Context Pointer to the context data registered to the Event.
+**/
+VOID
+EFIAPI
+InstallMemoryAttributesTableOnEndOfDxe (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ InstallMemoryAttributesTable ();
}
/**
@@ -190,19 +268,35 @@ CoreInitializeMemoryAttributesTable ( {
EFI_STATUS Status;
EFI_EVENT ReadyToBootEvent;
+ EFI_EVENT EndOfDxeEvent;
//
- // Construct the table at ReadyToBoot, because this should be
- // last point to allocate RuntimeCode/RuntimeData.
+ // Construct the table at ReadyToBoot.
//
- Status = gBS->CreateEventEx (
- EVT_NOTIFY_SIGNAL,
- TPL_NOTIFY,
- InstallMemoryAttributesTable,
- NULL,
- &gEfiEventReadyToBootGuid,
- &ReadyToBootEvent
- );
+ Status = CoreCreateEventInternal (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ InstallMemoryAttributesTableOnReadyToBoot,
+ NULL,
+ &gEfiEventReadyToBootGuid,
+ &ReadyToBootEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Construct the initial table at EndOfDxe,
+ // then SMM can consume this information.
+ // Use TPL_NOTIFY here, as such SMM code (TPL_CALLBACK)
+ // can run after it.
+ //
+ Status = CoreCreateEventInternal (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ InstallMemoryAttributesTableOnEndOfDxe,
+ NULL,
+ &gEfiEndOfDxeEventGroupGuid,
+ &EndOfDxeEvent
+ );
ASSERT_EFI_ERROR (Status);
return ;
}
diff --git a/MdeModulePkg/Core/Dxe/Misc/PropertiesTable.c b/MdeModulePkg/Core/Dxe/Misc/PropertiesTable.c index 06f3451b4e..5e9fda7c80 100644 --- a/MdeModulePkg/Core/Dxe/Misc/PropertiesTable.c +++ b/MdeModulePkg/Core/Dxe/Misc/PropertiesTable.c @@ -82,6 +82,8 @@ EFI_LOCK mPropertiesTableLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTI BOOLEAN mPropertiesTableEnable;
+BOOLEAN mPropertiesTableEndOfDxe = FALSE;
+
//
// Below functions are for MemoryMap
//
@@ -596,6 +598,11 @@ SplitRecord ( TempRecord.NumberOfPages = EfiSizeToPages (PhysicalEnd - PhysicalStart);
} while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd));
+ //
+ // The logic in function SplitTable() ensures that TotalNewRecordCount will not be zero if the
+ // code reaches here.
+ //
+ ASSERT (TotalNewRecordCount != 0);
return TotalNewRecordCount - 1;
}
@@ -758,7 +765,7 @@ SplitTable ( **/
EFI_STATUS
EFIAPI
-CoreGetMemoryMapPropertiesTable (
+CoreGetMemoryMapWithSeparatedImageSection (
IN OUT UINTN *MemoryMapSize,
IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
OUT UINTN *MapKey,
@@ -1097,6 +1104,11 @@ InsertImageRecord ( DEBUG ((EFI_D_VERBOSE, "InsertImageRecord - 0x%x\n", RuntimeImage));
DEBUG ((EFI_D_VERBOSE, "InsertImageRecord - 0x%016lx - 0x%016lx\n", (EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase, RuntimeImage->ImageSize));
+ if (mPropertiesTableEndOfDxe) {
+ DEBUG ((DEBUG_INFO, "Do not insert runtime image record after EndOfDxe\n"));
+ return ;
+ }
+
ImageRecord = AllocatePool (sizeof(*ImageRecord));
if (ImageRecord == NULL) {
return ;
@@ -1314,6 +1326,11 @@ RemoveImageRecord ( DEBUG ((EFI_D_VERBOSE, "RemoveImageRecord - 0x%x\n", RuntimeImage));
DEBUG ((EFI_D_VERBOSE, "RemoveImageRecord - 0x%016lx - 0x%016lx\n", (EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase, RuntimeImage->ImageSize));
+ if (mPropertiesTableEndOfDxe) {
+ DEBUG ((DEBUG_INFO, "Do not remove runtime image record after EndOfDxe\n"));
+ return ;
+ }
+
ImageRecord = FindImageRecord ((EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase, RuntimeImage->ImageSize);
if (ImageRecord == NULL) {
DEBUG ((EFI_D_ERROR, "!!!!!!!! ImageRecord not found !!!!!!!!\n"));
@@ -1351,6 +1368,7 @@ InstallPropertiesTable ( VOID *Context
)
{
+ mPropertiesTableEndOfDxe = TRUE;
if (PcdGetBool (PcdPropertiesTableEnable)) {
EFI_STATUS Status;
@@ -1364,7 +1382,7 @@ InstallPropertiesTable ( return ;
}
- gBS->GetMemoryMap = CoreGetMemoryMapPropertiesTable;
+ gBS->GetMemoryMap = CoreGetMemoryMapWithSeparatedImageSection;
gBS->Hdr.CRC32 = 0;
gBS->CalculateCrc32 ((UINT8 *)gBS, gBS->Hdr.HeaderSize, &gBS->Hdr.CRC32);
|