Commit f61900fd authored by Arvind Sankar's avatar Arvind Sankar Committed by Ard Biesheuvel
Browse files

efi/libstub: Unify initrd loading across architectures



Factor out the initrd loading into a common function that can be called
both from the generic efi-stub.c and the x86-specific x86-stub.c.

Signed-off-by: default avatarArvind Sankar <nivedita@alum.mit.edu>
Link: https://lore.kernel.org/r/20200430182843.2510180-10-nivedita@alum.mit.edu


Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
parent 987053a3
Loading
Loading
Loading
Loading
+43 −3
Original line number Diff line number Diff line
@@ -331,6 +331,7 @@ static const struct {
 *		%EFI_OUT_OF_RESOURCES if memory allocation failed
 *		%EFI_LOAD_ERROR in all other cases
 */
static
efi_status_t efi_load_initrd_dev_path(unsigned long *load_addr,
				      unsigned long *load_size,
				      unsigned long max)
@@ -343,9 +344,6 @@ efi_status_t efi_load_initrd_dev_path(unsigned long *load_addr,
	efi_handle_t handle;
	efi_status_t status;

	if (!load_addr || !load_size)
		return EFI_INVALID_PARAMETER;

	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)
@@ -375,3 +373,45 @@ efi_status_t efi_load_initrd_dev_path(unsigned long *load_addr,
	*load_size = initrd_size;
	return EFI_SUCCESS;
}

static
efi_status_t efi_load_initrd_cmdline(efi_loaded_image_t *image,
				     unsigned long *load_addr,
				     unsigned long *load_size,
				     unsigned long soft_limit,
				     unsigned long hard_limit)
{
	if (!IS_ENABLED(CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER) ||
	    (IS_ENABLED(CONFIG_X86) && (!efi_is_native() || image == NULL))) {
		*load_addr = *load_size = 0;
		return EFI_SUCCESS;
	}

	return handle_cmdline_files(image, L"initrd=", sizeof(L"initrd=") - 2,
				    soft_limit, hard_limit,
				    load_addr, load_size);
}

efi_status_t efi_load_initrd(efi_loaded_image_t *image,
			     unsigned long *load_addr,
			     unsigned long *load_size,
			     unsigned long soft_limit,
			     unsigned long hard_limit)
{
	efi_status_t status;

	if (!load_addr || !load_size)
		return EFI_INVALID_PARAMETER;

	status = efi_load_initrd_dev_path(load_addr, load_size, hard_limit);
	if (status == EFI_SUCCESS) {
		efi_info("Loaded initrd from LINUX_EFI_INITRD_MEDIA_GUID device path\n");
	} else if (status == EFI_NOT_FOUND) {
		status = efi_load_initrd_cmdline(image, load_addr, load_size,
						 soft_limit, hard_limit);
		if (status == EFI_SUCCESS && *load_size > 0)
			efi_info("Loaded initrd from command line option\n");
	}

	return status;
}
+2 −10
Original line number Diff line number Diff line
@@ -265,16 +265,8 @@ efi_status_t efi_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg)

	if (!efi_noinitrd) {
		max_addr = efi_get_max_initrd_addr(dram_base, image_addr);
		status = efi_load_initrd_dev_path(&initrd_addr, &initrd_size,
						  max_addr);
		if (status == EFI_SUCCESS) {
			efi_info("Loaded initrd from LINUX_EFI_INITRD_MEDIA_GUID device path\n");
		} else if (status == EFI_NOT_FOUND) {
		status = efi_load_initrd(image, &initrd_addr, &initrd_size,
					 ULONG_MAX, max_addr);
			if (status == EFI_SUCCESS && initrd_size > 0)
				efi_info("Loaded initrd from command line option\n");
		}
		if (status != EFI_SUCCESS)
			efi_err("Failed to load initrd!\n");
	}
+5 −16
Original line number Diff line number Diff line
@@ -677,21 +677,10 @@ static inline efi_status_t efi_load_dtb(efi_loaded_image_t *image,
				    ULONG_MAX, ULONG_MAX, load_addr, load_size);
}

static inline efi_status_t efi_load_initrd(efi_loaded_image_t *image,
efi_status_t efi_load_initrd(efi_loaded_image_t *image,
			     unsigned long *load_addr,
			     unsigned long *load_size,
			     unsigned long soft_limit,
					   unsigned long hard_limit)
{
	if (!IS_ENABLED(CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER))
		return EFI_SUCCESS;

	return handle_cmdline_files(image, L"initrd=", sizeof(L"initrd=") - 2,
				    soft_limit, hard_limit, load_addr, load_size);
}

efi_status_t efi_load_initrd_dev_path(unsigned long *load_addr,
				      unsigned long *load_size,
				      unsigned long max);
			     unsigned long hard_limit);

#endif
+2 −11
Original line number Diff line number Diff line
@@ -755,17 +755,8 @@ unsigned long efi_main(efi_handle_t handle,
	if (!efi_noinitrd) {
		unsigned long addr, size;

		status = efi_load_initrd_dev_path(&addr, &size, ULONG_MAX);
		if (status == EFI_NOT_FOUND) {
			if (efi_is_native() && image != NULL) {
		status = efi_load_initrd(image, &addr, &size,
							 hdr->initrd_addr_max,
							 ULONG_MAX);
			} else {
				addr = size = 0;
				status = EFI_SUCCESS;
			}
		}
					 hdr->initrd_addr_max, ULONG_MAX);

		if (status != EFI_SUCCESS) {
			efi_err("Failed to load initrd!\n");