]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg/GenericQemuLoadImageLib: Read cmdline from QemuKernelLoaderFs
authorDov Murik <dovmurik@linux.ibm.com>
Mon, 28 Jun 2021 10:51:09 +0000 (10:51 +0000)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Tue, 29 Jun 2021 12:33:17 +0000 (12:33 +0000)
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>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3457
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Message-Id: <20210628105110.379951-5-dovmurik@linux.ibm.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.c
OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.inf

index 8a29976ae17261e02a661e78bc61e227fad4d3d4..66e029397bd6de085f637a670ffa03404f72ee1f 100644 (file)
 #include <Base.h>\r
 #include <Guid/QemuKernelLoaderFsMedia.h>\r
 #include <Library/DebugLib.h>\r
+#include <Library/FileHandleLib.h>\r
 #include <Library/MemoryAllocationLib.h>\r
 #include <Library/PrintLib.h>\r
-#include <Library/QemuFwCfgLib.h>\r
 #include <Library/QemuLoadImageLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
 #include <Protocol/DevicePath.h>\r
 #include <Protocol/LoadedImage.h>\r
+#include <Protocol/SimpleFileSystem.h>\r
 \r
 #pragma pack (1)\r
 typedef struct {\r
@@ -30,6 +31,11 @@ typedef struct {
   KERNEL_FILE_DEVPATH       FileNode;\r
   EFI_DEVICE_PATH_PROTOCOL  EndNode;\r
 } KERNEL_VENMEDIA_FILE_DEVPATH;\r
+\r
+typedef struct {\r
+  VENDOR_DEVICE_PATH       VenMediaNode;\r
+  EFI_DEVICE_PATH_PROTOCOL EndNode;\r
+} SINGLE_VENMEDIA_NODE_DEVPATH;\r
 #pragma pack ()\r
 \r
 STATIC CONST KERNEL_VENMEDIA_FILE_DEVPATH mKernelDevicePath = {\r
@@ -51,6 +57,82 @@ STATIC CONST KERNEL_VENMEDIA_FILE_DEVPATH mKernelDevicePath = {
   }\r
 };\r
 \r
+STATIC CONST SINGLE_VENMEDIA_NODE_DEVPATH mQemuKernelLoaderFsDevicePath = {\r
+  {\r
+    {\r
+      MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP,\r
+      { sizeof (VENDOR_DEVICE_PATH) }\r
+    },\r
+    QEMU_KERNEL_LOADER_FS_MEDIA_GUID\r
+  }, {\r
+    END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
+    { sizeof (EFI_DEVICE_PATH_PROTOCOL) }\r
+  }\r
+};\r
+\r
+STATIC\r
+EFI_STATUS\r
+GetQemuKernelLoaderBlobSize (\r
+  IN  EFI_FILE_HANDLE     Root,\r
+  IN  CHAR16              *FileName,\r
+  OUT UINTN               *Size\r
+  )\r
+{\r
+  EFI_STATUS      Status;\r
+  EFI_FILE_HANDLE FileHandle;\r
+  UINT64          FileSize;\r
+\r
+  Status = Root->Open (Root, &FileHandle, FileName, EFI_FILE_MODE_READ, 0);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  Status = FileHandleGetSize (FileHandle, &FileSize);\r
+  if (EFI_ERROR (Status)) {\r
+    goto CloseFile;\r
+  }\r
+  if (FileSize > MAX_UINTN) {\r
+    Status = EFI_UNSUPPORTED;\r
+    goto CloseFile;\r
+  }\r
+  *Size = (UINTN)FileSize;\r
+  Status = EFI_SUCCESS;\r
+CloseFile:\r
+  FileHandle->Close (FileHandle);\r
+  return Status;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+ReadWholeQemuKernelLoaderBlob (\r
+  IN  EFI_FILE_HANDLE     Root,\r
+  IN  CHAR16              *FileName,\r
+  IN  UINTN               Size,\r
+  OUT VOID                *Buffer\r
+  )\r
+{\r
+  EFI_STATUS      Status;\r
+  EFI_FILE_HANDLE FileHandle;\r
+  UINTN           ReadSize;\r
+\r
+  Status = Root->Open (Root, &FileHandle, FileName, EFI_FILE_MODE_READ, 0);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  ReadSize = Size;\r
+  Status = FileHandle->Read (FileHandle, &ReadSize, Buffer);\r
+  if (EFI_ERROR (Status)) {\r
+    goto CloseFile;\r
+  }\r
+  if (ReadSize != Size) {\r
+    Status = EFI_PROTOCOL_ERROR;\r
+    goto CloseFile;\r
+  }\r
+  Status = EFI_SUCCESS;\r
+CloseFile:\r
+  FileHandle->Close (FileHandle);\r
+  return Status;\r
+}\r
+\r
 /**\r
   Download the kernel, the initial ramdisk, and the kernel command line from\r
   QEMU's fw_cfg. The kernel will be instructed via its command line to load\r
@@ -76,12 +158,16 @@ QemuLoadKernelImage (
   OUT EFI_HANDLE                  *ImageHandle\r
   )\r
 {\r
-  EFI_STATUS                Status;\r
-  EFI_HANDLE                KernelImageHandle;\r
-  EFI_LOADED_IMAGE_PROTOCOL *KernelLoadedImage;\r
-  UINTN                     CommandLineSize;\r
-  CHAR8                     *CommandLine;\r
-  UINTN                     InitrdSize;\r
+  EFI_STATUS                      Status;\r
+  EFI_HANDLE                      KernelImageHandle;\r
+  EFI_LOADED_IMAGE_PROTOCOL       *KernelLoadedImage;\r
+  EFI_DEVICE_PATH_PROTOCOL        *DevicePathNode;\r
+  EFI_HANDLE                      FsVolumeHandle;\r
+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FsProtocol;\r
+  EFI_FILE_HANDLE                 Root;\r
+  UINTN                           CommandLineSize;\r
+  CHAR8                           *CommandLine;\r
+  UINTN                           InitrdSize;\r
 \r
   //\r
   // Load the image. This should call back into the QEMU EFI loader file system.\r
@@ -124,8 +210,38 @@ QemuLoadKernelImage (
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
-  QemuFwCfgSelectItem (QemuFwCfgItemCommandLineSize);\r
-  CommandLineSize = (UINTN)QemuFwCfgRead32 ();\r
+  //\r
+  // Open the Qemu Kernel Loader abstract filesystem (volume) which will be\r
+  // used to query the "initrd" and to read the "cmdline" synthetic files.\r
+  //\r
+  DevicePathNode = (EFI_DEVICE_PATH_PROTOCOL *)&mQemuKernelLoaderFsDevicePath;\r
+  Status = gBS->LocateDevicePath (\r
+                  &gEfiSimpleFileSystemProtocolGuid,\r
+                  &DevicePathNode,\r
+                  &FsVolumeHandle\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    goto UnloadImage;\r
+  }\r
+\r
+  Status = gBS->HandleProtocol (\r
+                  FsVolumeHandle,\r
+                  &gEfiSimpleFileSystemProtocolGuid,\r
+                  (VOID **)&FsProtocol\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    goto UnloadImage;\r
+  }\r
+\r
+  Status = FsProtocol->OpenVolume (FsVolumeHandle, &Root);\r
+  if (EFI_ERROR (Status)) {\r
+    goto UnloadImage;\r
+  }\r
+\r
+  Status = GetQemuKernelLoaderBlobSize (Root, L"cmdline", &CommandLineSize);\r
+  if (EFI_ERROR (Status)) {\r
+    goto CloseRoot;\r
+  }\r
 \r
   if (CommandLineSize == 0) {\r
     KernelLoadedImage->LoadOptionsSize = 0;\r
@@ -133,11 +249,14 @@ QemuLoadKernelImage (
     CommandLine = AllocatePool (CommandLineSize);\r
     if (CommandLine == NULL) {\r
       Status = EFI_OUT_OF_RESOURCES;\r
-      goto UnloadImage;\r
+      goto CloseRoot;\r
     }\r
 \r
-    QemuFwCfgSelectItem (QemuFwCfgItemCommandLineData);\r
-    QemuFwCfgReadBytes (CommandLineSize, CommandLine);\r
+    Status = ReadWholeQemuKernelLoaderBlob (Root, L"cmdline", CommandLineSize,\r
+               CommandLine);\r
+    if (EFI_ERROR (Status)) {\r
+      goto FreeCommandLine;\r
+    }\r
 \r
     //\r
     // Verify NUL-termination of the command line.\r
@@ -155,8 +274,10 @@ QemuLoadKernelImage (
     KernelLoadedImage->LoadOptionsSize = (UINT32)((CommandLineSize - 1) * 2);\r
   }\r
 \r
-  QemuFwCfgSelectItem (QemuFwCfgItemInitrdSize);\r
-  InitrdSize = (UINTN)QemuFwCfgRead32 ();\r
+  Status = GetQemuKernelLoaderBlobSize (Root, L"initrd", &InitrdSize);\r
+  if (EFI_ERROR (Status)) {\r
+    goto FreeCommandLine;\r
+  }\r
 \r
   if (InitrdSize > 0) {\r
     //\r
@@ -199,6 +320,8 @@ FreeCommandLine:
   if (CommandLineSize > 0) {\r
     FreePool (CommandLine);\r
   }\r
+CloseRoot:\r
+  Root->Close (Root);\r
 UnloadImage:\r
   if (EFI_ERROR (Status)) {\r
     gBS->UnloadImage (KernelImageHandle);\r
index b262cb926a4deb106636f12c9dff69e2f5ce1760..9c9e35b1c5b9d72136e901e5c4d54ff01234ffcb 100644 (file)
 \r
 [LibraryClasses]\r
   DebugLib\r
+  FileHandleLib\r
   MemoryAllocationLib\r
   PrintLib\r
-  QemuFwCfgLib\r
   UefiBootServicesTableLib\r
 \r
 [Protocols]\r
   gEfiDevicePathProtocolGuid\r
   gEfiLoadedImageProtocolGuid\r
+  gEfiSimpleFileSystemProtocolGuid\r
 \r
 [Guids]\r
   gQemuKernelLoaderFsMediaGuid\r