From: Jann Horn <jannh@google.com>
To: Thomas Gleixner <tglx@linutronix.de>,
Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
Dave Hansen <dave.hansen@linux.intel.com>,
x86@kernel.org, "H. Peter Anvin" <hpa@zytor.com>,
Masahiro Yamada <masahiroy@kernel.org>,
Nathan Chancellor <nathan@kernel.org>,
Nicolas Schier <nicolas@fjasle.eu>
Cc: Ard Biesheuvel <ardb@kernel.org>,
linux-efi@vger.kernel.org,
Andrew Morton <akpm@linux-foundation.org>,
linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org,
Jann Horn <jannh@google.com>
Subject: [PATCH RFC] x86: Add CONFIG_KERNEL_UNCOMPRESSED support
Date: Tue, 21 Jan 2025 23:16:09 +0100 [thread overview]
Message-ID: <20250121-kernel-compress-fast-v1-1-fa693b6167d4@google.com> (raw)
Support storing the kernel uncompressed for developers who want to quickly
iterate with one-off kernel builds.
Store it in the usual format with a 4-byte length suffix and keep this new
codepath as close as possible to the normal path where decompression
happens.
The other compression methods offered by the kernel take some time;
even LZ4 (which the kernel uses at compression level 9) takes ~2.8
seconds to compress a 110M large vmlinux.bin on my machine.
An alternate approach to this would be to offer customization of the LZ4
compression level through a kconfig variable; and yet another approach
would be to abuse the existing gzip decompression logic by storing the
kernel as "non-compressed" DEFLATE blocks, so that the decompression code
will essentially end up just doing a bunch of memcpy() calls.
Signed-off-by: Jann Horn <jannh@google.com>
---
arch/x86/Kconfig | 1 +
arch/x86/boot/compressed/Makefile | 3 +++
arch/x86/boot/compressed/misc.c | 4 ++++
| 2 ++
drivers/firmware/efi/libstub/zboot.c | 2 ++
lib/decompress_dummy.c | 15 +++++++++++++++
scripts/Makefile.lib | 3 +++
7 files changed, 30 insertions(+)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index ef6cfea9df7333c52e331f487a0b29f037a6bf14..6d468d47861ae0b6ec6b7649af6ab4dd123eb5c8 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -250,6 +250,7 @@ config X86
select HAVE_KERNEL_LZO
select HAVE_KERNEL_XZ
select HAVE_KERNEL_ZSTD
+ select HAVE_KERNEL_UNCOMPRESSED
select HAVE_KPROBES
select HAVE_KPROBES_ON_FTRACE
select HAVE_FUNCTION_ERROR_INJECTION
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
index f2051644de9432e3466ac0ef1c4d3abc378e37d3..06079e02d9e01704cc0da06c1195854c8d0602ac 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -137,6 +137,8 @@ $(obj)/vmlinux.bin.lz4: $(vmlinux.bin.all-y) FORCE
$(call if_changed,lz4_with_size)
$(obj)/vmlinux.bin.zst: $(vmlinux.bin.all-y) FORCE
$(call if_changed,zstd22_with_size)
+$(obj)/vmlinux.bin.store: $(vmlinux.bin.all-y) FORCE
+ $(call if_changed,store_with_size)
suffix-$(CONFIG_KERNEL_GZIP) := gz
suffix-$(CONFIG_KERNEL_BZIP2) := bz2
@@ -145,6 +147,7 @@ suffix-$(CONFIG_KERNEL_XZ) := xz
suffix-$(CONFIG_KERNEL_LZO) := lzo
suffix-$(CONFIG_KERNEL_LZ4) := lz4
suffix-$(CONFIG_KERNEL_ZSTD) := zst
+suffix-$(CONFIG_KERNEL_UNCOMPRESSED) := store
quiet_cmd_mkpiggy = MKPIGGY $@
cmd_mkpiggy = $(obj)/mkpiggy $< > $@
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
index 0d37420cad0259554f8160dea0c502cb7e2fc6cd..5d514a147d5d1ae252419e4c7cdc09e9c29f110f 100644
--- a/arch/x86/boot/compressed/misc.c
+++ b/arch/x86/boot/compressed/misc.c
@@ -88,6 +88,10 @@ static int cols __section(".data");
#ifdef CONFIG_KERNEL_ZSTD
#include "../../../../lib/decompress_unzstd.c"
#endif
+
+#ifdef CONFIG_KERNEL_UNCOMPRESSED
+#include "../../../../lib/decompress_dummy.c"
+#endif
/*
* NOTE: When adding a new decompressor, please update the analysis in
* ../header.S.
--git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
index b5c79f43359bcde2c4c3c5ed796e8780f7979774..8397470231cf571a33ac75f7ca7020608e170eef 100644
--- a/arch/x86/boot/header.S
+++ b/arch/x86/boot/header.S
@@ -483,6 +483,8 @@ pref_address: .quad LOAD_PHYSICAL_ADDR # preferred load addr
# larger margin.
#
# extra_bytes = (uncompressed_size >> 8) + 131072
+#
+# Uncompressed data does not grow.
#define ZO_z_extra_bytes ((ZO_z_output_len >> 8) + 131072)
#if ZO_z_output_len > ZO_z_input_len
diff --git a/drivers/firmware/efi/libstub/zboot.c b/drivers/firmware/efi/libstub/zboot.c
index af23b3c502282f9bd644c38af445875c225cdf42..1c43a6ae5e665aa3bff3bd467c8a2f5525b1a6e9 100644
--- a/drivers/firmware/efi/libstub/zboot.c
+++ b/drivers/firmware/efi/libstub/zboot.c
@@ -27,6 +27,8 @@ static unsigned long free_mem_ptr, free_mem_end_ptr;
#include "../../../../lib/decompress_unxz.c"
#elif defined(CONFIG_KERNEL_ZSTD)
#include "../../../../lib/decompress_unzstd.c"
+#elif defined(CONFIG_KERNEL_UNCOMPRESSED)
+#include "../../../../lib/decompress_dummy.c"
#endif
extern char efi_zboot_header[];
diff --git a/lib/decompress_dummy.c b/lib/decompress_dummy.c
new file mode 100644
index 0000000000000000000000000000000000000000..49435e199a07f6ed376ff93adeae8ee08a9dd3d7
--- /dev/null
+++ b/lib/decompress_dummy.c
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0
+STATIC int INIT __decompress(unsigned char *buf, long len,
+ long (*fill)(void*, unsigned long),
+ long (*flush)(void*, unsigned long),
+ unsigned char *out_buf, long out_len,
+ long *pos,
+ void (*error)(char *x))
+{
+ if (out_len < len-4) {
+ error("output buffer too small");
+ return -1;
+ }
+ memcpy(out_buf, buf, len-4);
+ return 0;
+}
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 7395200538da89a2f6e6d21f8959f3f60d291d79..bb8116ba8ba189d5246fcb0e71c7be6e05ce5148 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -525,6 +525,9 @@ quiet_cmd_zstd22 = ZSTD22 $@
quiet_cmd_zstd22_with_size = ZSTD22 $@
cmd_zstd22_with_size = { cat $(real-prereqs) | $(ZSTD) -22 --ultra; $(size_append); } > $@
+quiet_cmd_store_with_size = STORE $@
+ cmd_store_with_size = { cat $(real-prereqs); $(size_append); } > $@
+
# ASM offsets
# ---------------------------------------------------------------------------
---
base-commit: 95ec54a420b8f445e04a7ca0ea8deb72c51fe1d3
change-id: 20250121-kernel-compress-fast-350ce5801c28
--
Jann Horn <jannh@google.com>
next reply other threads:[~2025-01-21 22:16 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-21 22:16 Jann Horn [this message]
2025-01-22 13:30 ` [PATCH RFC] x86: Add CONFIG_KERNEL_UNCOMPRESSED support Ard Biesheuvel
2025-01-22 13:54 ` Jann Horn
2025-01-22 14:19 ` Tor Vic
2025-01-22 14:30 ` Jann Horn
2025-01-22 14:52 ` Tor Vic
2025-01-22 14:21 ` Ard Biesheuvel
2025-02-23 18:33 ` Ingo Molnar
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=20250121-kernel-compress-fast-v1-1-fa693b6167d4@google.com \
--to=jannh@google.com \
--cc=akpm@linux-foundation.org \
--cc=ardb@kernel.org \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=hpa@zytor.com \
--cc=linux-efi@vger.kernel.org \
--cc=linux-kbuild@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=masahiroy@kernel.org \
--cc=mingo@redhat.com \
--cc=nathan@kernel.org \
--cc=nicolas@fjasle.eu \
--cc=tglx@linutronix.de \
--cc=x86@kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox