mirror of
				https://xff.cz/git/u-boot/
				synced 2025-10-31 10:26:10 +01:00 
			
		
		
		
	efi_loader: allow concatenation with contained end node
Allow appending a device-path to a device-path that contains an end node as separator. We need this feature for creating boot options specifying kernel, initrd, and dtb. Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com> Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
This commit is contained in:
		| @@ -530,7 +530,7 @@ struct efi_device_path *eficonfig_create_device_path(struct efi_device_path *dp_ | |||||||
| 	dp = efi_dp_shorten(dp_volume); | 	dp = efi_dp_shorten(dp_volume); | ||||||
| 	if (!dp) | 	if (!dp) | ||||||
| 		dp = dp_volume; | 		dp = dp_volume; | ||||||
| 	dp = efi_dp_concat(dp, &fp->dp, false); | 	dp = efi_dp_concat(dp, &fp->dp, 0); | ||||||
| 	free(buf); | 	free(buf); | ||||||
|  |  | ||||||
| 	return dp; | 	return dp; | ||||||
| @@ -1484,7 +1484,7 @@ static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_bo | |||||||
| 			goto out; | 			goto out; | ||||||
| 		} | 		} | ||||||
| 		initrd_dp = efi_dp_concat((const struct efi_device_path *)&id_dp, | 		initrd_dp = efi_dp_concat((const struct efi_device_path *)&id_dp, | ||||||
| 					  dp, false); | 					  dp, 0); | ||||||
| 		efi_free_pool(dp); | 		efi_free_pool(dp); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -1495,7 +1495,7 @@ static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_bo | |||||||
| 	} | 	} | ||||||
| 	final_dp_size = efi_dp_size(dp) + sizeof(END); | 	final_dp_size = efi_dp_size(dp) + sizeof(END); | ||||||
| 	if (initrd_dp) { | 	if (initrd_dp) { | ||||||
| 		final_dp = efi_dp_concat(dp, initrd_dp, true); | 		final_dp = efi_dp_concat(dp, initrd_dp, 1); | ||||||
| 		final_dp_size += efi_dp_size(initrd_dp) + sizeof(END); | 		final_dp_size += efi_dp_size(initrd_dp) + sizeof(END); | ||||||
| 	} else { | 	} else { | ||||||
| 		final_dp = efi_dp_dup(dp); | 		final_dp = efi_dp_dup(dp); | ||||||
|   | |||||||
| @@ -696,7 +696,7 @@ struct efi_device_path *create_initrd_dp(const char *dev, const char *part, | |||||||
| 		short_fp = tmp_fp; | 		short_fp = tmp_fp; | ||||||
|  |  | ||||||
| 	initrd_dp = efi_dp_concat((const struct efi_device_path *)&id_dp, | 	initrd_dp = efi_dp_concat((const struct efi_device_path *)&id_dp, | ||||||
| 				  short_fp, false); | 				  short_fp, 0); | ||||||
|  |  | ||||||
| out: | out: | ||||||
| 	efi_free_pool(tmp_dp); | 	efi_free_pool(tmp_dp); | ||||||
| @@ -916,7 +916,7 @@ static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag, | |||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	final_fp = efi_dp_concat(file_path, initrd_dp, true); | 	final_fp = efi_dp_concat(file_path, initrd_dp, 1); | ||||||
| 	if (!final_fp) { | 	if (!final_fp) { | ||||||
| 		printf("Cannot create final device path\n"); | 		printf("Cannot create final device path\n"); | ||||||
| 		r = CMD_RET_FAILURE; | 		r = CMD_RET_FAILURE; | ||||||
|   | |||||||
| @@ -946,7 +946,7 @@ struct efi_device_path *efi_dp_from_lo(struct efi_load_option *lo, | |||||||
| 				       const efi_guid_t *guid); | 				       const efi_guid_t *guid); | ||||||
| struct efi_device_path *efi_dp_concat(const struct efi_device_path *dp1, | struct efi_device_path *efi_dp_concat(const struct efi_device_path *dp1, | ||||||
| 				      const struct efi_device_path *dp2, | 				      const struct efi_device_path *dp2, | ||||||
| 				      bool split_end_node); | 				      size_t split_end_node); | ||||||
| struct efi_device_path *search_gpt_dp_node(struct efi_device_path *device_path); | struct efi_device_path *search_gpt_dp_node(struct efi_device_path *device_path); | ||||||
| efi_status_t efi_deserialize_load_option(struct efi_load_option *lo, u8 *data, | efi_status_t efi_deserialize_load_option(struct efi_load_option *lo, u8 *data, | ||||||
| 					 efi_uintn_t *size); | 					 efi_uintn_t *size); | ||||||
|   | |||||||
| @@ -150,7 +150,7 @@ efi_status_t efi_run_image(void *source_buffer, efi_uintn_t source_size) | |||||||
| 		msg_path = file_path; | 		msg_path = file_path; | ||||||
| 	} else { | 	} else { | ||||||
| 		file_path = efi_dp_concat(bootefi_device_path, | 		file_path = efi_dp_concat(bootefi_device_path, | ||||||
| 					  bootefi_image_path, false); | 					  bootefi_image_path, 0); | ||||||
| 		msg_path = bootefi_image_path; | 		msg_path = bootefi_image_path; | ||||||
| 		log_debug("Loaded from disk\n"); | 		log_debug("Loaded from disk\n"); | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -130,7 +130,7 @@ static efi_status_t try_load_from_file_path(efi_handle_t *fs_handles, | |||||||
| 		if (!dp) | 		if (!dp) | ||||||
| 			continue; | 			continue; | ||||||
|  |  | ||||||
| 		dp = efi_dp_concat(dp, fp, false); | 		dp = efi_dp_concat(dp, fp, 0); | ||||||
| 		if (!dp) | 		if (!dp) | ||||||
| 			continue; | 			continue; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1816,7 +1816,7 @@ efi_status_t efi_setup_loaded_image(struct efi_device_path *device_path, | |||||||
| 	if (device_path) { | 	if (device_path) { | ||||||
| 		info->device_handle = efi_dp_find_obj(device_path, NULL, NULL); | 		info->device_handle = efi_dp_find_obj(device_path, NULL, NULL); | ||||||
|  |  | ||||||
| 		dp = efi_dp_concat(device_path, file_path, false); | 		dp = efi_dp_concat(device_path, file_path, 0); | ||||||
| 		if (!dp) { | 		if (!dp) { | ||||||
| 			ret = EFI_OUT_OF_RESOURCES; | 			ret = EFI_OUT_OF_RESOURCES; | ||||||
| 			goto failure; | 			goto failure; | ||||||
|   | |||||||
| @@ -276,10 +276,11 @@ struct efi_device_path *efi_dp_dup(const struct efi_device_path *dp) | |||||||
|  * |  * | ||||||
|  * @dp1:	    First device path |  * @dp1:	    First device path | ||||||
|  * @dp2:	    Second device path |  * @dp2:	    Second device path | ||||||
|  * @split_end_node: If true the two device paths will be concatenated and |  * @split_end_node: | ||||||
|  *                  separated by an end node (DEVICE_PATH_SUB_TYPE_END). |  * * 0 to concatenate | ||||||
|  *		    If false the second device path will be concatenated to the |  * * 1 to concatenate with end node added as separator | ||||||
|  *		    first one as-is. |  * * size of dp1 excluding last end node to concatenate with end node as | ||||||
|  |  *   separator in case dp1 contains an end node | ||||||
|  * |  * | ||||||
|  * Return: |  * Return: | ||||||
|  * concatenated device path or NULL. Caller must free the returned value |  * concatenated device path or NULL. Caller must free the returned value | ||||||
| @@ -287,7 +288,7 @@ struct efi_device_path *efi_dp_dup(const struct efi_device_path *dp) | |||||||
| struct | struct | ||||||
| efi_device_path *efi_dp_concat(const struct efi_device_path *dp1, | efi_device_path *efi_dp_concat(const struct efi_device_path *dp1, | ||||||
| 			       const struct efi_device_path *dp2, | 			       const struct efi_device_path *dp2, | ||||||
| 			       bool split_end_node) | 			       size_t split_end_node) | ||||||
| { | { | ||||||
| 	struct efi_device_path *ret; | 	struct efi_device_path *ret; | ||||||
| 	size_t end_size; | 	size_t end_size; | ||||||
| @@ -301,10 +302,15 @@ efi_device_path *efi_dp_concat(const struct efi_device_path *dp1, | |||||||
| 		ret = efi_dp_dup(dp1); | 		ret = efi_dp_dup(dp1); | ||||||
| 	} else { | 	} else { | ||||||
| 		/* both dp1 and dp2 are non-null */ | 		/* both dp1 and dp2 are non-null */ | ||||||
| 		unsigned sz1 = efi_dp_size(dp1); | 		size_t sz1; | ||||||
| 		unsigned sz2 = efi_dp_size(dp2); | 		size_t sz2 = efi_dp_size(dp2); | ||||||
| 		void *p; | 		void *p; | ||||||
|  |  | ||||||
|  | 		if (split_end_node < sizeof(struct efi_device_path)) | ||||||
|  | 			sz1 = efi_dp_size(dp1); | ||||||
|  | 		else | ||||||
|  | 			sz1 = split_end_node; | ||||||
|  |  | ||||||
| 		if (split_end_node) | 		if (split_end_node) | ||||||
| 			end_size = 2 * sizeof(END); | 			end_size = 2 * sizeof(END); | ||||||
| 		else | 		else | ||||||
|   | |||||||
| @@ -76,7 +76,7 @@ static struct efi_device_path * EFIAPI append_device_path( | |||||||
| 	const struct efi_device_path *src2) | 	const struct efi_device_path *src2) | ||||||
| { | { | ||||||
| 	EFI_ENTRY("%pD, %pD", src1, src2); | 	EFI_ENTRY("%pD, %pD", src1, src2); | ||||||
| 	return EFI_EXIT(efi_dp_concat(src1, src2, false)); | 	return EFI_EXIT(efi_dp_concat(src1, src2, 0)); | ||||||
| } | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user