diff mbox series

[3/3] spl: fit: Load compressed blob to heap buffer

Message ID 20231103143426.3643712-3-loic.poulain@linaro.org
State New
Headers show
Series [1/3] spl: fit: Discard decompression if not supported | expand

Commit Message

Loic Poulain Nov. 3, 2023, 2:34 p.m. UTC
CONFIG_SYS_LOAD_ADDR is usually configured as the address where
the kernel should be loaded at. It can be problematic to use it
as a generic temporary buffer for FIT compressed blobs.

An example is when the image is a compressed kernel with load
address equal to CONFIG_SYS_LOAD_ADDR, this causes (inplace)
decompression to fail.

Instead we can simply allocate a temporary buffer in the heap

Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
---
 common/spl/spl_fit.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

Comments

Sean Anderson Nov. 4, 2023, 3:13 p.m. UTC | #1
On 11/3/23 10:34, Loic Poulain wrote:
> CONFIG_SYS_LOAD_ADDR is usually configured as the address where
> the kernel should be loaded at. It can be problematic to use it
> as a generic temporary buffer for FIT compressed blobs.
> 
> An example is when the image is a compressed kernel with load
> address equal to CONFIG_SYS_LOAD_ADDR, this causes (inplace)
> decompression to fail.
> 
> Instead we can simply allocate a temporary buffer in the heap
> 
> Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
> ---
>   common/spl/spl_fit.c | 16 ++++++++++------
>   1 file changed, 10 insertions(+), 6 deletions(-)
> 
> diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
> index 08428660b0..8a807db5ba 100644
> --- a/common/spl/spl_fit.c
> +++ b/common/spl/spl_fit.c
> @@ -249,7 +249,7 @@ static int load_simple_fit(struct spl_load_info *info, ulong sector,
>   	ulong size;
>   	ulong load_addr;
>   	void *load_ptr;
> -	void *src;
> +	void *src, *src_ptr;
>   	ulong overhead;
>   	int nr_sectors;
>   	uint8_t image_comp, type = -1;
> @@ -289,8 +289,6 @@ static int load_simple_fit(struct spl_load_info *info, ulong sector,
>   	}
>   
>   	if (external_data) {
> -		void *src_ptr;
> -
>   		/* External data */
>   		if (fit_image_get_data_size(fit, node, &len))
>   			return -ENOENT;
> @@ -302,10 +300,13 @@ static int load_simple_fit(struct spl_load_info *info, ulong sector,
>   			return 0;
>   		}
>   
> -		if (image_comp != IH_COMP_NONE)
> -			src_ptr = map_sysmem(ALIGN(CONFIG_SYS_LOAD_ADDR, ARCH_DMA_MINALIGN), len);
> -		else
> +		if (image_comp != IH_COMP_NONE) {
> +			src_ptr = malloc_cache_aligned(len + 2 * info->bl_len);
> +			if (!src_ptr)
> +				return -ENOMEM;
> +		} else {
>   			src_ptr = map_sysmem(ALIGN(load_addr, ARCH_DMA_MINALIGN), len);
> +		}
>   		length = len;
>   
>   		overhead = get_aligned_image_overhead(info, offset);
> @@ -383,6 +384,9 @@ static int load_simple_fit(struct spl_load_info *info, ulong sector,
>   			image_info->entry_point = FDT_ERROR;
>   	}
>   
> +	if (external_data && image_comp != IH_COMP_NONE)
> +		free(src_ptr);
> +
>   	return 0;
>   }
>   

Why not use spl_simple_fit_read?

--Sean
diff mbox series

Patch

diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
index 08428660b0..8a807db5ba 100644
--- a/common/spl/spl_fit.c
+++ b/common/spl/spl_fit.c
@@ -249,7 +249,7 @@  static int load_simple_fit(struct spl_load_info *info, ulong sector,
 	ulong size;
 	ulong load_addr;
 	void *load_ptr;
-	void *src;
+	void *src, *src_ptr;
 	ulong overhead;
 	int nr_sectors;
 	uint8_t image_comp, type = -1;
@@ -289,8 +289,6 @@  static int load_simple_fit(struct spl_load_info *info, ulong sector,
 	}
 
 	if (external_data) {
-		void *src_ptr;
-
 		/* External data */
 		if (fit_image_get_data_size(fit, node, &len))
 			return -ENOENT;
@@ -302,10 +300,13 @@  static int load_simple_fit(struct spl_load_info *info, ulong sector,
 			return 0;
 		}
 
-		if (image_comp != IH_COMP_NONE)
-			src_ptr = map_sysmem(ALIGN(CONFIG_SYS_LOAD_ADDR, ARCH_DMA_MINALIGN), len);
-		else
+		if (image_comp != IH_COMP_NONE) {
+			src_ptr = malloc_cache_aligned(len + 2 * info->bl_len);
+			if (!src_ptr)
+				return -ENOMEM;
+		} else {
 			src_ptr = map_sysmem(ALIGN(load_addr, ARCH_DMA_MINALIGN), len);
+		}
 		length = len;
 
 		overhead = get_aligned_image_overhead(info, offset);
@@ -383,6 +384,9 @@  static int load_simple_fit(struct spl_load_info *info, ulong sector,
 			image_info->entry_point = FDT_ERROR;
 	}
 
+	if (external_data && image_comp != IH_COMP_NONE)
+		free(src_ptr);
+
 	return 0;
 }