From: Aristo Chen Date: Fri, 10 Jul 2026 13:13:29 +0000 (+0000) Subject: bootm: teach handle_decomp_error() about the noload decompression buffer X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=79b6ee1a4b3ce9ca2db0429fc2e8dfb4110cd7e8;p=thirdparty%2Fu-boot.git bootm: teach handle_decomp_error() about the noload decompression buffer For a compressed kernel_noload image, bootm_load_os() allocates a per-image decompression buffer of ALIGN(image_len * 8, SZ_1M) rather than the global CONFIG_SYS_BOOTM_LEN. When decompression fails on that path, handle_decomp_error() still prints Image too large: increase CONFIG_SYS_BOOTM_LEN which is misleading: increasing CONFIG_SYS_BOOTM_LEN does not help because the smaller per-image buffer is the actual bound. Commit 2ff26c1e378d ("bootm: fix overflow of the noload kernel decompression buffer") worked around this by printing a follow-up note right after handle_decomp_error() returned, but the boot log then reads as two contradictory sentences. Introduce enum bootm_decomp_limit and pass it into handle_decomp_error() so the helper picks the right message in one place. For the per-image path it now prints Image too large for the per-image decompression buffer (0x100000 bytes) quoting the actual buffer size; the global path is unchanged. Drop the trailing note in bootm_load_os() so only one line is printed. Suggested-by: Simon Glass Signed-off-by: Aristo Chen Reviewed-by: Tom Rini Reviewed-by: Simon Glass --- diff --git a/boot/bootm.c b/boot/bootm.c index 803d6406be4..3bce8586834 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -575,6 +575,18 @@ static int bootm_find_other(ulong img_addr, const char *conf_ramdisk, #endif /* USE_HOSTC */ #if !defined(USE_HOSTCC) || defined(CONFIG_FIT_SIGNATURE) +/** + * enum bootm_decomp_limit - What bounded the decompression buffer. + * @BOOTM_DECOMP_LIMIT_GLOBAL: Global CONFIG_SYS_BOOTM_LEN limit. + * @BOOTM_DECOMP_LIMIT_PER_IMAGE: Per-image buffer sized from the + * compressed image (e.g. the + * kernel_noload decompression buffer). + */ +enum bootm_decomp_limit { + BOOTM_DECOMP_LIMIT_GLOBAL, + BOOTM_DECOMP_LIMIT_PER_IMAGE, +}; + /** * handle_decomp_error() - display a decompression error * @@ -585,11 +597,14 @@ static int bootm_find_other(ulong img_addr, const char *conf_ramdisk, * @comp_type: Compression type being used (IH_COMP_...) * @uncomp_size: Number of bytes uncompressed * @buf_size: Number of bytes the decompresion buffer was + * @limit: Which allocation actually bounded the buffer, so the + * hint points at the knob the reader can act on * @ret: errno error code received from compression library * Return: Appropriate BOOTM_ERR_ error code */ static int handle_decomp_error(int comp_type, size_t uncomp_size, - size_t buf_size, int ret) + size_t buf_size, + enum bootm_decomp_limit limit, int ret) { const char *name = genimg_get_comp_name(comp_type); @@ -598,10 +613,15 @@ static int handle_decomp_error(int comp_type, size_t uncomp_size, return BOOTM_ERR_UNIMPLEMENTED; if ((comp_type == IH_COMP_GZIP && ret == Z_BUF_ERROR) || - uncomp_size >= buf_size) - printf("Image too large: increase CONFIG_SYS_BOOTM_LEN\n"); - else + uncomp_size >= buf_size) { + if (limit == BOOTM_DECOMP_LIMIT_PER_IMAGE) + printf("Image too large for the per-image decompression buffer (%#zx bytes)\n", + buf_size); + else + printf("Image too large: increase CONFIG_SYS_BOOTM_LEN\n"); + } else { printf("%s: uncompress error %d\n", name, ret); + } /* * The decompression routines are now safe, so will not write beyond @@ -628,6 +648,7 @@ static int bootm_load_os(struct bootm_headers *images, int boot_progress) ulong image_start = os.image_start; ulong image_len = os.image_len; ulong decomp_len = CONFIG_SYS_BOOTM_LEN; + enum bootm_decomp_limit decomp_limit = BOOTM_DECOMP_LIMIT_GLOBAL; ulong flush_start; bool no_overlap; void *load_buf, *image_buf; @@ -644,6 +665,7 @@ static int bootm_load_os(struct bootm_headers *images, int boot_progress) phys_addr_t addr; decomp_len = ALIGN(image_len * 8, SZ_1M); + decomp_limit = BOOTM_DECOMP_LIMIT_PER_IMAGE; err = lmb_alloc_mem(LMB_MEM_ALLOC_ANY, SZ_2M, &addr, decomp_len, LMB_NONE); if (err) @@ -663,10 +685,7 @@ static int bootm_load_os(struct bootm_headers *images, int boot_progress) decomp_len, &load_end); if (err) { err = handle_decomp_error(os.comp, load_end - load, - decomp_len, err); - if (os.type == IH_TYPE_KERNEL_NOLOAD && os.comp != IH_COMP_NONE) - printf("Note: noload decompression buffer is %#lx bytes (not CONFIG_SYS_BOOTM_LEN)\n", - decomp_len); + decomp_len, decomp_limit, err); bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE); return err; } @@ -1288,7 +1307,8 @@ static int bootm_host_load_image(const void *fit, int req_image_type, free(load_buf); if (ret) { - ret = handle_decomp_error(image_comp, load_end - 0, buf_size, ret); + ret = handle_decomp_error(image_comp, load_end - 0, buf_size, + BOOTM_DECOMP_LIMIT_GLOBAL, ret); if (ret != BOOTM_ERR_UNIMPLEMENTED) return ret; }