@@ -482,37 +482,50 @@ 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 either from the LoadFile2 initrd
+ * loading protocol installed on the loaded image
+ * handle, or 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
- * case @load_addr and @load_size are assigned accordingly
- * * %EFI_NOT_FOUND if no LoadFile2 protocol exists on the initrd device path
+ * * %EFI_SUCCESS if the initrd was loaded successfully, in which case the base
+ * and size members of @initrd are assigned accordingly
+ * * %EFI_NOT_FOUND if no LoadFile2 protocol exists on the loaded image handle
+ * or on the initrd device path
* * %EFI_OUT_OF_RESOURCES if memory allocation failed
* * %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;
- const efi_device_path_protocol_t *dp;
+ efi_guid_t initrd_lf2_proto_guid = LINUX_EFI_INITRD_LF2_PROTOCOL_GUID;
+ const efi_device_path_protocol_t *dp = &initrd_dev_path.end;
efi_load_file2_protocol_t *lf2;
efi_handle_t handle;
efi_status_t status;
- dp = &initrd_dev_path.vendor.header;
- 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 = &initrd_dev_path.vendor.header;
+ 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 +580,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)
@@ -417,6 +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)
@@ -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