Re: [PATCH 2/2] efi: libstub: Look for initrd LoadFile2 protocol on image handle

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxx>
> ---
>  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@xxxxxxxxxx>
Reviewed-by: Ilias Apalodimas <ilias.apalodimas@xxxxxxxxxx>



[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux