[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [XEN PATCH 2/2] x86/Dom0: Use streaming decompression for ZSTD compressed kernels
On Arch Linux kernel decompression will fail when Xen has been unified with the kernel and initramfs as a single binary. This change works for both streaming and non-streaming ZSTD content. Signed-off-by: Rafaël Kooi <rafael_andreas@xxxxxxxxxxx> --- xen/common/decompress.c | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/xen/common/decompress.c b/xen/common/decompress.c index 989336983f..cde754ffb1 100644 --- a/xen/common/decompress.c +++ b/xen/common/decompress.c @@ -3,11 +3,26 @@ #include <xen/string.h> #include <xen/decompress.h> +typedef struct _ZSTD_state +{ + void *write_buf; + unsigned int write_pos; +} ZSTD_state; + static void __init cf_check error(const char *msg) { printk("%s\n", msg); } +static int __init cf_check ZSTD_flush(void *buf, unsigned int pos, + void *userptr) +{ + ZSTD_state *state = (ZSTD_state*)userptr; + memcpy(state->write_buf + state->write_pos, buf, pos); + state->write_pos += pos; + return pos; +} + int __init decompress(void *inbuf, unsigned int len, void *outbuf) { #if 0 /* Not needed here yet. */ @@ -17,22 +32,32 @@ int __init decompress(void *inbuf, unsigned int len, void *outbuf) #endif if ( len >= 3 && !memcmp(inbuf, "\x42\x5a\x68", 3) ) - return bunzip2(inbuf, len, NULL, NULL, outbuf, NULL, error); + return bunzip2(inbuf, len, NULL, NULL, outbuf, NULL, error, NULL); if ( len >= 6 && !memcmp(inbuf, "\3757zXZ", 6) ) - return unxz(inbuf, len, NULL, NULL, outbuf, NULL, error); + return unxz(inbuf, len, NULL, NULL, outbuf, NULL, error, NULL); if ( len >= 2 && !memcmp(inbuf, "\135\000", 2) ) - return unlzma(inbuf, len, NULL, NULL, outbuf, NULL, error); + return unlzma(inbuf, len, NULL, NULL, outbuf, NULL, error, NULL); if ( len >= 5 && !memcmp(inbuf, "\x89LZO", 5) ) - return unlzo(inbuf, len, NULL, NULL, outbuf, NULL, error); + return unlzo(inbuf, len, NULL, NULL, outbuf, NULL, error, NULL); if ( len >= 2 && !memcmp(inbuf, "\x02\x21", 2) ) - return unlz4(inbuf, len, NULL, NULL, outbuf, NULL, error); + return unlz4(inbuf, len, NULL, NULL, outbuf, NULL, error, NULL); if ( len >= 4 && !memcmp(inbuf, "\x28\xb5\x2f\xfd", 4) ) - return unzstd(inbuf, len, NULL, NULL, outbuf, NULL, error); + { + // NOTE (Rafaël): On Arch Linux the kernel is compressed in a way + // that requires streaming ZSTD decompression. Otherwise decompression + // will fail when using a unified EFI binary. Somehow decompression + // works when not using a unified EFI binary, I suspect this is the + // kernel self decompressing. Or there is a code path that I am not + // aware of that takes care of the use case properly. + + ZSTD_state state = (ZSTD_state){ outbuf, 0 }; + return unzstd(inbuf, len, NULL, ZSTD_flush, NULL, NULL, error, &state); + } return 1; } -- 2.40.0
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |