aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware/efi/libstub/zboot.c
diff options
context:
space:
mode:
authorArd Biesheuvel <ardb@kernel.org>2022-09-22 12:03:52 +0200
committerArd Biesheuvel <ardb@kernel.org>2022-09-27 13:26:16 +0200
commit3c6edd9034240ce9582be3392112321336bd25bb (patch)
tree0f0aabffc23d2eed052440071db2fbc8e1a7fc34 /drivers/firmware/efi/libstub/zboot.c
parentefi: libstub: fix up the last remaining open coded boot service call (diff)
downloadlinux-dev-3c6edd9034240ce9582be3392112321336bd25bb.tar.xz
linux-dev-3c6edd9034240ce9582be3392112321336bd25bb.zip
efi: zboot: create MemoryMapped() device path for the parent if needed
LoadImage() is supposed to install an instance of the protocol EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL onto the loaded image's handle so that the program can figure out where it was loaded from. The reference implementation even does this (with a NULL protocol pointer) if the call to LoadImage() used the source buffer and size arguments, and passed NULL for the image device path. Hand rolled implementations of LoadImage may behave differently, though, and so it is better to tolerate situations where the protocol is missing. And actually, concatenating an Offset() node to a NULL device path (as we do currently) is not great either. So in cases where the protocol is absent, or when it points to NULL, construct a MemoryMapped() device node as the base node that describes the parent image's footprint in memory. Cc: Daan De Meyer <daandemeyer@fb.com> Cc: Jeremy Linton <jeremy.linton@arm.com> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Diffstat (limited to 'drivers/firmware/efi/libstub/zboot.c')
-rw-r--r--drivers/firmware/efi/libstub/zboot.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/drivers/firmware/efi/libstub/zboot.c b/drivers/firmware/efi/libstub/zboot.c
index a9f41902c908..ea72c8f27da6 100644
--- a/drivers/firmware/efi/libstub/zboot.c
+++ b/drivers/firmware/efi/libstub/zboot.c
@@ -162,6 +162,11 @@ static void append_end_node(efi_device_path_protocol_t **dp)
asmlinkage efi_status_t __efiapi
efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab)
{
+ struct efi_mem_mapped_dev_path mmdp = {
+ .header.type = EFI_DEV_HW,
+ .header.sub_type = EFI_DEV_MEM_MAPPED,
+ .header.length = sizeof(struct efi_mem_mapped_dev_path)
+ };
efi_device_path_protocol_t *parent_dp, *dpp, *lf2_dp, *li_dp;
efi_load_file2_protocol_t zboot_load_file2;
efi_loaded_image_t *parent, *child;
@@ -191,13 +196,20 @@ efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab)
status = efi_bs_call(handle_protocol, handle,
&LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID,
(void **)&parent_dp);
- if (status != EFI_SUCCESS) {
- log(L"Failed to locate parent's loaded image device path protocol");
- return status;
+ if (status != EFI_SUCCESS || parent_dp == NULL) {
+ // Create a MemoryMapped() device path node to describe
+ // the parent image if no device path was provided.
+ mmdp.memory_type = parent->image_code_type;
+ mmdp.starting_addr = (unsigned long)parent->image_base;
+ mmdp.ending_addr = (unsigned long)parent->image_base +
+ parent->image_size - 1;
+ parent_dp = &mmdp.header;
+ dp_len = sizeof(mmdp);
+ } else {
+ dp_len = device_path_length(parent_dp);
}
// Allocate some pool memory for device path protocol data
- dp_len = parent_dp ? device_path_length(parent_dp) : 0;
status = efi_bs_call(allocate_pool, EFI_LOADER_DATA,
2 * (dp_len + sizeof(struct efi_rel_offset_dev_path) +
sizeof(struct efi_generic_dev_path)) +