1. is it possible that a PE image sits in the right location but the SectionAlignment is larger than FileAlignment so each section still needs to be copied to the aligned memory location?
2. PeCoffLoaderRelocateImage() might not be called for XIP > -----Original Message----- > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Ard > Biesheuvel > Sent: Monday, May 29, 2023 6:17 PM > To: devel@edk2.groups.io > Cc: Ard Biesheuvel <a...@kernel.org>; Ni, Ray <ray...@intel.com>; Yao, Jiewen > <jiewen....@intel.com>; Gerd Hoffmann <kra...@redhat.com>; Taylor Beebe > <t...@taylorbeebe.com>; Oliver Smith-Denny <o...@smith-denny.com>; Bi, Dandan > <dandan...@intel.com>; Gao, Liming <gaolim...@byosoft.com.cn>; Kinney, > Michael D <michael.d.kin...@intel.com>; Leif Lindholm > <quic_llind...@quicinc.com>; Michael Kubacki <mikub...@linux.microsoft.com> > Subject: [edk2-devel] [RFC PATCH 08/11] MdeModulePkg/DxeIpl: Relocate and > remap XIP capable DXE drivers > > Before handing over to the DXE core, iterate over all known FFS files > and find the ones that can execute in place. These files are then > relocated in place and mapped with restricted permissions, allowing the > DXE core to dispatch them without the need to perform any manipulation > of the file contents or the page table permissions. > > Signed-off-by: Ard Biesheuvel <a...@kernel.org> > --- > MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 1 + > MdeModulePkg/Core/DxeIplPeim/DxeLoad.c | 196 ++++++++++++++++++++ > 2 files changed, 197 insertions(+) > > diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf > b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf > index f1990eac77607854..60112100df78b396 100644 > --- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf > +++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf > @@ -65,6 +65,7 @@ [LibraryClasses] > PeimEntryPoint > > DebugLib > > DebugAgentLib > > + PeCoffLib > > PeiServicesTablePointerLib > > PerformanceLib > > > > diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c > b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c > index 2c19f1a507baf34a..1f20db1faffbd1d2 100644 > --- a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c > +++ b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c > @@ -10,6 +10,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent > > > #include "DxeIpl.h" > > > > +#include <Library/PeCoffLib.h> > > +#include <Ppi/MemoryAttribute.h> > > + > > // > > // Module Globals used in the DXE to PEI hand off > > // These must be module globals, so the stack can be switched > > @@ -228,6 +231,197 @@ ValidateMemoryTypeInfoVariable ( > return TRUE; > > } > > > > +/** > > + Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF > file. > > + The function is used for XIP code to have optimized memory copy. > > + > > + @param FileHandle The handle to the PE/COFF file > > + @param FileOffset The offset, in bytes, into the file to read > > + @param ReadSize The number of bytes to read from the file starting > at > FileOffset > > + @param Buffer A pointer to the buffer to read the data into. > > + > > + @return EFI_SUCCESS ReadSize bytes of data were read into Buffer from > the > > + PE/COFF file starting at FileOffset > > + > > +**/ > > +STATIC > > +EFI_STATUS > > +EFIAPI > > +PeiImageRead ( > > + IN VOID *FileHandle, > > + IN UINTN FileOffset, > > + IN UINTN *ReadSize, > > + OUT VOID *Buffer > > + ) > > +{ > > + CHAR8 *Destination8; > > + CHAR8 *Source8; > > + > > + Destination8 = Buffer; > > + Source8 = (CHAR8 *)((UINTN)FileHandle + FileOffset); > > + if (Destination8 != Source8) { > > + CopyMem (Destination8, Source8, *ReadSize); > > + } > > + > > + return EFI_SUCCESS; > > +} > > + > > +STATIC > > +VOID > > +RemapImage ( > > + IN EDKII_MEMORY_ATTRIBUTE_PPI *MemoryPpi, > > + IN CONST PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext > > + ) > > +{ > > + EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; > > + EFI_IMAGE_SECTION_HEADER *Section; > > + PHYSICAL_ADDRESS SectionAddress; > > + EFI_STATUS Status; > > + UINT64 Permissions; > > + UINTN Index; > > + > > + if (MemoryPpi == NULL) { > > + return; > > + } > > + > > + Hdr.Union = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((UINT8 > *)ImageContext->Handle + > > + > ImageContext->PeCoffHeaderOffset); > > + ASSERT (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE); > > + > > + Section = (EFI_IMAGE_SECTION_HEADER *)((UINT8 *)Hdr.Union + sizeof > (UINT32) + > > + sizeof (EFI_IMAGE_FILE_HEADER) + > > + > Hdr.Pe32->FileHeader.SizeOfOptionalHeader > > + ); > > + > > + for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) { > > + SectionAddress = ImageContext->ImageAddress + > Section[Index].VirtualAddress; > > + Permissions = 0; > > + > > + if ((Section[Index].Characteristics & EFI_IMAGE_SCN_MEM_WRITE) == 0) { > > + Permissions |= EFI_MEMORY_RO; > > + } > > + > > + if ((Section[Index].Characteristics & EFI_IMAGE_SCN_MEM_EXECUTE) == 0) { > > + Permissions |= EFI_MEMORY_XP; > > + } > > + > > + Status = MemoryPpi->SetPermissions ( > > + MemoryPpi, > > + SectionAddress, > > + Section[Index].Misc.VirtualSize, > > + Permissions, > > + Permissions ^ EFI_MEMORY_RO ^ EFI_MEMORY_XP > > + ); > > + ASSERT_EFI_ERROR (Status); > > + } > > +} > > + > > +STATIC > > +VOID > > +RelocateAndRemapDriversInPlace ( > > + VOID > > + ) > > +{ > > + EFI_STATUS Status; > > + UINTN Instance; > > + EFI_PEI_FV_HANDLE VolumeHandle; > > + EFI_PEI_FILE_HANDLE FileHandle; > > + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; > > + UINT32 AuthenticationState; > > + EDKII_MEMORY_ATTRIBUTE_PPI *MemoryPpi; > > + > > + MemoryPpi = NULL; > > + PeiServicesLocatePpi (&gEdkiiMemoryAttributePpiGuid, 0, NULL, (VOID > **)&MemoryPpi); > > + > > + Instance = 0; > > + do { > > + // > > + // Traverse all firmware volume instances > > + // > > + Status = PeiServicesFfsFindNextVolume (Instance, &VolumeHandle); > > + if (Status == EFI_NOT_FOUND) { > > + return; > > + } > > + > > + ASSERT_EFI_ERROR (Status); > > + > > + FileHandle = NULL; > > + do { > > + Status = PeiServicesFfsFindNextFile ( > > + EFI_FV_FILETYPE_DRIVER, > > + VolumeHandle, > > + &FileHandle); > > + if (Status == EFI_NOT_FOUND) { > > + break; > > + } > > + > > + ASSERT_EFI_ERROR (Status); > > + > > + ZeroMem (&ImageContext, sizeof (ImageContext)); > > + > > + Status = PeiServicesFfsFindSectionData3 ( > > + EFI_SECTION_PE32, > > + 0, > > + FileHandle, > > + &ImageContext.Handle, > > + &AuthenticationState > > + ); > > + if (Status == EFI_NOT_FOUND) { > > + continue; > > + } > > + > > + ASSERT_EFI_ERROR (Status); > > + > > + ImageContext.ImageRead = PeiImageRead; > > + Status = PeCoffLoaderGetImageInfo (&ImageContext); > > + if (EFI_ERROR (Status)) { > > + ASSERT_EFI_ERROR (Status); > > + continue; > > + } > > + > > + ImageContext.ImageAddress = > (PHYSICAL_ADDRESS)(UINTN)ImageContext.Handle; > > + if ((ImageContext.ImageAddress & (ImageContext.SectionAlignment - 1)) > != > 0) { > > + DEBUG ((DEBUG_VERBOSE, "%a: skip PE image at %p\n", __func__, > ImageContext.Handle)); > > + continue; > > + } > > + > > + DEBUG (( > > + DEBUG_INFO, > > + "%a: relocate PE image at %p for execution in place\n", > > + __func__, > > + ImageContext.Handle > > + )); > > + > > + // > > + // 'Load' the image in-place - this just performs a sanity check on > > + // the PE metadata but does not actually move any data > > + // > > + Status = PeCoffLoaderLoadImage (&ImageContext); > > + if (EFI_ERROR (Status)) { > > + ASSERT_EFI_ERROR (Status); > > + continue; > > + } > > + > > + // > > + // Relocate this driver in place > > + // > > + Status = PeCoffLoaderRelocateImage (&ImageContext); > > + if (EFI_ERROR (Status)) { > > + ASSERT_EFI_ERROR (Status); > > + continue; > > + } > > + > > + // > > + // Apply section permissions to the page tables > > + // > > + RemapImage (MemoryPpi, &ImageContext); > > + > > + } while (TRUE); > > + > > + Instance++; > > + } while (TRUE); > > +} > > + > > /** > > Main entry point to last PEIM. > > > > @@ -436,6 +630,8 @@ DxeLoadCore ( > DxeCoreEntryPoint > > ); > > > > + RelocateAndRemapDriversInPlace (); > > + > > // > > // Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT > > // > > -- > 2.39.2 > > > > -=-=-=-=-=-= > Groups.io Links: You receive all messages sent to this group. > View/Reply Online (#105370): https://edk2.groups.io/g/devel/message/105370 > Mute This Topic: https://groups.io/mt/99197142/1712937 > Group Owner: devel+ow...@edk2.groups.io > Unsubscribe: https://edk2.groups.io/g/devel/unsub [ray...@intel.com] > -=-=-=-=-=-= > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#105414): https://edk2.groups.io/g/devel/message/105414 Mute This Topic: https://groups.io/mt/99197142/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/leave/9847357/21656/1706620634/xyzzy [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-