[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v3 2/3] xen/efi: Support loading initrd using GRUB2 LoadFile2 protocol
On Thu, Jun 26, 2025 at 2:29 PM Jan Beulich <jbeulich@xxxxxxxx> wrote: > > On 25.06.2025 09:34, Frediano Ziglio wrote: > > --- a/xen/common/efi/boot.c > > +++ b/xen/common/efi/boot.c > > @@ -850,6 +850,74 @@ static bool __init read_file(EFI_FILE_HANDLE > > dir_handle, CHAR16 *name, > > return true; > > } > > > > +#pragma pack(1) > > +typedef struct { > > + VENDOR_DEVICE_PATH VenMediaNode; > > + EFI_DEVICE_PATH EndNode; > > +} SINGLE_NODE_VENDOR_MEDIA_DEVPATH; > > +#pragma pack() > > Where is this coming from? And why is this declared locally here, but the ... > The declaration comes from e2dk code and it's similar to code in Linux. It's not a generic declaration so it's not in a header. > > +static bool __init initrd_load_file2(const CHAR16 *name, struct file *file) > > +{ > > + static const SINGLE_NODE_VENDOR_MEDIA_DEVPATH __initconst > > initrd_dev_path = { > > + { > > + { > > + MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP, { sizeof > > (VENDOR_DEVICE_PATH) } > > + }, > > + LINUX_EFI_INITRD_MEDIA_GUID > > + }, > > + { > > + END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, > > + { sizeof (EFI_DEVICE_PATH) } > > + } > > + }; > > + static EFI_GUID __initdata lf2_proto_guid = > > EFI_LOAD_FILE2_PROTOCOL_GUID; > > ... corresponding GUID is put in a (random?) header file? > The GUID is declared in the header for device paths, being a GUID for a device path. > > + EFI_DEVICE_PATH *dp; > > + EFI_LOAD_FILE2_PROTOCOL *lf2; > > + EFI_HANDLE handle; > > + EFI_STATUS ret; > > + UINTN size; > > + > > + dp = (EFI_DEVICE_PATH *)&initrd_dev_path; > > Instead of a (fragile) cast, why not > > dp = &initrd_dev_path->VenMediaNode.Header; > It makes sense, although at the end it's just style. Code came from Linux in this case. > ? And then perhaps also as initializer of the variable? > > > + ret = efi_bs->LocateDevicePath(&lf2_proto_guid, &dp, &handle); > > + if ( EFI_ERROR(ret) ) > > + { > > + if ( ret == EFI_NOT_FOUND) > > + return false; > > + PrintErrMesg(L"Error getting file with LoadFile2 interface", ret); > > + } > > + > > + ret = efi_bs->HandleProtocol(handle, &lf2_proto_guid, (void **)&lf2); > > + if ( EFI_ERROR(ret) ) > > + PrintErrMesg(L"LoadFile2 file does not provide correct protocol", > > ret); > > + > > + size = 0; > > + ret = lf2->LoadFile(lf2, dp, false, &size, NULL); > > + if ( ret != EFI_BUFFER_TOO_SMALL ) > > + PrintErrMesg(L"Loading failed", ret); > > Here it's particularly bad, but throughout: How would one know in what > context the failure was? Wouldn't you want to include "name" in the > output? read_file() does include this detail. > It makes sense > > + file->addr = min(1UL << (32 + PAGE_SHIFT), > > + HYPERVISOR_VIRT_END - DIRECTMAP_VIRT_START); > > I understand you took this from read_file(), but the construct looks > outdated. For one, it should have been abstracted away when the Arm64 > work was done (I don't think such a restriction exists there), and > then I'm also not sure the restriction would unconditionally apply on > x86 anymore. > Do you have an updated/correct formula? > > + ret = efi_bs->AllocatePages(AllocateMaxAddress, EfiLoaderData, > > + PFN_UP(size), &file->addr); > > + if ( EFI_ERROR(ret) ) > > + PrintErrMesg(L"Allocation failed", ret); > > + > > + file->need_to_free = true; > > + file->size = size; > > + > > + ret = lf2->LoadFile(lf2, dp, false, &size, file->str); > > + if ( EFI_ERROR(ret) ) > > + { > > + efi_bs->FreePages(file->addr, PFN_UP(size)); > > + PrintErrMesg(L"Loading failed", ret); > > + } > > + > > + efi_arch_handle_module(file, name, NULL); > > Shouldn't it be handle_file_info() that you call, and a little earlier? > Already changed in the last series. Earlier where? You want it after loading data, right ? > > --- a/xen/include/efi/efidevp.h > > +++ b/xen/include/efi/efidevp.h > > @@ -398,5 +398,26 @@ typedef union { > > > > } EFI_DEV_PATH_PTR; > > > > +#define EFI_LOAD_FILE2_PROTOCOL_GUID \ > > + { 0x4006c0c1, 0xfcb3, 0x403e, {0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, > > 0xe0, 0x6d } } > > + > > +typedef struct EFI_LOAD_FILE2_PROTOCOL EFI_LOAD_FILE2_PROTOCOL; > > + > > +typedef > > +EFI_STATUS > > +(EFIAPI *EFI_LOAD_FILE2)( > > + IN EFI_LOAD_FILE2_PROTOCOL *This, > > + IN EFI_DEVICE_PATH *FilePath, > > + IN BOOLEAN BootPolicy, > > + IN OUT UINTN *BufferSize, > > + IN VOID *Buffer OPTIONAL > > + ); > > + > > +struct EFI_LOAD_FILE2_PROTOCOL { > > + EFI_LOAD_FILE2 LoadFile; > > +}; > > + > > +#define LINUX_EFI_INITRD_MEDIA_GUID \ > > + { 0x5568e427, 0x68fc, 0x4f3d, {0xac, 0x74, 0xca, 0x55, 0x52, 0x31, > > 0xcc, 0x68} } > > > > #endif > > While I'm not maintainer of this code anymore, I hope the new maintainers will > still respect the original idea of keeping these headers in sync with their > origin. The way it's arranged, this change doesn't look like it would have > been > taken from the gnu-efi package (albeit I will admit I didn't go check). > I'll have a look at gnu-efi headers. Note that the media GUID is GRUB/Linux specific so probably won't be in gnu-efi. > Jan Frediano
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |