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 <ler...@redhat.com> Cc: Ard Biesheuvel <ardb+tianoc...@kernel.org> Cc: Jordan Justen <jordan.l.jus...@intel.com> Cc: James Bottomley <j...@linux.ibm.com> Cc: Tobin Feldman-Fitzthum <to...@linux.ibm.com> Signed-off-by: Dov Murik <dovmu...@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 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#76666): https://edk2.groups.io/g/devel/message/76666 Mute This Topic: https://groups.io/mt/83602584/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-