]> git.proxmox.com Git - mirror_edk2.git/commitdiff
StandaloneMmPkg/StandaloneMmCoreEntryPoint: relocate StMM core on the fly
authorArd Biesheuvel <ard.biesheuvel@arm.com>
Tue, 9 Jun 2020 08:34:27 +0000 (10:34 +0200)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Tue, 16 Jun 2020 16:15:00 +0000 (16:15 +0000)
Apply PE/COFF fixups when starting up the standalone MM core, so that
it can execute at any address regardless of the link time address.

Note that this requires the PE/COFF image to be emitted with its
relocation section preserved. Special care is taken to ensure that
TE images are dealt with correctly as well.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
Acked-by: Jiewen Yao <Jiewen.yao@intel.com>
Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>
Tested-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
StandaloneMmPkg/Include/Library/AArch64/StandaloneMmCoreEntryPoint.h
StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/SetPermissions.c
StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/StandaloneMmCoreEntryPoint.c

index 494bcf3dc28f741a8917c880a359d64fa3912755..0f9a032404582fd59e3d4e2bf2884b1077b78d5c 100644 (file)
@@ -71,6 +71,7 @@ typedef RETURN_STATUS (*REGION_PERMISSION_UPDATE_FUNC) (
   and make further progress in the boot process.\r
 \r
   @param  ImageContext           Pointer to PE/COFF image context\r
+  @param  ImageBase              Base of image in memory\r
   @param  SectionHeaderOffset    Offset of PE/COFF image section header\r
   @param  NumberOfSections       Number of Sections\r
   @param  TextUpdater            Function to change code permissions\r
@@ -82,6 +83,7 @@ EFI_STATUS
 EFIAPI\r
 UpdateMmFoundationPeCoffPermissions (\r
   IN  CONST PE_COFF_LOADER_IMAGE_CONTEXT      *ImageContext,\r
+  IN  EFI_PHYSICAL_ADDRESS                    ImageBase,\r
   IN  UINT32                                  SectionHeaderOffset,\r
   IN  CONST  UINT16                           NumberOfSections,\r
   IN  REGION_PERMISSION_UPDATE_FUNC           TextUpdater,\r
@@ -98,6 +100,7 @@ UpdateMmFoundationPeCoffPermissions (
 \r
   @param  TeData                 Pointer to PE/COFF image data\r
   @param  ImageContext           Pointer to PE/COFF image context\r
+  @param  ImageBase              Pointer to ImageBase variable\r
   @param  SectionHeaderOffset    Offset of PE/COFF image section header\r
   @param  NumberOfSections       Number of Sections\r
 \r
@@ -107,6 +110,7 @@ EFIAPI
 GetStandaloneMmCorePeCoffSections (\r
   IN        VOID                            *TeData,\r
   IN  OUT   PE_COFF_LOADER_IMAGE_CONTEXT    *ImageContext,\r
+      OUT   EFI_PHYSICAL_ADDRESS            *ImageBase,\r
   IN  OUT   UINT32                          *SectionHeaderOffset,\r
   IN  OUT   UINT16                          *NumberOfSections\r
   );\r
index 00f49c9d05583c99ca6490191858f8105f7c39fa..bf9650d546291f6d449249d4f0577278a93adb24 100644 (file)
@@ -29,6 +29,7 @@ EFI_STATUS
 EFIAPI\r
 UpdateMmFoundationPeCoffPermissions (\r
   IN  CONST PE_COFF_LOADER_IMAGE_CONTEXT      *ImageContext,\r
+  IN  EFI_PHYSICAL_ADDRESS                    ImageBase,\r
   IN  UINT32                                  SectionHeaderOffset,\r
   IN  CONST  UINT16                           NumberOfSections,\r
   IN  REGION_PERMISSION_UPDATE_FUNC           TextUpdater,\r
@@ -87,7 +88,7 @@ UpdateMmFoundationPeCoffPermissions (
     // if it is a writeable section then mark it appropriately as well.\r
     //\r
     if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_MEM_EXECUTE) == 0) {\r
-      Base = ImageContext->ImageAddress + SectionHeader.VirtualAddress;\r
+      Base = ImageBase + SectionHeader.VirtualAddress;\r
 \r
       TextUpdater (Base, SectionHeader.Misc.VirtualSize);\r
 \r
@@ -153,6 +154,7 @@ STATIC
 EFI_STATUS\r
 GetPeCoffSectionInformation (\r
   IN  OUT   PE_COFF_LOADER_IMAGE_CONTEXT      *ImageContext,\r
+      OUT   EFI_PHYSICAL_ADDRESS              *ImageBase,\r
       OUT   UINT32                            *SectionHeaderOffset,\r
       OUT   UINT16                            *NumberOfSections\r
   )\r
@@ -212,6 +214,7 @@ GetPeCoffSectionInformation (
     return Status;\r
   }\r
 \r
+  *ImageBase = ImageContext->ImageAddress;\r
   if (!ImageContext->IsTeImage) {\r
     ASSERT (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE);\r
 \r
@@ -232,7 +235,7 @@ GetPeCoffSectionInformation (
   } else {\r
     *SectionHeaderOffset = (UINTN)(sizeof (EFI_TE_IMAGE_HEADER));\r
     *NumberOfSections = Hdr.Te->NumberOfSections;\r
-    ImageContext->ImageAddress -= (UINT32)Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER);\r
+    *ImageBase -= (UINT32)Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER);\r
   }\r
   return RETURN_SUCCESS;\r
 }\r
@@ -242,6 +245,7 @@ EFIAPI
 GetStandaloneMmCorePeCoffSections (\r
   IN        VOID                            *TeData,\r
   IN  OUT   PE_COFF_LOADER_IMAGE_CONTEXT    *ImageContext,\r
+      OUT   EFI_PHYSICAL_ADDRESS            *ImageBase,\r
   IN  OUT   UINT32                          *SectionHeaderOffset,\r
   IN  OUT   UINT16                          *NumberOfSections\r
   )\r
@@ -255,7 +259,8 @@ GetStandaloneMmCorePeCoffSections (
 \r
   DEBUG ((DEBUG_INFO, "Found Standalone MM PE data - 0x%x\n", TeData));\r
 \r
-  Status = GetPeCoffSectionInformation (ImageContext, SectionHeaderOffset, NumberOfSections);\r
+  Status = GetPeCoffSectionInformation (ImageContext, ImageBase,\r
+             SectionHeaderOffset, NumberOfSections);\r
   if (EFI_ERROR (Status)) {\r
     DEBUG ((DEBUG_ERROR, "Unable to locate Standalone MM Core PE-COFF Section information - %r\n", Status));\r
     return Status;\r
index 20723385113f90dd20ad83c8e286a17a3aab72a2..9cecfa667b905c975ddd348513c51fc8a5955718 100644 (file)
@@ -225,6 +225,7 @@ _ModuleEntryPoint (
   VOID                                    *HobStart;\r
   VOID                                    *TeData;\r
   UINTN                                   TeDataSize;\r
+  EFI_PHYSICAL_ADDRESS                    ImageBase;\r
 \r
   // Get Secure Partition Manager Version Information\r
   Status = GetSpmVersion ();\r
@@ -253,6 +254,7 @@ _ModuleEntryPoint (
   Status = GetStandaloneMmCorePeCoffSections (\r
              TeData,\r
              &ImageContext,\r
+             &ImageBase,\r
              &SectionHeaderOffset,\r
              &NumberOfSections\r
              );\r
@@ -261,10 +263,21 @@ _ModuleEntryPoint (
     goto finish;\r
   }\r
 \r
+  //\r
+  // ImageBase may deviate from ImageContext.ImageAddress if we are dealing\r
+  // with a TE image, in which case the latter points to the actual offset\r
+  // of the image, whereas ImageBase refers to the address where the image\r
+  // would start if the stripped PE headers were still in place. In either\r
+  // case, we need to fix up ImageBase so it refers to the actual current\r
+  // load address.\r
+  //\r
+  ImageBase += (UINTN)TeData - ImageContext.ImageAddress;\r
+\r
   // Update the memory access permissions of individual sections in the\r
   // Standalone MM core module\r
   Status = UpdateMmFoundationPeCoffPermissions (\r
              &ImageContext,\r
+             ImageBase,\r
              SectionHeaderOffset,\r
              NumberOfSections,\r
              ArmSetMemoryRegionNoExec,\r
@@ -276,6 +289,15 @@ _ModuleEntryPoint (
     goto finish;\r
   }\r
 \r
+  if (ImageContext.ImageAddress != (UINTN)TeData) {\r
+    ImageContext.ImageAddress = (UINTN)TeData;\r
+    ArmSetMemoryRegionNoExec (ImageBase, SIZE_4KB);\r
+    ArmClearMemoryRegionReadOnly (ImageBase, SIZE_4KB);\r
+\r
+    Status = PeCoffLoaderRelocateImage (&ImageContext);\r
+    ASSERT_EFI_ERROR (Status);\r
+  }\r
+\r
   //\r
   // Create Hoblist based upon boot information passed by privileged software\r
   //\r