From: Aristo Chen <aristo.chen@canonical.com>
To: u-boot@lists.u-boot-project.org
Cc: sjg@chromium.org, nora.schiffer@ew.tq-group.com,
Aristo Chen <aristo.chen@canonical.com>,
Tom Rini <trini@konsulko.com>
Subject: [PATCH v2 3/8] bootm: size the noload zstd decompression buffer from Frame_Content_Size
Date: Tue, 18 Aug 2026 13:23:17 +0000 [thread overview]
Message-ID: <20260818132332.324173-4-aristo.chen@canonical.com> (raw)
In-Reply-To: <20260818132332.324173-1-aristo.chen@canonical.com>
Add a small static helper bootm_zstd_uncompressed_size() that returns
the frame's Frame_Content_Size via zstd_get_frame_header(), and wire
it into bootm_load_os() as a new case in the size-hint switch
alongside the existing gzip case.
zstd_get_frame_header() and the frame-parsing code behind it ship
with the zstd decompressor, which is already linked into any board
that enables ZSTD, so calling it here adds no new zstd code to the
image. The returned value is used as an allocation hint only and is
capped by the caller; full validation still runs inside
zstd_decompress() during the actual decompression.
Signed-off-by: Aristo Chen <aristo.chen@canonical.com>
---
boot/bootm.c | 44 ++++++++++++++++++++++++++++++++++++++------
1 file changed, 38 insertions(+), 6 deletions(-)
diff --git a/boot/bootm.c b/boot/bootm.c
index ab787979f2e..e4284fe9844 100644
--- a/boot/bootm.c
+++ b/boot/bootm.c
@@ -25,6 +25,7 @@
#include <asm/io.h>
#include <asm/unaligned.h>
#include <linux/sizes.h>
+#include <linux/zstd.h>
#include <tpm-v2.h>
#include <tpm_tcg2.h>
#if defined(CONFIG_CMD_USB)
@@ -657,6 +658,31 @@ static ulong bootm_gzip_uncompressed_size(const void *src, ulong len)
}
#endif
+#if CONFIG_IS_ENABLED(ZSTD)
+/*
+ * Return the zstd frame's Frame_Content_Size, or 0 if the header does
+ * not parse or the size is absent. zstd_get_frame_header() and the
+ * frame-parsing code behind it are part of the zstd decompressor that
+ * is already linked into any board with ZSTD enabled, so the call adds
+ * only the call site. The value is an allocation hint; the decoder
+ * stays authoritative during the actual decompression.
+ */
+static ulong bootm_zstd_uncompressed_size(const void *src, ulong len)
+{
+ zstd_frame_header hdr;
+ size_t ret;
+
+ ret = zstd_get_frame_header(&hdr, src, len);
+ if (zstd_is_error(ret) || ret > 0)
+ return 0;
+ if (hdr.frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN ||
+ hdr.frameContentSize == ZSTD_CONTENTSIZE_ERROR ||
+ hdr.frameContentSize > ULONG_MAX)
+ return 0;
+ return (ulong)hdr.frameContentSize;
+}
+#endif
+
static int bootm_load_os(struct bootm_headers *images, int boot_progress)
{
const struct image_info os = images->os;
@@ -678,12 +704,12 @@ static int bootm_load_os(struct bootm_headers *images, int boot_progress)
/*
* For a "noload" compressed kernel we need to allocate a buffer large
* enough to decompress in to and use that as the load address now.
- * For a gzip stream the trailing 4-byte ISIZE field holds the
- * original size modulo 2^32; when it is present and within
- * CONFIG_SYS_BOOTM_LEN, allocate exactly that. Otherwise fall back
- * to an 8x multiplier, which comfortably covers what zstd and xz
- * achieve on real kernels with headroom for well-compressed
- * payloads. Use an alignment of 2MB since this might help arm64.
+ * When the compressed stream records its uncompressed size and that
+ * value is within CONFIG_SYS_BOOTM_LEN, allocate exactly that.
+ * Otherwise fall back to an 8x multiplier, which comfortably covers
+ * what zstd and xz achieve on real kernels with headroom for
+ * well-compressed payloads. Use an alignment of 2MB since this
+ * might help arm64.
*/
if (os.type == IH_TYPE_KERNEL_NOLOAD && os.comp != IH_COMP_NONE) {
phys_addr_t addr;
@@ -695,6 +721,12 @@ static int bootm_load_os(struct bootm_headers *images, int boot_progress)
hdr_size = bootm_gzip_uncompressed_size(image_buf,
image_len);
break;
+#endif
+#if CONFIG_IS_ENABLED(ZSTD)
+ case IH_COMP_ZSTD:
+ hdr_size = bootm_zstd_uncompressed_size(image_buf,
+ image_len);
+ break;
#endif
default:
break;
--
2.43.0
next prev parent reply other threads:[~2026-08-18 13:50 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-09 4:23 [PATCH 0/3] bootm: size the noload buffer from the compressor header Aristo Chen via U-Boot
2026-08-09 4:23 ` [PATCH 1/3] bootm: size the noload decompression " Aristo Chen via U-Boot
2026-08-09 15:27 ` Tom Rini
2026-08-10 2:32 ` Aristo Chen via U-Boot
2026-08-10 16:37 ` Tom Rini
2026-08-12 7:45 ` Nora Schiffer
2026-08-12 15:57 ` Tom Rini
2026-08-15 18:33 ` Simon Glass
2026-08-17 16:01 ` Aristo Chen via U-Boot
2026-08-17 19:24 ` Tom Rini
2026-08-09 4:23 ` [PATCH 2/3] test: fit: cover the kernel_noload header-size and lying-header paths Aristo Chen via U-Boot
2026-08-09 4:23 ` [PATCH 3/3] test: lib: cover image_decomp_get_uncompressed_size() for lzma streams Aristo Chen via U-Boot
2026-08-18 13:23 ` [PATCH v2 0/8] bootm: size the noload buffer from the compressor header Aristo Chen
2026-08-18 13:23 ` [PATCH v2 1/8] bootm: size the noload gzip decompression buffer from ISIZE Aristo Chen
2026-08-18 13:23 ` [PATCH v2 2/8] test: fit: cover the kernel_noload gzip header-size and lying-header paths Aristo Chen
2026-08-18 13:23 ` Aristo Chen [this message]
2026-08-18 13:23 ` [PATCH v2 4/8] test: fit: cover the kernel_noload zstd header-size path Aristo Chen
2026-08-18 13:23 ` [PATCH v2 5/8] bootm: size the noload lz4 decompression buffer from Content_Size Aristo Chen
2026-08-18 13:23 ` [PATCH v2 6/8] test: fit: cover the kernel_noload lz4 header-size path Aristo Chen
2026-08-18 13:23 ` [PATCH v2 7/8] bootm: size the noload lzma decompression buffer from the header Aristo Chen
2026-08-18 13:23 ` [PATCH v2 8/8] test: fit: cover the kernel_noload lzma header-size and unknown-size paths Aristo Chen
2026-08-18 22:10 ` [PATCH v2 0/8] bootm: size the noload buffer from the compressor header Tom Rini
2026-08-19 14:53 ` Aristo Chen
2026-08-21 18:55 ` Tom Rini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260818132332.324173-4-aristo.chen@canonical.com \
--to=aristo.chen@canonical.com \
--cc=nora.schiffer@ew.tq-group.com \
--cc=sjg@chromium.org \
--cc=trini@konsulko.com \
--cc=u-boot@lists.u-boot-project.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.