diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c
index d1026c6a544058b4..7ca993fd0e331637 100644
--- a/drivers/firmware/efi/libstub/efi-stub-helper.c
+++ b/drivers/firmware/efi/libstub/efi-stub-helper.c
@@ -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)
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 04a733f0ba956211..08a1518de0fb4921 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -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)
 
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
