Re: [PATCH v4 0/7] x86/boot: Remove runtime relocations from compressed kernel

Sedat Dilek
2020-07-14T20:17:48Z

[-- Attachment #1: Type: text/plain, Size: 1292 bytes --]

On Tue, Jul 14, 2020 at 10:14 PM Arvind Sankar <nivedita@alum.mit.edu> wrote:
>
> On Tue, Jul 14, 2020 at 10:10:14PM +0200, Sedat Dilek wrote:
> > On Tue, Jul 14, 2020 at 10:07 PM Arvind Sankar <nivedita@alum.mit.edu> wrote:
> > >
> > > On Tue, Jul 14, 2020 at 09:53:19PM +0200, Sedat Dilek wrote:
> > > >
> > > > Hmm, you might be right with moving to LDFLAGS_vmlinux.
> > > >
> > > > Attached are my linux-config and dmesg-output.
> > > >
> > > > - Sedat -
> > >
> > > Which tree are you building against? I notice you have KERNEL_ZSTD
> > > enabled, which hasn't been merged yet.
> > >
> > > Are you using Nick's series [v7]?
> > >
> > > Also from the naming -- are you using LLVM_IAS=1 with some patches to
> > > make it work?
> > >
> > > [v7] https://lore.kernel.org/lkml/20200708185024.2767937-1-nickrterrell@gmail.com/
> >
> > Sorry for not telling you the full story.
> > Yes, I have some additional patches like Nick T. "zstd-v7" which
> > should IMHO not touch this area.
> >
> > - Sedat -
>
> That series does touch boot/compressed, since the point is to add
> support for zstd-compressed kernels. I'll need to test it out, the
> __DISABLE_EXPORTS he's now using must not be working for some reason.

I have seen this in the between zstd-v6 and zstd-v7 - diff attached.

- Sedat -

[-- Attachment #2: zstd-initramfs-terrelln-v6-VS-zstd-initramfs-terrelln-v7.diff --]
[-- Type: text/x-patch, Size: 7050 bytes --]

diff --git a/Makefile b/Makefile
index fe0164a654c7..d14f9b7038ba 100644
--- a/Makefile
+++ b/Makefile
@@ -464,6 +464,7 @@ KLZOP = lzop
LZMA = lzma
LZ4 = lz4c
XZ = xz
+ZSTD = zstd

CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \
-Wbitwise -Wno-return-void -Wno-unknown-attribute $(CF)
@@ -512,7 +513,7 @@ CLANG_FLAGS :=
export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC
export CPP AR NM STRIP OBJCOPY OBJDUMP OBJSIZE READELF PAHOLE LEX YACC AWK INSTALLKERNEL
export PERL PYTHON PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX
-export KGZIP KBZIP2 KLZOP LZMA LZ4 XZ
+export KGZIP KBZIP2 KLZOP LZMA LZ4 XZ ZSTD
export KBUILD_HOSTCXXFLAGS KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS LDFLAGS_MODULE

export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS KBUILD_LDFLAGS
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
index 471e61400a2e..3498cd990869 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -146,7 +146,7 @@ $(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y) FORCE
$(obj)/vmlinux.bin.lz4: $(vmlinux.bin.all-y) FORCE
$(call if_changed,lz4)
$(obj)/vmlinux.bin.zst: $(vmlinux.bin.all-y) FORCE
- $(call if_changed,zstd)
+ $(call if_changed,zstd22)

suffix-$(CONFIG_KERNEL_GZIP) := gz
suffix-$(CONFIG_KERNEL_BZIP2) := bz2
diff --git a/lib/decompress_unzstd.c b/lib/decompress_unzstd.c
index f317afab502f..053834f24b8c 100644
--- a/lib/decompress_unzstd.c
+++ b/lib/decompress_unzstd.c
@@ -59,12 +59,15 @@
* zstd's only source dependeny is xxhash, which has no source
* dependencies.
*
- * zstd and xxhash avoid declaring themselves as modules
- * when ZSTD_PREBOOT and XXH_PREBOOT are defined.
+ * When UNZSTD_PREBOOT is defined we declare __decompress(), which is
+ * used for kernel decompression, instead of unzstd().
+ *
+ * __DISABLE_EXPORTS stops zstd and xxhash from declaring themselves
+ * as modules by disabling the EXPORT_SYMBOL macro.
*/
#ifdef STATIC
-# define ZSTD_PREBOOT
-# define XXH_PREBOOT
+# define UNZSTD_PREBOOT
+# define __DISABLE_EXPORTS
# include "xxhash.c"
# include "zstd/entropy_common.c"
# include "zstd/fse_decompress.c"
@@ -319,7 +322,7 @@ static int INIT __unzstd(unsigned char *in_buf, long in_len,
return err;
}

-#ifndef ZSTD_PREBOOT
+#ifndef UNZSTD_PREBOOT
STATIC int INIT unzstd(unsigned char *buf, long len,
long (*fill)(void*, unsigned long),
long (*flush)(void*, unsigned long),
diff --git a/lib/xxhash.c b/lib/xxhash.c
index b4364e011392..aa61e2a3802f 100644
--- a/lib/xxhash.c
+++ b/lib/xxhash.c
@@ -80,11 +80,13 @@ void xxh32_copy_state(struct xxh32_state *dst, const struct xxh32_state *src)
{
memcpy(dst, src, sizeof(*dst));
}
+EXPORT_SYMBOL(xxh32_copy_state);

void xxh64_copy_state(struct xxh64_state *dst, const struct xxh64_state *src)
{
memcpy(dst, src, sizeof(*dst));
}
+EXPORT_SYMBOL(xxh64_copy_state);

/*-***************************
* Simple Hash Functions
@@ -149,6 +151,7 @@ uint32_t xxh32(const void *input, const size_t len, const uint32_t seed)

return h32;
}
+EXPORT_SYMBOL(xxh32);

static uint64_t xxh64_round(uint64_t acc, const uint64_t input)
{
@@ -231,6 +234,7 @@ uint64_t xxh64(const void *input, const size_t len, const uint64_t seed)

return h64;
}
+EXPORT_SYMBOL(xxh64);

/*-**************************************************
* Advanced Hash Functions
@@ -247,6 +251,7 @@ void xxh32_reset(struct xxh32_state *statePtr, const uint32_t seed)
state.v4 = seed - PRIME32_1;
memcpy(statePtr, &state, sizeof(state));
}
+EXPORT_SYMBOL(xxh32_reset);

void xxh64_reset(struct xxh64_state *statePtr, const uint64_t seed)
{
@@ -260,6 +265,7 @@ void xxh64_reset(struct xxh64_state *statePtr, const uint64_t seed)
state.v4 = seed - PRIME64_1;
memcpy(statePtr, &state, sizeof(state));
}
+EXPORT_SYMBOL(xxh64_reset);

int xxh32_update(struct xxh32_state *state, const void *input, const size_t len)
{
@@ -328,6 +334,7 @@ int xxh32_update(struct xxh32_state *state, const void *input, const size_t len)

return 0;
}
+EXPORT_SYMBOL(xxh32_update);

uint32_t xxh32_digest(const struct xxh32_state *state)
{
@@ -365,6 +372,7 @@ uint32_t xxh32_digest(const struct xxh32_state *state)

return h32;
}
+EXPORT_SYMBOL(xxh32_digest);

int xxh64_update(struct xxh64_state *state, const void *input, const size_t len)
{
@@ -431,6 +439,7 @@ int xxh64_update(struct xxh64_state *state, const void *input, const size_t len)

return 0;
}
+EXPORT_SYMBOL(xxh64_update);

uint64_t xxh64_digest(const struct xxh64_state *state)
{
@@ -485,19 +494,7 @@ uint64_t xxh64_digest(const struct xxh64_state *state)

return h64;
}
-
-#ifndef XXH_PREBOOT
-EXPORT_SYMBOL(xxh32_copy_state);
-EXPORT_SYMBOL(xxh64_copy_state);
-EXPORT_SYMBOL(xxh32);
-EXPORT_SYMBOL(xxh64);
-EXPORT_SYMBOL(xxh32_reset);
-EXPORT_SYMBOL(xxh64_reset);
-EXPORT_SYMBOL(xxh32_update);
-EXPORT_SYMBOL(xxh32_digest);
-EXPORT_SYMBOL(xxh64_update);
EXPORT_SYMBOL(xxh64_digest);

MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION("xxHash");
-#endif
diff --git a/lib/zstd/decompress.c b/lib/zstd/decompress.c
index 73ded63278cf..269ee9a796c1 100644
--- a/lib/zstd/decompress.c
+++ b/lib/zstd/decompress.c
@@ -2490,7 +2490,6 @@ size_t ZSTD_decompressStream(ZSTD_DStream *zds, ZSTD_outBuffer *output, ZSTD_inB
}
}

-#ifndef ZSTD_PREBOOT
EXPORT_SYMBOL(ZSTD_DCtxWorkspaceBound);
EXPORT_SYMBOL(ZSTD_initDCtx);
EXPORT_SYMBOL(ZSTD_decompressDCtx);
@@ -2530,4 +2529,3 @@ EXPORT_SYMBOL(ZSTD_insertBlock);

MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION("Zstd Decompressor");
-#endif
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index d960f8815f87..54f7b7eb580b 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -419,14 +419,21 @@ quiet_cmd_xzmisc = XZMISC $@
# format has the size information available at the beginning of the file too,
# but it's in a more complex format and it's good to avoid changing the part
# of the boot code that reads the uncompressed size.
+#
# Note that the bytes added by size_append will make the zstd tool think that
# the file is corrupt. This is expected.
+#
+# zstd uses a maximum window size of 8 MB. zstd22 uses a maximum window size of
+# 128 MB. zstd22 is used for kernel compression because it is decompressed in a
+# single pass, so zstd doesn't need to allocate a window buffer. When streaming
+# decompression is used, like initramfs decompression, zstd22 should likely not
+# be used because it would require zstd to allocate a 128 MB buffer.

quiet_cmd_zstd = ZSTD $@
-cmd_zstd = (cat $(filter-out FORCE,$^) | \
- zstd -19 && \
- $(call size_append, $(filter-out FORCE,$^))) > $@ || \
- (rm -f $@ ; false)
+ cmd_zstd = { cat $(real-prereqs) | $(ZSTD) -19; $(size_append); } > $@
+
+quiet_cmd_zstd22 = ZSTD22 $@
+ cmd_zstd22 = { cat $(real-prereqs) | $(ZSTD) -22 --ultra; $(size_append); } > $@

# ASM offsets
# ---------------------------------------------------------------------------