From: Ilias Apalodimas <ilias.apalodimas@linaro.org>
To: Ard Biesheuvel <ardb@kernel.org>
Cc: linux-efi@vger.kernel.org, Michael Brown <mcb30@ipxe.org>
Subject: Re: [PATCH 2/2] efi: libstub: Look for initrd LoadFile2 protocol on image handle
Date: Mon, 13 Mar 2023 10:11:34 +0200 [thread overview]
Message-ID: <ZA7atjWz16jQYr0H@hera> (raw)
In-Reply-To: <20230310084529.3229983-3-ardb@kernel.org>
On Fri, Mar 10, 2023 at 09:45:29AM +0100, Ard Biesheuvel wrote:
> The use of a global singleton device path for describing the initrd to
> be loaded by the kernel implies that only a single handle can exist that
> carries the initrd LoadFile2 protocol implementation.
>
> This avoids the need on the part of the EFI stub to reason about which
> initrd is the preferred one when several are being provided - we already
> have initrd loading via the setup header on x86 and via DT on other
> architectures, in addition to the initrd= command line option, and so
> having a single loader provided initrd that supersedes all of them was
> deemed preferable over having multiple sources.
>
> However, this means that intermediate loader stages cannot simply
> install the LoadFile2 initrd device path, and will need to check for
> failures and deal with them. It also means that such stages will have to
> reason about whether or not the subsequent stage being loaded is the
> final one, or whether it may attempt to install the initrd device path
> itself.
>
> We can solve this by associating the initrd LoadFile2 protocol with the
> loaded image instead of with a global singleton device path. That way,
> each stage can associate any initrd it provides with the image that it
> is loading.
>
> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> ---
> drivers/firmware/efi/libstub/efi-stub-helper.c | 42 ++++++++++++--------
> include/linux/efi.h | 2 +-
> include/linux/pe.h | 2 +-
> 3 files changed, 28 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c
> index d47aa855398b39a6..a97c95a1d99e0b9d 100644
> --- a/drivers/firmware/efi/libstub/efi-stub-helper.c
> +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c
> @@ -482,10 +482,11 @@ static const struct {
> };
>
> /**
> - * efi_load_initrd_dev_path() - load the initrd from the Linux initrd device path
> - * @initrd: pointer of struct to store the address where the initrd was loaded
> - * and the size of the loaded initrd
> - * @max: upper limit for the initrd memory allocation
> + * efi_load_initrd_lf2() - load the initrd from the Linux initrd device path
> + * @image_handle: EFI handle of the loaded image
> + * @initrd: pointer of struct to store the address where the initrd was
> + * loaded and the size of the loaded initrd
> + * @max: upper limit for the initrd memory allocation
> *
> * Return:
> * * %EFI_SUCCESS if the initrd was loaded successfully, in which
> @@ -495,24 +496,33 @@ static const struct {
> * * %EFI_LOAD_ERROR in all other cases
> */
> static
> -efi_status_t efi_load_initrd_dev_path(struct linux_efi_initrd *initrd,
> - unsigned long max)
> +efi_status_t efi_load_initrd_lf2(efi_handle_t image_handle,
> + struct linux_efi_initrd *initrd,
> + unsigned long max)
> {
> efi_guid_t lf2_proto_guid = EFI_LOAD_FILE2_PROTOCOL_GUID;
> + efi_guid_t initrd_lf2_proto_guid = LINUX_EFI_INITRD_LF2_PROTOCOL_GUID;
> efi_device_path_protocol_t *dp;
> efi_load_file2_protocol_t *lf2;
> efi_handle_t handle;
> efi_status_t status;
>
> - dp = (efi_device_path_protocol_t *)&initrd_dev_path;
> - status = efi_bs_call(locate_device_path, &lf2_proto_guid, &dp, &handle);
> - if (status != EFI_SUCCESS)
> - return status;
> -
> - status = efi_bs_call(handle_protocol, handle, &lf2_proto_guid,
> + /* first look for a initrd loading protocol specific to this image */
> + status = efi_bs_call(handle_protocol, image_handle, &initrd_lf2_proto_guid,
> (void **)&lf2);
> - if (status != EFI_SUCCESS)
> - return status;
> + if (status != EFI_SUCCESS) {
> + /* look for the global singleton initrd loading protocol */
> + dp = (efi_device_path_protocol_t *)&initrd_dev_path;
> + status = efi_bs_call(locate_device_path, &lf2_proto_guid, &dp,
> + &handle);
> + if (status != EFI_SUCCESS)
> + return status;
> +
> + status = efi_bs_call(handle_protocol, handle, &lf2_proto_guid,
> + (void **)&lf2);
> + if (status != EFI_SUCCESS)
> + return status;
> + }
>
> initrd->size = 0;
> status = efi_call_proto(lf2, load_file, dp, false, &initrd->size, NULL);
> @@ -567,9 +577,9 @@ efi_status_t efi_load_initrd(efi_handle_t handle,
> if (!IS_ENABLED(CONFIG_BLK_DEV_INITRD) || efi_noinitrd)
> return EFI_SUCCESS;
>
> - status = efi_load_initrd_dev_path(&initrd, hard_limit);
> + status = efi_load_initrd_lf2(handle, &initrd, hard_limit);
> if (status == EFI_SUCCESS) {
> - efi_info("Loaded initrd from LINUX_EFI_INITRD_MEDIA_GUID device path\n");
> + efi_info("Loaded initrd using LoadFile2 protocol\n");
> if (initrd.size > 0 &&
> efi_measure_tagged_event(initrd.base, initrd.size,
> EFISTUB_EVT_INITRD) == EFI_SUCCESS)
> diff --git a/include/linux/efi.h b/include/linux/efi.h
> index 04a733f0ba956211..83643d6aee755d85 100644
> --- a/include/linux/efi.h
> +++ b/include/linux/efi.h
> @@ -417,7 +417,7 @@ void efi_native_runtime_setup(void);
> #define LINUX_EFI_MOK_VARIABLE_TABLE_GUID EFI_GUID(0xc451ed2b, 0x9694, 0x45d3, 0xba, 0xba, 0xed, 0x9f, 0x89, 0x88, 0xa3, 0x89)
> #define LINUX_EFI_COCO_SECRET_AREA_GUID EFI_GUID(0xadf956ad, 0xe98c, 0x484c, 0xae, 0x11, 0xb5, 0x1c, 0x7d, 0x33, 0x64, 0x47)
> #define LINUX_EFI_BOOT_MEMMAP_GUID EFI_GUID(0x800f683f, 0xd08b, 0x423a, 0xa2, 0x93, 0x96, 0x5c, 0x3c, 0x6f, 0xe2, 0xb4)
> -
> +#define LINUX_EFI_INITRD_LF2_PROTOCOL_GUID EFI_GUID(0xf9e3378e, 0xb3b1, 0x423a, 0xbd, 0x9a, 0x2d, 0x08, 0x60, 0x28, 0x7f, 0x72)
> #define RISCV_EFI_BOOT_PROTOCOL_GUID EFI_GUID(0xccd15fec, 0x6f73, 0x4eec, 0x83, 0x95, 0x3e, 0x69, 0xe4, 0xb9, 0x40, 0xbf)
>
> /*
> diff --git a/include/linux/pe.h b/include/linux/pe.h
> index 6ffabf1e6d039e67..934e3a15ea7ddc07 100644
> --- a/include/linux/pe.h
> +++ b/include/linux/pe.h
> @@ -29,7 +29,7 @@
> * handover_offset and xloadflags fields in the bootparams structure.
> */
> #define LINUX_EFISTUB_MAJOR_VERSION 0x1
> -#define LINUX_EFISTUB_MINOR_VERSION 0x1
> +#define LINUX_EFISTUB_MINOR_VERSION 0x2
>
> /*
> * LINUX_PE_MAGIC appears at offset 0x38 into the MS-DOS header of EFI bootable
> --
> 2.39.2
>
Tested (with a slightly hacked version of u-boot) both paths.
Tested-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
prev parent reply other threads:[~2023-03-13 8:11 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-10 8:45 [PATCH 0/2] efi: Allow initrd LoadFile2 proto on loaded image Ard Biesheuvel
2023-03-10 8:45 ` [PATCH 1/2] efi: libstub: Pass loaded image EFI handle to efi_load_initrd() Ard Biesheuvel
2023-03-13 7:25 ` Ilias Apalodimas
2023-03-10 8:45 ` [PATCH 2/2] efi: libstub: Look for initrd LoadFile2 protocol on image handle Ard Biesheuvel
2023-03-13 8:11 ` Ilias Apalodimas [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZA7atjWz16jQYr0H@hera \
--to=ilias.apalodimas@linaro.org \
--cc=ardb@kernel.org \
--cc=linux-efi@vger.kernel.org \
--cc=mcb30@ipxe.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox