From: Lennart Poettering Date: Wed, 14 Jan 2026 17:22:29 +0000 (+0100) Subject: efi: use 'struct iovec' more, pass initrds down with it X-Git-Tag: v260-rc1~400 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=80ab99d4d200c29727b573df6bccc49cc9dca6a4;p=thirdparty%2Fsystemd.git efi: use 'struct iovec' more, pass initrds down with it --- diff --git a/src/boot/boot.c b/src/boot/boot.c index 3ff757c53d6..b8a9264a496 100644 --- a/src/boot/boot.c +++ b/src/boot/boot.c @@ -13,6 +13,7 @@ #include "export-vars.h" #include "graphics.h" #include "initrd.h" +#include "iovec-util-fundamental.h" #include "line-edit.h" #include "measure.h" #include "memory-util-fundamental.h" @@ -2690,7 +2691,7 @@ static EFI_STATUS call_image_start( return log_error_status(err, "Error loading %ls: %m", entry->devicetree); } - err = initrd_register(PHYSICAL_ADDRESS_TO_POINTER(initrd_pages.addr), initrd_size, &initrd_handle); + err = initrd_register(&IOVEC_MAKE(PHYSICAL_ADDRESS_TO_POINTER(initrd_pages.addr), initrd_size), &initrd_handle); if (err != EFI_SUCCESS) return log_error_status(err, "Error registering initrd: %m"); } diff --git a/src/boot/initrd.c b/src/boot/initrd.c index 1de4fcfa054..f817fc3fdf2 100644 --- a/src/boot/initrd.c +++ b/src/boot/initrd.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include "initrd.h" +#include "iovec-util-fundamental.h" #include "proto/device-path.h" #include "proto/load-file.h" #include "util.h" @@ -11,8 +12,7 @@ /* extend LoadFileProtocol */ struct initrd_loader { EFI_LOAD_FILE_PROTOCOL load_file; - const void *address; - size_t length; + struct iovec data; }; /* static structure for LINUX_INITRD_MEDIA device path @@ -52,23 +52,21 @@ static EFIAPI EFI_STATUS initrd_load_file( return EFI_UNSUPPORTED; loader = (struct initrd_loader *) this; - - if (loader->length == 0 || !loader->address) + if (!iovec_is_set(&loader->data)) return EFI_NOT_FOUND; - if (!buffer || *buffer_size < loader->length) { - *buffer_size = loader->length; + if (!buffer || *buffer_size < loader->data.iov_len) { + *buffer_size = loader->data.iov_len; return EFI_BUFFER_TOO_SMALL; } - memcpy(buffer, loader->address, loader->length); - *buffer_size = loader->length; + memcpy(buffer, loader->data.iov_base, loader->data.iov_len); + *buffer_size = loader->data.iov_len; return EFI_SUCCESS; } EFI_STATUS initrd_register( - const void *initrd_address, - size_t initrd_length, + const struct iovec *initrd, EFI_HANDLE *ret_initrd_handle) { EFI_STATUS err; @@ -78,7 +76,10 @@ EFI_STATUS initrd_register( assert(ret_initrd_handle); - if (!initrd_address || initrd_length == 0) + /* If no initrd is specified we'll not install any. This avoids regstration of the protocol for that + * case, leaving it open for something else. */ + + if (!iovec_is_set(initrd)) return EFI_SUCCESS; /* check if a LINUX_INITRD_MEDIA_GUID DevicePath is already registered. @@ -92,8 +93,7 @@ EFI_STATUS initrd_register( loader = xnew(struct initrd_loader, 1); *loader = (struct initrd_loader) { .load_file.LoadFile = initrd_load_file, - .address = initrd_address, - .length = initrd_length + .data = *initrd, }; /* create a new handle and register the LoadFile2 protocol with the InitrdMediaPath on it */ diff --git a/src/boot/initrd.h b/src/boot/initrd.h index e7685aeb4a6..50987c497d6 100644 --- a/src/boot/initrd.h +++ b/src/boot/initrd.h @@ -4,8 +4,7 @@ #include "efi.h" EFI_STATUS initrd_register( - const void *initrd_address, - size_t initrd_length, + const struct iovec *initrd, EFI_HANDLE *ret_initrd_handle); EFI_STATUS initrd_unregister(EFI_HANDLE initrd_handle); diff --git a/src/boot/linux.c b/src/boot/linux.c index 376b52d72ac..22b758b8e64 100644 --- a/src/boot/linux.c +++ b/src/boot/linux.c @@ -96,7 +96,7 @@ static EFI_STATUS load_via_boot_services( } _cleanup_(cleanup_initrd) EFI_HANDLE initrd_handle = NULL; - err = initrd_register(initrd->iov_base, initrd->iov_len, &initrd_handle); + err = initrd_register(initrd, &initrd_handle); if (err != EFI_SUCCESS) return log_error_status(err, "Error registering initrd: %m"); @@ -315,7 +315,7 @@ EFI_STATUS linux_exec( } _cleanup_(cleanup_initrd) EFI_HANDLE initrd_handle = NULL; - err = initrd_register(initrd->iov_base, initrd->iov_len, &initrd_handle); + err = initrd_register(initrd, &initrd_handle); if (err != EFI_SUCCESS) return log_error_status(err, "Error registering initrd: %m");