[PATCH v1 2/3] OvmfPkg/GenericQemuLoadImageLib: Read cmdline from QemuKernelLoaderFs


Dov Murik
 

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 | 132 =
++++++++++++++++++--
2 files changed, 126 insertions(+), 8 deletions(-)

diff --git a/OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLi=
b.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=0D
MemoryAllocationLib=0D
PrintLib=0D
- QemuFwCfgLib=0D
UefiBootServicesTableLib=0D
=0D
[Protocols]=0D
gEfiDevicePathProtocolGuid=0D
gEfiLoadedImageProtocolGuid=0D
+ gEfiSimpleFileSystemProtocolGuid=0D
=0D
[Guids]=0D
gQemuKernelLoaderFsMediaGuid=0D
diff --git a/OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLi=
b.c b/OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.c
index 114db7e8441f..7d26c912e14f 100644
--- a/OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.c
+++ b/OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.c
@@ -11,9 +11,9 @@
#include <Base.h>=0D
#include <Guid/QemuKernelLoaderFsMedia.h>=0D
#include <Library/DebugLib.h>=0D
+#include <Library/FileHandleLib.h>=0D
#include <Library/MemoryAllocationLib.h>=0D
#include <Library/PrintLib.h>=0D
-#include <Library/QemuFwCfgLib.h>=0D
#include <Library/QemuLoadImageLib.h>=0D
#include <Library/UefiBootServicesTableLib.h>=0D
#include <Protocol/DevicePath.h>=0D
@@ -30,6 +30,11 @@ typedef struct {
KERNEL_FILE_DEVPATH FileNode;=0D
EFI_DEVICE_PATH_PROTOCOL EndNode;=0D
} KERNEL_VENMEDIA_FILE_DEVPATH;=0D
+=0D
+typedef struct {=0D
+ VENDOR_DEVICE_PATH VenMediaNode;=0D
+ EFI_DEVICE_PATH_PROTOCOL EndNode;=0D
+} SINGLE_VENMEDIA_NODE_DEVPATH;=0D
#pragma pack ()=0D
=0D
STATIC CONST KERNEL_VENMEDIA_FILE_DEVPATH mKernelDevicePath =3D {=0D
@@ -51,6 +56,78 @@ STATIC CONST KERNEL_VENMEDIA_FILE_DEVPATH mKernelDeviceP=
ath =3D {
}=0D
};=0D
=0D
+STATIC CONST SINGLE_VENMEDIA_NODE_DEVPATH mQemuKernelLoaderFileSystemDevic=
ePath =3D {=0D
+ {=0D
+ {=0D
+ MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP,=0D
+ { sizeof (VENDOR_DEVICE_PATH) }=0D
+ },=0D
+ QEMU_KERNEL_LOADER_FS_MEDIA_GUID=0D
+ }, {=0D
+ END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,=0D
+ { sizeof (EFI_DEVICE_PATH_PROTOCOL) }=0D
+ }=0D
+};=0D
+=0D
+STATIC=0D
+EFI_STATUS=0D
+GetQemuKernelBlobSize (=0D
+ IN EFI_FILE_HANDLE Root,=0D
+ IN CHAR16 *FileName,=0D
+ OUT UINTN *Size=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ EFI_FILE_HANDLE FileHandle;=0D
+ UINT64 FileSize;=0D
+=0D
+ Status =3D Root->Open (Root, &FileHandle, FileName, EFI_FILE_MODE_READ, =
0);=0D
+ if (EFI_ERROR (Status)) {=0D
+ return Status;=0D
+ }=0D
+ Status =3D FileHandleGetSize (FileHandle, &FileSize);=0D
+ if (EFI_ERROR (Status)) {=0D
+ goto CloseFile;=0D
+ }=0D
+ *Size =3D FileSize;=0D
+ Status =3D EFI_SUCCESS;=0D
+CloseFile:=0D
+ FileHandle->Close (FileHandle);=0D
+ return Status;=0D
+}=0D
+=0D
+STATIC=0D
+EFI_STATUS=0D
+ReadWholeQemuKernelBlob (=0D
+ IN EFI_FILE_HANDLE Root,=0D
+ IN CHAR16 *FileName,=0D
+ IN UINTN Size,=0D
+ OUT VOID *Buffer=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ EFI_FILE_HANDLE FileHandle;=0D
+ UINTN ReadSize;=0D
+=0D
+ Status =3D Root->Open (Root, &FileHandle, FileName, EFI_FILE_MODE_READ, =
0);=0D
+ if (EFI_ERROR (Status)) {=0D
+ return Status;=0D
+ }=0D
+ ReadSize =3D Size;=0D
+ Status =3D FileHandle->Read (FileHandle, &ReadSize, Buffer);=0D
+ if (EFI_ERROR (Status)) {=0D
+ goto CloseFile;=0D
+ }=0D
+ if (ReadSize !=3D Size) {=0D
+ Status =3D EFI_PROTOCOL_ERROR;=0D
+ goto CloseFile;=0D
+ }=0D
+ Status =3D EFI_SUCCESS;=0D
+CloseFile:=0D
+ FileHandle->Close (FileHandle);=0D
+ return Status;=0D
+}=0D
+=0D
/**=0D
Download the kernel, the initial ramdisk, and the kernel command line fr=
om=0D
QEMU's fw_cfg. The kernel will be instructed via its command line to loa=
d=0D
@@ -79,6 +156,10 @@ QemuLoadKernelImage (
EFI_STATUS Status;=0D
EFI_HANDLE KernelImageHandle;=0D
EFI_LOADED_IMAGE_PROTOCOL *KernelLoadedImage;=0D
+ EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;=0D
+ EFI_HANDLE FsVolumeHandle;=0D
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FsProtocol;=0D
+ EFI_FILE_HANDLE Root;=0D
UINTN CommandLineSize;=0D
CHAR8 *CommandLine;=0D
UINTN InitrdSize;=0D
@@ -124,8 +205,38 @@ QemuLoadKernelImage (
);=0D
ASSERT_EFI_ERROR (Status);=0D
=0D
- QemuFwCfgSelectItem (QemuFwCfgItemCommandLineSize);=0D
- CommandLineSize =3D (UINTN)QemuFwCfgRead32 ();=0D
+ //=0D
+ // Open the Qemu Kernel Loader abstract filesystem (volume) which will b=
e=0D
+ // used to read the "initrd" and "cmdline" synthetic files.=0D
+ //=0D
+ DevicePathNode =3D (EFI_DEVICE_PATH_PROTOCOL *) &mQemuKernelLoaderFileSy=
stemDevicePath;=0D
+ Status =3D gBS->LocateDevicePath (=0D
+ &gEfiSimpleFileSystemProtocolGuid,=0D
+ &DevicePathNode,=0D
+ &FsVolumeHandle=0D
+ );=0D
+ if (EFI_ERROR (Status)) {=0D
+ return Status;=0D
+ }=0D
+=0D
+ Status =3D gBS->HandleProtocol (=0D
+ FsVolumeHandle,=0D
+ &gEfiSimpleFileSystemProtocolGuid,=0D
+ (VOID **)&FsProtocol=0D
+ );=0D
+ if (EFI_ERROR (Status)) {=0D
+ return Status;=0D
+ }=0D
+=0D
+ Status =3D FsProtocol->OpenVolume (FsVolumeHandle, &Root);=0D
+ if (EFI_ERROR (Status)) {=0D
+ return Status;=0D
+ }=0D
+=0D
+ Status =3D GetQemuKernelBlobSize (Root, L"cmdline", &CommandLineSize);=0D
+ if (EFI_ERROR (Status)) {=0D
+ goto CloseRoot;=0D
+ }=0D
=0D
if (CommandLineSize =3D=3D 0) {=0D
KernelLoadedImage->LoadOptionsSize =3D 0;=0D
@@ -136,8 +247,10 @@ QemuLoadKernelImage (
goto UnloadImage;=0D
}=0D
=0D
- QemuFwCfgSelectItem (QemuFwCfgItemCommandLineData);=0D
- QemuFwCfgReadBytes (CommandLineSize, CommandLine);=0D
+ Status =3D ReadWholeQemuKernelBlob (Root, L"cmdline", CommandLineSize,=
CommandLine);=0D
+ if (EFI_ERROR (Status)) {=0D
+ goto FreeCommandLine;=0D
+ }=0D
=0D
//=0D
// Verify NUL-termination of the command line.=0D
@@ -155,8 +268,10 @@ QemuLoadKernelImage (
KernelLoadedImage->LoadOptionsSize =3D (UINT32)((CommandLineSize - 1) =
* 2);=0D
}=0D
=0D
- QemuFwCfgSelectItem (QemuFwCfgItemInitrdSize);=0D
- InitrdSize =3D (UINTN)QemuFwCfgRead32 ();=0D
+ Status =3D GetQemuKernelBlobSize (Root, L"initrd", &InitrdSize);=0D
+ if (EFI_ERROR (Status)) {=0D
+ goto FreeCommandLine;=0D
+ }=0D
=0D
if (InitrdSize > 0) {=0D
//=0D
@@ -193,6 +308,7 @@ QemuLoadKernelImage (
}=0D
=0D
*ImageHandle =3D KernelImageHandle;=0D
+ Root->Close (Root);=0D
return EFI_SUCCESS;=0D
=0D
FreeCommandLine:=0D
@@ -201,6 +317,8 @@ FreeCommandLine:
}=0D
UnloadImage:=0D
gBS->UnloadImage (KernelImageHandle);=0D
+CloseRoot:=0D
+ Root->Close (Root);=0D
=0D
return Status;=0D
}=0D
--=20
2.25.1

Join devel@edk2.groups.io to automatically receive all group messages.