public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Dov Murik" <dovmurik@linux.ibm.com>
To: devel@edk2.groups.io
Cc: Dov Murik <dovmurik@linux.ibm.com>,
	Laszlo Ersek <lersek@redhat.com>,
	Ard Biesheuvel <ardb+tianocore@kernel.org>,
	Jordan Justen <jordan.l.justen@intel.com>,
	James Bottomley <jejb@linux.ibm.com>,
	Tobin Feldman-Fitzthum <tobin@linux.ibm.com>
Subject: [PATCH v2 2/3] OvmfPkg/GenericQemuLoadImageLib: Read cmdline from QemuKernelLoaderFs
Date: Thu, 17 Jun 2021 12:16:59 +0000	[thread overview]
Message-ID: <20210617121700.2883073-3-dovmurik@linux.ibm.com> (raw)
In-Reply-To: <20210617121700.2883073-1-dovmurik@linux.ibm.com>

Remove the QemuFwCfgLib interface used to read the QEMU cmdline
(-append argument) and the initrd size.  Instead, use the synthetic
filesystem QemuKernelLoaderFs which has three files: "kernel", "initrd",
and "cmdline".

Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Tobin Feldman-Fitzthum <tobin@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
---
 OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.inf |   2 +-
 OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.c   | 145 ++++++++++++++++++--
 2 files changed, 133 insertions(+), 14 deletions(-)

diff --git a/OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.inf b/OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.inf
index b262cb926a4d..f462fd6922cf 100644
--- a/OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.inf
+++ b/OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.inf
@@ -27,12 +27,12 @@ [LibraryClasses]
   DebugLib
   MemoryAllocationLib
   PrintLib
-  QemuFwCfgLib
   UefiBootServicesTableLib
 
 [Protocols]
   gEfiDevicePathProtocolGuid
   gEfiLoadedImageProtocolGuid
+  gEfiSimpleFileSystemProtocolGuid
 
 [Guids]
   gQemuKernelLoaderFsMediaGuid
diff --git a/OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.c b/OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.c
index 114db7e8441f..f520456e3b24 100644
--- a/OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.c
+++ b/OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.c
@@ -11,9 +11,9 @@
 #include <Base.h>
 #include <Guid/QemuKernelLoaderFsMedia.h>
 #include <Library/DebugLib.h>
+#include <Library/FileHandleLib.h>
 #include <Library/MemoryAllocationLib.h>
 #include <Library/PrintLib.h>
-#include <Library/QemuFwCfgLib.h>
 #include <Library/QemuLoadImageLib.h>
 #include <Library/UefiBootServicesTableLib.h>
 #include <Protocol/DevicePath.h>
@@ -30,6 +30,11 @@ typedef struct {
   KERNEL_FILE_DEVPATH       FileNode;
   EFI_DEVICE_PATH_PROTOCOL  EndNode;
 } KERNEL_VENMEDIA_FILE_DEVPATH;
+
+typedef struct {
+  VENDOR_DEVICE_PATH       VenMediaNode;
+  EFI_DEVICE_PATH_PROTOCOL EndNode;
+} SINGLE_VENMEDIA_NODE_DEVPATH;
 #pragma pack ()
 
 STATIC CONST KERNEL_VENMEDIA_FILE_DEVPATH mKernelDevicePath = {
@@ -51,6 +56,78 @@ STATIC CONST KERNEL_VENMEDIA_FILE_DEVPATH mKernelDevicePath = {
   }
 };
 
+STATIC CONST SINGLE_VENMEDIA_NODE_DEVPATH mQemuKernelLoaderFileSystemDevicePath = {
+  {
+    {
+      MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP,
+      { sizeof (VENDOR_DEVICE_PATH) }
+    },
+    QEMU_KERNEL_LOADER_FS_MEDIA_GUID
+  }, {
+    END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    { sizeof (EFI_DEVICE_PATH_PROTOCOL) }
+  }
+};
+
+STATIC
+EFI_STATUS
+GetQemuKernelLoaderBlobSize (
+  IN  EFI_FILE_HANDLE     Root,
+  IN  CHAR16              *FileName,
+  OUT UINTN               *Size
+  )
+{
+  EFI_STATUS      Status;
+  EFI_FILE_HANDLE FileHandle;
+  UINT64          FileSize;
+
+  Status = Root->Open (Root, &FileHandle, FileName, EFI_FILE_MODE_READ, 0);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  Status = FileHandleGetSize (FileHandle, &FileSize);
+  if (EFI_ERROR (Status)) {
+    goto CloseFile;
+  }
+  *Size = FileSize;
+  Status = EFI_SUCCESS;
+CloseFile:
+  FileHandle->Close (FileHandle);
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+ReadWholeQemuKernelLoaderBlob (
+  IN  EFI_FILE_HANDLE     Root,
+  IN  CHAR16              *FileName,
+  IN  UINTN               Size,
+  OUT VOID                *Buffer
+  )
+{
+  EFI_STATUS      Status;
+  EFI_FILE_HANDLE FileHandle;
+  UINTN           ReadSize;
+
+  Status = Root->Open (Root, &FileHandle, FileName, EFI_FILE_MODE_READ, 0);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  ReadSize = Size;
+  Status = FileHandle->Read (FileHandle, &ReadSize, Buffer);
+  if (EFI_ERROR (Status)) {
+    goto CloseFile;
+  }
+  if (ReadSize != Size) {
+    Status = EFI_PROTOCOL_ERROR;
+    goto CloseFile;
+  }
+  Status = EFI_SUCCESS;
+CloseFile:
+  FileHandle->Close (FileHandle);
+  return Status;
+}
+
 /**
   Download the kernel, the initial ramdisk, and the kernel command line from
   QEMU's fw_cfg. The kernel will be instructed via its command line to load
@@ -76,12 +153,16 @@ QemuLoadKernelImage (
   OUT EFI_HANDLE                  *ImageHandle
   )
 {
-  EFI_STATUS                Status;
-  EFI_HANDLE                KernelImageHandle;
-  EFI_LOADED_IMAGE_PROTOCOL *KernelLoadedImage;
-  UINTN                     CommandLineSize;
-  CHAR8                     *CommandLine;
-  UINTN                     InitrdSize;
+  EFI_STATUS                      Status;
+  EFI_HANDLE                      KernelImageHandle;
+  EFI_LOADED_IMAGE_PROTOCOL       *KernelLoadedImage;
+  EFI_DEVICE_PATH_PROTOCOL        *DevicePathNode;
+  EFI_HANDLE                      FsVolumeHandle;
+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FsProtocol;
+  EFI_FILE_HANDLE                 Root;
+  UINTN                           CommandLineSize;
+  CHAR8                           *CommandLine;
+  UINTN                           InitrdSize;
 
   //
   // Load the image. This should call back into the QEMU EFI loader file system.
@@ -124,8 +205,38 @@ QemuLoadKernelImage (
                   );
   ASSERT_EFI_ERROR (Status);
 
-  QemuFwCfgSelectItem (QemuFwCfgItemCommandLineSize);
-  CommandLineSize = (UINTN)QemuFwCfgRead32 ();
+  //
+  // Open the Qemu Kernel Loader abstract filesystem (volume) which will be
+  // used to read the "initrd" and "cmdline" synthetic files.
+  //
+  DevicePathNode = (EFI_DEVICE_PATH_PROTOCOL *)&mQemuKernelLoaderFileSystemDevicePath;
+  Status = gBS->LocateDevicePath (
+                  &gEfiSimpleFileSystemProtocolGuid,
+                  &DevicePathNode,
+                  &FsVolumeHandle
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = gBS->HandleProtocol (
+                  FsVolumeHandle,
+                  &gEfiSimpleFileSystemProtocolGuid,
+                  (VOID **)&FsProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = FsProtocol->OpenVolume (FsVolumeHandle, &Root);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = GetQemuKernelLoaderBlobSize (Root, L"cmdline", &CommandLineSize);
+  if (EFI_ERROR (Status)) {
+    goto CloseRoot;
+  }
 
   if (CommandLineSize == 0) {
     KernelLoadedImage->LoadOptionsSize = 0;
@@ -136,8 +247,11 @@ QemuLoadKernelImage (
       goto UnloadImage;
     }
 
-    QemuFwCfgSelectItem (QemuFwCfgItemCommandLineData);
-    QemuFwCfgReadBytes (CommandLineSize, CommandLine);
+    Status = ReadWholeQemuKernelLoaderBlob (Root, L"cmdline", CommandLineSize,
+               CommandLine);
+    if (EFI_ERROR (Status)) {
+      goto FreeCommandLine;
+    }
 
     //
     // Verify NUL-termination of the command line.
@@ -155,8 +269,10 @@ QemuLoadKernelImage (
     KernelLoadedImage->LoadOptionsSize = (UINT32)((CommandLineSize - 1) * 2);
   }
 
-  QemuFwCfgSelectItem (QemuFwCfgItemInitrdSize);
-  InitrdSize = (UINTN)QemuFwCfgRead32 ();
+  Status = GetQemuKernelLoaderBlobSize (Root, L"initrd", &InitrdSize);
+  if (EFI_ERROR (Status)) {
+    goto FreeCommandLine;
+  }
 
   if (InitrdSize > 0) {
     //
@@ -193,6 +309,7 @@ QemuLoadKernelImage (
   }
 
   *ImageHandle = KernelImageHandle;
+  Root->Close (Root);
   return EFI_SUCCESS;
 
 FreeCommandLine:
@@ -201,6 +318,8 @@ FreeCommandLine:
   }
 UnloadImage:
   gBS->UnloadImage (KernelImageHandle);
+CloseRoot:
+  Root->Close (Root);
 
   return Status;
 }
-- 
2.25.1


  parent reply	other threads:[~2021-06-17 12:17 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-17 12:16 [RESEND] [PATCH v2 0/3] OvmfPkg: Use QemuKernelLoaderFs to read cmdline/initrd Dov Murik
2021-06-17 12:16 ` [PATCH v2 1/3] Revert "OvmfPkg/QemuKernelLoaderFsDxe: don't expose kernel command line" Dov Murik
2021-06-24 13:46   ` [edk2-devel] " Laszlo Ersek
2021-06-27  8:58     ` Dov Murik
2021-06-17 12:16 ` Dov Murik [this message]
2021-06-24 17:49   ` [edk2-devel] [PATCH v2 2/3] OvmfPkg/GenericQemuLoadImageLib: Read cmdline from QemuKernelLoaderFs Laszlo Ersek
2021-06-27  9:05     ` Dov Murik
2021-06-17 12:17 ` [PATCH v2 3/3] OvmfPkg/X86QemuLoadImageLib: State fw_cfg dependency in file header Dov Murik
2021-06-24 17:53   ` [edk2-devel] " Laszlo Ersek
2021-06-27  8:59     ` Dov Murik
  -- strict thread matches above, loose matches on Subject: below --
2021-06-17  9:12 [PATCH v2 0/3] OvmfPkg: Use QemuKernelLoaderFs to read cmdline/initrd Dov Murik
2021-06-17  9:12 ` [PATCH v2 2/3] OvmfPkg/GenericQemuLoadImageLib: Read cmdline from QemuKernelLoaderFs Dov Murik

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=20210617121700.2883073-3-dovmurik@linux.ibm.com \
    --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