From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by mx.groups.io with SMTP id smtpd.web11.46679.1685355452933148710 for ; Mon, 29 May 2023 03:17:33 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=scsVsLwh; spf=pass (domain: kernel.org, ip: 139.178.84.217, mailfrom: ardb@kernel.org) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 6BB5560AF5; Mon, 29 May 2023 10:17:32 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 71213C433EF; Mon, 29 May 2023 10:17:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1685355451; bh=s/xxL4DwKKtbksErG4B0SdbxJjmdF5LR0eRG9s1a1VY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=scsVsLwhFtFKhsuK0hcZ8b9TkDg4Rc1xspKkA+2OA9GPsfCls5AmYnsm3EENDlgM8 9TwYzZsXNtTuPxg6Kye9TO32YygLTqQd5hGWQcAWerYHBeJ3VDA96IlrBjaG8xWTUZ 3JvdXTYRCUiwCvJ3v7OvJzbZJljJYJ28IOsPo9WBwuFS7oO9M1nt+oGGgn0dBHulxO rBIPlK+8luoyjrQCWHZiRs3VaGyWJQ4KPMFnZdo18gOrQynv6zlIvLL5yQVtS4M/Bu U1exgtHeXwObDm9KAo1f6zZb/Y9A4zlUwKKroQ93mxyDj7h7ZWXSZoT05TmHbdiT36 xp/KrCoESrfgw== From: "Ard Biesheuvel" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Ray Ni , Jiewen Yao , Gerd Hoffmann , Taylor Beebe , Oliver Smith-Denny , Dandan Bi , Liming Gao , "Kinney, Michael D" , Leif Lindholm , Michael Kubacki Subject: [RFC PATCH 05/11] MdeModulePkg/DxeCore: Use memory mapped FV protocol to avoid image copy Date: Mon, 29 May 2023 12:16:59 +0200 Message-Id: <20230529101705.2476949-6-ardb@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230529101705.2476949-1-ardb@kernel.org> References: <20230529101705.2476949-1-ardb@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Use the memory mapped FV protocol to obtain the existing location in memory and the size of an image being loaded from a firmware volume. This removes the need to do a memcopy of the file data. Signed-off-by: Ard Biesheuvel --- MdeModulePkg/Core/Dxe/DxeMain.h | 1 + MdeModulePkg/Core/Dxe/DxeMain.inf | 3 + MdeModulePkg/Core/Dxe/Image/Image.c | 111 +++++++++++++++++--- MdeModulePkg/Include/Protocol/MemoryMappedFv.h | 59 +++++++++++ MdeModulePkg/MdeModulePkg.dec | 3 + 5 files changed, 163 insertions(+), 14 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMai= n.h index 43daa037be441150..a695b457c79b65bb 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -45,6 +45,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include =0D #include =0D #include =0D +#include =0D #include =0D #include =0D #include =0D diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeM= ain.inf index 35d5bf0dee6f7f3f..a7175cb364b9b5de 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -153,6 +153,9 @@ [Protocols] gEfiLoadedImageDevicePathProtocolGuid ## PRODUCES=0D gEfiHiiPackageListProtocolGuid ## SOMETIMES_PRODUCES=0D gEfiSmmBase2ProtocolGuid ## SOMETIMES_CONSUMES=0D + ## PRODUCES=0D + ## CONSUMES=0D + gEdkiiMemoryMappedFvProtocolGuid=0D gEdkiiPeCoffImageEmulatorProtocolGuid ## SOMETIMES_CONSUMES=0D =0D # Arch Protocols=0D diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Im= age/Image.c index f30e369370a09609..3dfab4829b3ca17f 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1043,6 +1043,76 @@ CoreUnloadAndCloseImage ( CoreFreePool (Image);=0D }=0D =0D +/**=0D + Get the image file data and size directly from a memory mapped FV=0D +=0D + If FilePath is NULL, then NULL is returned.=0D + If FileSize is NULL, then NULL is returned.=0D + If AuthenticationStatus is NULL, then NULL is returned.=0D +=0D + @param[in] FvHandle The firmware volume handle=0D + @param[in] FilePath The pointer to the device path of = the file=0D + that is abstracted to the file buf= fer.=0D + @param[out] FileSize The pointer to the size of the abs= tracted=0D + file buffer.=0D + @param[out] AuthenticationStatus Pointer to the authentication stat= us.=0D +=0D + @retval NULL FilePath is NULL, or FileSize is NULL, or AuthenticationS= tatus=0D + is NULL, or the file is not memory mapped=0D + @retval other The abstracted file buffer.=0D +**/=0D +STATIC=0D +VOID *=0D +GetFileFromMemoryMappedFv (=0D + IN EFI_HANDLE FvHandle,=0D + IN CONST EFI_DEVICE_PATH_PROTOCOL *FilePath,=0D + OUT UINTN *FileSize,=0D + OUT UINT32 *AuthenticationStatus=0D + )=0D +{=0D + EDKII_MEMORY_MAPPED_FV_PROTOCOL *MemMappedFv;=0D + CONST EFI_GUID *NameGuid;=0D + EFI_PHYSICAL_ADDRESS Address;=0D + EFI_STATUS Status;=0D +=0D + if ((FilePath =3D=3D NULL) ||=0D + (FileSize =3D=3D NULL) ||=0D + (AuthenticationStatus =3D=3D NULL))=0D + {=0D + return NULL;=0D + }=0D +=0D + NameGuid =3D EfiGetNameGuidFromFwVolDevicePathNode (=0D + (CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)FilePath);=0D + if (NameGuid =3D=3D NULL) {=0D + return NULL;=0D + }=0D +=0D + Status =3D gBS->HandleProtocol (=0D + FvHandle,=0D + &gEdkiiMemoryMappedFvProtocolGuid,=0D + (VOID **)&MemMappedFv=0D + );=0D + if (EFI_ERROR (Status)) {=0D + ASSERT (Status =3D=3D EFI_UNSUPPORTED);=0D + return NULL;=0D + }=0D +=0D + Status =3D MemMappedFv->GetLocationAndSize (=0D + MemMappedFv,=0D + NameGuid,=0D + EFI_SECTION_PE32,=0D + &Address,=0D + FileSize,=0D + AuthenticationStatus=0D + );=0D + if (EFI_ERROR (Status) || (Address > (MAX_ADDRESS - *FileSize))) {=0D + return NULL;=0D + }=0D +=0D + return (VOID *)(UINTN)Address;=0D +}=0D +=0D /**=0D Loads an EFI image into memory and returns a handle to the image.=0D =0D @@ -1164,6 +1234,16 @@ CoreLoadImageCommon ( Status =3D CoreLocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &Ha= ndleFilePath, &DeviceHandle);=0D if (!EFI_ERROR (Status)) {=0D ImageIsFromFv =3D TRUE;=0D +=0D + //=0D + // If possible, use the memory mapped file image directly, rather th= an copying it into a buffer=0D + //=0D + FHand.Source =3D GetFileFromMemoryMappedFv (=0D + DeviceHandle,=0D + HandleFilePath,=0D + &FHand.SourceSize,=0D + &AuthenticationStatus=0D + );=0D } else {=0D HandleFilePath =3D FilePath;=0D Status =3D CoreLocateDevicePath (&gEfiSimpleFileSystemProtoc= olGuid, &HandleFilePath, &DeviceHandle);=0D @@ -1187,21 +1267,24 @@ CoreLoadImageCommon ( //=0D // Get the source file buffer by its device path.=0D //=0D - FHand.Source =3D GetFileBufferByFilePath (=0D - BootPolicy,=0D - FilePath,=0D - &FHand.SourceSize,=0D - &AuthenticationStatus=0D - );=0D if (FHand.Source =3D=3D NULL) {=0D - Status =3D EFI_NOT_FOUND;=0D - } else {=0D - FHand.FreeBuffer =3D TRUE;=0D - if (ImageIsFromLoadFile) {=0D - //=0D - // LoadFile () may cause the device path of the Handle be updated.= =0D - //=0D - OriginalFilePath =3D AppendDevicePath (DevicePathFromHandle (Devic= eHandle), Node);=0D + FHand.Source =3D GetFileBufferByFilePath (=0D + BootPolicy,=0D + FilePath,=0D + &FHand.SourceSize,=0D + &AuthenticationStatus=0D + );=0D +=0D + if (FHand.Source =3D=3D NULL) {=0D + Status =3D EFI_NOT_FOUND;=0D + } else {=0D + FHand.FreeBuffer =3D TRUE;=0D + if (ImageIsFromLoadFile) {=0D + //=0D + // LoadFile () may cause the device path of the Handle be update= d.=0D + //=0D + OriginalFilePath =3D AppendDevicePath (DevicePathFromHandle (Dev= iceHandle), Node);=0D + }=0D }=0D }=0D }=0D diff --git a/MdeModulePkg/Include/Protocol/MemoryMappedFv.h b/MdeModulePkg/= Include/Protocol/MemoryMappedFv.h new file mode 100644 index 0000000000000000..821009122113a658 --- /dev/null +++ b/MdeModulePkg/Include/Protocol/MemoryMappedFv.h @@ -0,0 +1,59 @@ +/** @file=0D + Protocol to obtain information about files in memory mapped firmware vol= umes=0D +=0D + Copyright (c) 2023, Google LLC. All rights reserved.
=0D +=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#ifndef EDKII_MEMORY_MAPPED_FV_H_=0D +#define EDKII_MEMORY_MAPPED_FV_H_=0D +=0D +#define EDKII_MEMORY_MAPPED_FV_PROTOCOL_GUID \=0D + { 0xb9bfa973, 0x5384, 0x441e, { 0xa4, 0xe7, 0x20, 0xe6, 0x5d, 0xaf, 0x2e= , 0x0f } }=0D +=0D +typedef struct _EDKII_MEMORY_MAPPED_FV_PROTOCOL EDKII_MEMORY_MAPPED_FV_PRO= TOCOL;=0D +=0D +//=0D +// Function Prototypes=0D +//=0D +=0D +/**=0D + Get the physical address and size of a file's section in a memory mapped= FV=0D +=0D + @param[in] This The protocol pointer=0D + @param[in] NameGuid The name GUID of the file=0D + @param[in] SectionType The file section from which to retrieve addres= s and size=0D + @param[out] FileAddress The physical address of the file=0D + @param[out] FileSize The size of the file=0D + @param[out] AuthStatus The authentication status associated with the = file=0D +=0D + @retval EFI_SUCCESS Information about the file was retrieved = successfully.=0D + @retval EFI_INVALID_PARAMETER FileAddress was NULL, FileSize was NULL, = AuthStatus=0D + was NULL.=0D + @retval EFI_NOT_FOUND No section of the specified type could be= located in=0D + the specified file.=0D +=0D +**/=0D +typedef=0D +EFI_STATUS=0D +(EFIAPI *GET_LOCATION_AND_SIZE)(=0D + IN EDKII_MEMORY_MAPPED_FV_PROTOCOL *This,=0D + IN CONST EFI_GUID *NameGuid,=0D + IN EFI_SECTION_TYPE SectionType,=0D + OUT EFI_PHYSICAL_ADDRESS *FileAddress,=0D + OUT UINTN *FileSize,=0D + OUT UINT32 *AuthStatus=0D + );=0D +=0D +//=0D +// Protocol interface structure=0D +//=0D +struct _EDKII_MEMORY_MAPPED_FV_PROTOCOL {=0D + GET_LOCATION_AND_SIZE GetLocationAndSize;=0D +};=0D +=0D +extern EFI_GUID gEdkiiMemoryMappedFvProtocolGuid;=0D +=0D +#endif=0D diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index d65dae18aa81e569..2d72ac733d82195e 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -679,6 +679,9 @@ [Protocols] ## Include/Protocol/PlatformBootManager.h=0D gEdkiiPlatformBootManagerProtocolGuid =3D { 0xaa17add4, 0x756c, 0x460d, = { 0x94, 0xb8, 0x43, 0x88, 0xd7, 0xfb, 0x3e, 0x59 } }=0D =0D + ## Include/Protocol/MemoryMappedFv.h=0D + gEdkiiMemoryMappedFvProtocolGuid =3D { 0xb9bfa973, 0x5384, 0x441e, { 0xa= 4, 0xe7, 0x20, 0xe6, 0x5d, 0xaf, 0x2e, 0x0f } }=0D +=0D #=0D # [Error.gEfiMdeModulePkgTokenSpaceGuid]=0D # 0x80000001 | Invalid value provided.=0D --=20 2.39.2