[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


  • To: xen-devel@xxxxxxxxxxxxxxxxxxxx
  • From: Rafaël Kooi <rafael_andreas@xxxxxxxxxxx>
  • Date: Wed, 10 May 2023 02:18:22 +0200
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=none; dmarc=none; dkim=none; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=Co0A8XpUzSdvSffHfW1JcfS0NgGlehxe6pGZTt39HIE=; b=T5BOE9bB0TEiD5VWiQpmV7JGoup47DkMRhy1Y6WnVG6R2Nz1dioJx3xrlqr1RpOh3FRtFmDx0gBOiksojwbH5dXSMEqhHvL8Kh0gJ7fNogjiTh/s9lIWBkABKx4fkgKywqHX3q0V8Boavg0lJXNNgQAVHYwvEuBIux+5J9L71X51i9v0TbF2pBXAUZIR5ClNSc9LK/zUtly9yxCA7QHxbVeyAxg0OK0qusSGVfSQtsZujKowVj5SFYkEMs701RmSmruWKJDz+6+Rmmp23tTVDq2OuwMfIzrllGOmbp4eZV7Sn648HQa/x43ojBic33Omlf6dOCsLZpEL0EKEKRpYgw==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=JpxuxsysUsDSy+raGfwZoQG51JT6QRIdG++XXpcSoUesQw9F8jwVr0CgyxdY5R1VWVm5xIdvfHI3sWj6Z0zJJQVYrvodrggawSqPEizDJuK7Jnrj8qjgZhvnW4eb8YyOOcvawrzlq6Hzk/idD2yl1nWTqFB4j3yphKgZ+G3GHeahTanKOZ9jhTI5OZPRvtzbUuBuUFyz4tx2uI6vdxgj+JtpecFWHwvtaQ9dGM7L55c88nhG0qC6TVGbyCDBr1ZetSQnlkrB25+06IgTPZP7cUxjU59sMb0EWsMq5qpe5Akaaj/zFEQDctr5asjw4mPRl1HJG60hHHzmkr+IBo9+LQ==
  • Cc: Rafaël Kooi <rafael_andreas@xxxxxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, George Dunlap <george.dunlap@xxxxxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, Julien Grall <julien@xxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>
  • Delivery-date: Wed, 10 May 2023 05:14:14 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

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




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.