public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Ard Biesheuvel" <ardb@kernel.org>
To: devel@edk2.groups.io
Cc: Ard Biesheuvel <ardb@kernel.org>, Ray Ni <ray.ni@intel.com>,
	Jiewen Yao <jiewen.yao@intel.com>,
	Gerd Hoffmann <kraxel@redhat.com>,
	Taylor Beebe <t@taylorbeebe.com>,
	Oliver Smith-Denny <osd@smith-denny.com>,
	Dandan Bi <dandan.bi@intel.com>,
	Liming Gao <gaoliming@byosoft.com.cn>,
	"Kinney, Michael D" <michael.d.kinney@intel.com>,
	Leif Lindholm <quic_llindhol@quicinc.com>,
	Michael Kubacki <mikuback@linux.microsoft.com>
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	[thread overview]
Message-ID: <20230529101705.2476949-6-ardb@kernel.org> (raw)
In-Reply-To: <20230529101705.2476949-1-ardb@kernel.org>

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 <ardb@kernel.org>
---
 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/DxeMain.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 <Protocol/HiiPackageList.h>
 #include <Protocol/SmmBase2.h>
 #include <Protocol/PeCoffImageEmulator.h>
+#include <Protocol/MemoryMappedFv.h>
 #include <Guid/MemoryTypeInformation.h>
 #include <Guid/FirmwareFileSystem2.h>
 #include <Guid/FirmwareFileSystem3.h>
diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf
index 35d5bf0dee6f7f3f..a7175cb364b9b5de 100644
--- a/MdeModulePkg/Core/Dxe/DxeMain.inf
+++ b/MdeModulePkg/Core/Dxe/DxeMain.inf
@@ -153,6 +153,9 @@ [Protocols]
   gEfiLoadedImageDevicePathProtocolGuid         ## PRODUCES
   gEfiHiiPackageListProtocolGuid                ## SOMETIMES_PRODUCES
   gEfiSmmBase2ProtocolGuid                      ## SOMETIMES_CONSUMES
+  ## PRODUCES
+  ## CONSUMES
+  gEdkiiMemoryMappedFvProtocolGuid
   gEdkiiPeCoffImageEmulatorProtocolGuid         ## SOMETIMES_CONSUMES
 
   # Arch Protocols
diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/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);
 }
 
+/**
+  Get the image file data and size directly from a memory mapped FV
+
+  If FilePath is NULL, then NULL is returned.
+  If FileSize is NULL, then NULL is returned.
+  If AuthenticationStatus is NULL, then NULL is returned.
+
+  @param[in]       FvHandle             The firmware volume handle
+  @param[in]       FilePath             The pointer to the device path of the file
+                                        that is abstracted to the file buffer.
+  @param[out]      FileSize             The pointer to the size of the abstracted
+                                        file buffer.
+  @param[out]      AuthenticationStatus Pointer to the authentication status.
+
+  @retval NULL   FilePath is NULL, or FileSize is NULL, or AuthenticationStatus
+                 is NULL, or the file is not memory mapped
+  @retval other  The abstracted file buffer.
+**/
+STATIC
+VOID *
+GetFileFromMemoryMappedFv (
+  IN  EFI_HANDLE                      FvHandle,
+  IN  CONST EFI_DEVICE_PATH_PROTOCOL  *FilePath,
+  OUT UINTN                           *FileSize,
+  OUT UINT32                          *AuthenticationStatus
+  )
+{
+  EDKII_MEMORY_MAPPED_FV_PROTOCOL  *MemMappedFv;
+  CONST EFI_GUID                   *NameGuid;
+  EFI_PHYSICAL_ADDRESS             Address;
+  EFI_STATUS                       Status;
+
+  if ((FilePath == NULL) ||
+      (FileSize == NULL) ||
+      (AuthenticationStatus == NULL))
+  {
+    return NULL;
+  }
+
+  NameGuid = EfiGetNameGuidFromFwVolDevicePathNode (
+               (CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)FilePath);
+  if (NameGuid == NULL) {
+    return NULL;
+  }
+
+  Status = gBS->HandleProtocol (
+                  FvHandle,
+                  &gEdkiiMemoryMappedFvProtocolGuid,
+                  (VOID **)&MemMappedFv
+                  );
+  if (EFI_ERROR (Status)) {
+    ASSERT (Status == EFI_UNSUPPORTED);
+    return NULL;
+  }
+
+  Status = MemMappedFv->GetLocationAndSize (
+                          MemMappedFv,
+                          NameGuid,
+                          EFI_SECTION_PE32,
+                          &Address,
+                          FileSize,
+                          AuthenticationStatus
+                          );
+  if (EFI_ERROR (Status) || (Address > (MAX_ADDRESS - *FileSize))) {
+    return NULL;
+  }
+
+  return (VOID *)(UINTN)Address;
+}
+
 /**
   Loads an EFI image into memory and returns a handle to the image.
 
@@ -1164,6 +1234,16 @@ CoreLoadImageCommon (
     Status = CoreLocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &HandleFilePath, &DeviceHandle);
     if (!EFI_ERROR (Status)) {
       ImageIsFromFv = TRUE;
+
+      //
+      // If possible, use the memory mapped file image directly, rather than copying it into a buffer
+      //
+      FHand.Source = GetFileFromMemoryMappedFv (
+                       DeviceHandle,
+                       HandleFilePath,
+                       &FHand.SourceSize,
+                       &AuthenticationStatus
+                       );
     } else {
       HandleFilePath = FilePath;
       Status         = CoreLocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &HandleFilePath, &DeviceHandle);
@@ -1187,21 +1267,24 @@ CoreLoadImageCommon (
     //
     // Get the source file buffer by its device path.
     //
-    FHand.Source = GetFileBufferByFilePath (
-                     BootPolicy,
-                     FilePath,
-                     &FHand.SourceSize,
-                     &AuthenticationStatus
-                     );
     if (FHand.Source == NULL) {
-      Status = EFI_NOT_FOUND;
-    } else {
-      FHand.FreeBuffer = TRUE;
-      if (ImageIsFromLoadFile) {
-        //
-        // LoadFile () may cause the device path of the Handle be updated.
-        //
-        OriginalFilePath = AppendDevicePath (DevicePathFromHandle (DeviceHandle), Node);
+      FHand.Source = GetFileBufferByFilePath (
+                       BootPolicy,
+                       FilePath,
+                       &FHand.SourceSize,
+                       &AuthenticationStatus
+                       );
+
+      if (FHand.Source == NULL) {
+        Status = EFI_NOT_FOUND;
+      } else {
+        FHand.FreeBuffer = TRUE;
+        if (ImageIsFromLoadFile) {
+          //
+          // LoadFile () may cause the device path of the Handle be updated.
+          //
+          OriginalFilePath = AppendDevicePath (DevicePathFromHandle (DeviceHandle), Node);
+        }
       }
     }
   }
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
+  Protocol to obtain information about files in memory mapped firmware volumes
+
+  Copyright (c) 2023, Google LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef EDKII_MEMORY_MAPPED_FV_H_
+#define EDKII_MEMORY_MAPPED_FV_H_
+
+#define EDKII_MEMORY_MAPPED_FV_PROTOCOL_GUID \
+  { 0xb9bfa973, 0x5384, 0x441e, { 0xa4, 0xe7, 0x20, 0xe6, 0x5d, 0xaf, 0x2e, 0x0f } }
+
+typedef struct _EDKII_MEMORY_MAPPED_FV_PROTOCOL EDKII_MEMORY_MAPPED_FV_PROTOCOL;
+
+//
+// Function Prototypes
+//
+
+/**
+  Get the physical address and size of a file's section in a memory mapped FV
+
+  @param[in]  This          The protocol pointer
+  @param[in]  NameGuid      The name GUID of the file
+  @param[in]  SectionType   The file section from which to retrieve address and size
+  @param[out] FileAddress   The physical address of the file
+  @param[out] FileSize      The size of the file
+  @param[out] AuthStatus    The authentication status associated with the file
+
+  @retval EFI_SUCCESS            Information about the file was retrieved successfully.
+  @retval EFI_INVALID_PARAMETER  FileAddress was NULL, FileSize was NULL, AuthStatus
+                                 was NULL.
+  @retval EFI_NOT_FOUND          No section of the specified type could be located in
+                                 the specified file.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *GET_LOCATION_AND_SIZE)(
+  IN  EDKII_MEMORY_MAPPED_FV_PROTOCOL  *This,
+  IN  CONST EFI_GUID                   *NameGuid,
+  IN  EFI_SECTION_TYPE                 SectionType,
+  OUT EFI_PHYSICAL_ADDRESS             *FileAddress,
+  OUT UINTN                            *FileSize,
+  OUT UINT32                           *AuthStatus
+  );
+
+//
+// Protocol interface structure
+//
+struct _EDKII_MEMORY_MAPPED_FV_PROTOCOL {
+  GET_LOCATION_AND_SIZE   GetLocationAndSize;
+};
+
+extern EFI_GUID  gEdkiiMemoryMappedFvProtocolGuid;
+
+#endif
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
   gEdkiiPlatformBootManagerProtocolGuid = { 0xaa17add4, 0x756c, 0x460d, { 0x94, 0xb8, 0x43, 0x88, 0xd7, 0xfb, 0x3e, 0x59 } }
 
+  ## Include/Protocol/MemoryMappedFv.h
+  gEdkiiMemoryMappedFvProtocolGuid = { 0xb9bfa973, 0x5384, 0x441e, { 0xa4, 0xe7, 0x20, 0xe6, 0x5d, 0xaf, 0x2e, 0x0f } }
+
 #
 # [Error.gEfiMdeModulePkgTokenSpaceGuid]
 #   0x80000001 | Invalid value provided.
-- 
2.39.2


  parent reply	other threads:[~2023-05-29 10:17 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-29 10:16 [RFC PATCH 00/11] Permit DXE drivers to execute in place Ard Biesheuvel
2023-05-29 10:16 ` [RFC PATCH 01/11] MdeModulePkg/DxeCore: Remove unused 'EntryPoint' argument to LoadImage Ard Biesheuvel
2023-05-30  5:54   ` Ni, Ray
2023-05-30  7:36     ` Ard Biesheuvel
2023-05-29 10:16 ` [RFC PATCH 02/11] MdeModulePkg/DxeCore: Remove unused DstBuffer arg from LoadImage Ard Biesheuvel
2023-05-30  5:58   ` Ni, Ray
2023-05-29 10:16 ` [RFC PATCH 03/11] MdeModulePkg/DxeCore: Remove FreePage argument from CoreUnloadImage Ard Biesheuvel
2023-05-30  5:59   ` Ni, Ray
2023-05-29 10:16 ` [RFC PATCH 04/11] MdeModulePkg/DxeCore: Avoid caching memory mapped FFS files Ard Biesheuvel
2023-05-30  6:03   ` Ni, Ray
2023-05-30  7:47     ` Ard Biesheuvel
2023-05-29 10:16 ` Ard Biesheuvel [this message]
2023-05-30  6:21   ` [RFC PATCH 05/11] MdeModulePkg/DxeCore: Use memory mapped FV protocol to avoid image copy Ni, Ray
2023-05-30  7:51     ` [edk2-devel] " Ard Biesheuvel
2023-05-30  8:40       ` Ni, Ray
2023-05-30  8:51         ` Ard Biesheuvel
2023-05-29 10:17 ` [RFC PATCH 06/11] MdeModulePkg/DxeCore: Expose memory mapped FV protocol when possible Ard Biesheuvel
2023-05-30  6:22   ` Ni, Ray
2023-05-29 10:17 ` [RFC PATCH 07/11] MdeModulePkg/DxeCore: Execute loaded images in place if possible Ard Biesheuvel
2023-05-30  6:32   ` Ni, Ray
2023-05-30  7:54     ` Ard Biesheuvel
2023-05-29 10:17 ` [RFC PATCH 08/11] MdeModulePkg/DxeIpl: Relocate and remap XIP capable DXE drivers Ard Biesheuvel
2023-05-30  6:45   ` [edk2-devel] " Ni, Ray
2023-05-30  7:58     ` Ard Biesheuvel
2023-05-30  8:02       ` Ni, Ray
2023-05-30  8:29         ` Ard Biesheuvel
2023-05-30  9:06       ` Marvin Häuser
2023-05-30  9:18         ` Marvin Häuser
2023-05-30  9:38         ` Ard Biesheuvel
2023-05-30  9:41           ` Marvin Häuser
2023-05-30  9:47             ` Ard Biesheuvel
2023-05-30  9:48               ` Ard Biesheuvel
2023-05-30  9:52                 ` Marvin Häuser
2023-05-30 10:02                   ` Ard Biesheuvel
2023-05-30 10:25                     ` Marvin Häuser
2023-05-31  7:13                       ` Ni, Ray
2023-05-31  8:05                         ` Marvin Häuser
2023-05-29 10:17 ` [RFC PATCH 09/11] MdeModulePkg/DxeCore: Add PCD NX policy bit for default NX state Ard Biesheuvel
2023-05-30  6:54   ` Ni, Ray
2023-05-30  8:33     ` Ard Biesheuvel
2023-05-29 10:17 ` [RFC PATCH 10/11] ArmVirtPkg/ArmVirtQemu: Allow CPU arch protocol DXE to execute in place Ard Biesheuvel
2023-05-29 10:17 ` [RFC PATCH 11/11] ArmVirtPkg/ArmVirtQemu: Map all DRAM non-execute by default Ard Biesheuvel
2023-06-01 14:53 ` [edk2-devel] [RFC PATCH 00/11] Permit DXE drivers to execute in place Oliver Smith-Denny
2023-06-01 18:11   ` Ard Biesheuvel
2023-06-01 18:30     ` Oliver Smith-Denny

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230529101705.2476949-6-ardb@kernel.org \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox