Author: arekm Date: Sun Nov 27 11:32:23 2011 GMT Module: packages Tag: HEAD ---- Log message: - xz compression support from upstream prepared by archlinux
---- Files affected: packages/xen: xen.spec (1.90 -> 1.91) , xen-xz.patch (NONE -> 1.1) (NEW) ---- Diffs: ================================================================ Index: packages/xen/xen.spec diff -u packages/xen/xen.spec:1.90 packages/xen/xen.spec:1.91 --- packages/xen/xen.spec:1.90 Sun Nov 27 11:30:35 2011 +++ packages/xen/xen.spec Sun Nov 27 12:32:18 2011 @@ -12,7 +12,7 @@ Summary(pl.UTF-8): Xen - monitor maszyny wirtualnej Name: xen Version: 4.1.2 -Release: 0.2 +Release: 0.3 License: GPL Group: Applications/System Source0: http://bits.xensource.com/oss-xen/release/%{version}/%{name}-%{version}.tar.gz @@ -36,6 +36,7 @@ Patch1: %{name}-symbols.patch Patch2: %{name}-curses.patch Patch3: %{name}-gcc.patch +Patch4: %{name}-xz.patch URL: http://www.cl.cam.ac.uk/Research/SRG/netos/xen/index.html BuildRequires: SDL-devel %{?with_hvm:BuildRequires: bcc} @@ -190,6 +191,7 @@ %patch1 -p1 %patch2 -p1 #%%patch3 -p1 +%patch4 -p1 %{__rm} -v tools/check/*.orig @@ -367,6 +369,9 @@ All persons listed below can be reached at <cvs_login>@pld-linux.org $Log$ +Revision 1.91 2011/11/27 11:32:18 arekm +- xz compression support from upstream prepared by archlinux + Revision 1.90 2011/11/27 10:30:35 glen - download stubdown sources to distfiles ================================================================ Index: packages/xen/xen-xz.patch diff -u /dev/null packages/xen/xen-xz.patch:1.1 --- /dev/null Sun Nov 27 12:32:23 2011 +++ packages/xen/xen-xz.patch Sun Nov 27 12:32:18 2011 @@ -0,0 +1,3528 @@ +diff --git a/xen/common/Makefile b/xen/common/Makefile +--- a/xen/common/Makefile ++++ b/xen/common/Makefile +@@ -43,7 +43,7 @@ + obj-y += rbtree.o + obj-y += lzo.o + +-obj-$(CONFIG_X86) += decompress.o bunzip2.o unlzma.o unlzo.o ++obj-$(CONFIG_X86) += decompress.o bunzip2.o unxz.o unlzma.o unlzo.o + + obj-$(perfc) += perfc.o + obj-$(crash_debug) += gdbstub.o +diff --git a/xen/common/decompress.c b/xen/common/decompress.c +--- a/xen/common/decompress.c ++++ b/xen/common/decompress.c +@@ -20,6 +20,9 @@ + if ( len >= 3 && !memcmp(inbuf, "\x42\x5a\x68", 3) ) + return bunzip2(inbuf, len, NULL, NULL, outbuf, NULL, error); + ++ if ( len >= 6 && !memcmp(inbuf, "\3757zXZ", 6) ) ++ return unxz(inbuf, len, NULL, NULL, outbuf, NULL, error); ++ + if ( len >= 2 && !memcmp(inbuf, "\135\000", 2) ) + return unlzma(inbuf, len, NULL, NULL, outbuf, NULL, error); + +diff --git a/xen/common/decompress.h b/xen/common/decompress.h +--- a/xen/common/decompress.h ++++ b/xen/common/decompress.h +@@ -8,6 +8,7 @@ + + #define STATIC + #define INIT __init ++#define INITDATA __initdata + + static void(*__initdata error)(const char *); + #define set_error_fn(x) error = x; +diff --git a/xen/common/unxz.c b/xen/common/unxz.c +new file mode 100644 +--- /dev/null ++++ b/xen/common/unxz.c +@@ -0,0 +1,306 @@ ++/* ++ * Wrapper for decompressing XZ-compressed kernel, initramfs, and initrd ++ * ++ * Author: Lasse Collin <[email protected]> ++ * ++ * This file has been put into the public domain. ++ * You can do whatever you want with this file. ++ */ ++ ++/* ++ * Important notes about in-place decompression ++ * ++ * At least on x86, the kernel is decompressed in place: the compressed data ++ * is placed to the end of the output buffer, and the decompressor overwrites ++ * most of the compressed data. There must be enough safety margin to ++ * guarantee that the write position is always behind the read position. ++ * ++ * The safety margin for XZ with LZMA2 or BCJ+LZMA2 is calculated below. ++ * Note that the margin with XZ is bigger than with Deflate (gzip)! ++ * ++ * The worst case for in-place decompression is that the beginning of ++ * the file is compressed extremely well, and the rest of the file is ++ * uncompressible. Thus, we must look for worst-case expansion when the ++ * compressor is encoding uncompressible data. ++ * ++ * The structure of the .xz file in case of a compresed kernel is as follows. ++ * Sizes (as bytes) of the fields are in parenthesis. ++ * ++ * Stream Header (12) ++ * Block Header: ++ * Block Header (8-12) ++ * Compressed Data (N) ++ * Block Padding (0-3) ++ * CRC32 (4) ++ * Index (8-20) ++ * Stream Footer (12) ++ * ++ * Normally there is exactly one Block, but let's assume that there are ++ * 2-4 Blocks just in case. Because Stream Header and also Block Header ++ * of the first Block don't make the decompressor produce any uncompressed ++ * data, we can ignore them from our calculations. Block Headers of possible ++ * additional Blocks have to be taken into account still. With these ++ * assumptions, it is safe to assume that the total header overhead is ++ * less than 128 bytes. ++ * ++ * Compressed Data contains LZMA2 or BCJ+LZMA2 encoded data. Since BCJ ++ * doesn't change the size of the data, it is enough to calculate the ++ * safety margin for LZMA2. ++ * ++ * LZMA2 stores the data in chunks. Each chunk has a header whose size is ++ * a maximum of 6 bytes, but to get round 2^n numbers, let's assume that ++ * the maximum chunk header size is 8 bytes. After the chunk header, there ++ * may be up to 64 KiB of actual payload in the chunk. Often the payload is ++ * quite a bit smaller though; to be safe, let's assume that an average ++ * chunk has only 32 KiB of payload. ++ * ++ * The maximum uncompressed size of the payload is 2 MiB. The minimum ++ * uncompressed size of the payload is in practice never less than the ++ * payload size itself. The LZMA2 format would allow uncompressed size ++ * to be less than the payload size, but no sane compressor creates such ++ * files. LZMA2 supports storing uncompressible data in uncompressed form, ++ * so there's never a need to create payloads whose uncompressed size is ++ * smaller than the compressed size. ++ * ++ * The assumption, that the uncompressed size of the payload is never ++ * smaller than the payload itself, is valid only when talking about ++ * the payload as a whole. It is possible that the payload has parts where ++ * the decompressor consumes more input than it produces output. Calculating ++ * the worst case for this would be tricky. Instead of trying to do that, ++ * let's simply make sure that the decompressor never overwrites any bytes ++ * of the payload which it is currently reading. ++ * ++ * Now we have enough information to calculate the safety margin. We need ++ * - 128 bytes for the .xz file format headers; ++ * - 8 bytes per every 32 KiB of uncompressed size (one LZMA2 chunk header ++ * per chunk, each chunk having average payload size of 32 KiB); and ++ * - 64 KiB (biggest possible LZMA2 chunk payload size) to make sure that ++ * the decompressor never overwrites anything from the LZMA2 chunk ++ * payload it is currently reading. ++ * ++ * We get the following formula: ++ * ++ * safety_margin = 128 + uncompressed_size * 8 / 32768 + 65536 ++ * = 128 + (uncompressed_size >> 12) + 65536 ++ * ++ * For comparision, according to arch/x86/boot/compressed/misc.c, the ++ * equivalent formula for Deflate is this: ++ * ++ * safety_margin = 18 + (uncompressed_size >> 12) + 32768 ++ * ++ * Thus, when updating Deflate-only in-place kernel decompressor to ++ * support XZ, the fixed overhead has to be increased from 18+32768 bytes ++ * to 128+65536 bytes. ++ */ ++ ++#include "decompress.h" ++ ++#define XZ_EXTERN STATIC ++ ++/* ++ * For boot time use, we enable only the BCJ filter of the current ++ * architecture or none if no BCJ filter is available for the architecture. ++ */ ++#ifdef CONFIG_X86 ++# define XZ_DEC_X86 ++#endif ++#ifdef CONFIG_PPC ++# define XZ_DEC_POWERPC ++#endif ++#ifdef CONFIG_ARM ++# define XZ_DEC_ARM ++#endif ++#ifdef CONFIG_IA64 ++# define XZ_DEC_IA64 ++#endif ++#ifdef CONFIG_SPARC ++# define XZ_DEC_SPARC ++#endif ++ ++/* ++ * This will get the basic headers so that memeq() and others ++ * can be defined. ++ */ ++#include "xz/private.h" ++ ++/* ++ * memeq and memzero are not used much and any remotely sane implementation ++ * is fast enough. memcpy/memmove speed matters in multi-call mode, but ++ * the kernel image is decompressed in single-call mode, in which only ++ * memcpy speed can matter and only if there is a lot of uncompressible data ++ * (LZMA2 stores uncompressible chunks in uncompressed form). Thus, the ++ * functions below should just be kept small; it's probably not worth ++ * optimizing for speed. ++ */ ++ ++#ifndef memeq ++#define memeq(p1, p2, sz) (memcmp(p1, p2, sz) == 0) ++#endif ++ ++#ifndef memzero ++#define memzero(p, sz) memset(p, 0, sz) ++#endif ++ ++#include "xz/crc32.c" ++#include "xz/dec_stream.c" ++#include "xz/dec_lzma2.c" ++#include "xz/dec_bcj.c" ++ ++/* Size of the input and output buffers in multi-call mode */ ++#define XZ_IOBUF_SIZE 4096 ++ ++/* ++ * This function implements the API defined in <linux/decompress/generic.h>. ++ * ++ * This wrapper will automatically choose single-call or multi-call mode ++ * of the native XZ decoder API. The single-call mode can be used only when ++ * both input and output buffers are available as a single chunk, i.e. when ++ * fill() and flush() won't be used. ++ */ ++STATIC int INIT unxz(unsigned char *in, unsigned int in_size, ++ int (*fill)(void *dest, unsigned int size), ++ int (*flush)(void *src, unsigned int size), ++ unsigned char *out, unsigned int *in_used, ++ void (*error_fn)(const char *x)) ++{ ++ struct xz_buf b; ++ struct xz_dec *s; ++ enum xz_ret ret; ++ bool_t must_free_in = false; ++ ++ set_error_fn(error_fn); ++ ++ xz_crc32_init(); ++ ++ if (in_used != NULL) ++ *in_used = 0; ++ ++ if (fill == NULL && flush == NULL) ++ s = xz_dec_init(XZ_SINGLE, 0); ++ else ++ s = xz_dec_init(XZ_DYNALLOC, (uint32_t)-1); ++ ++ if (s == NULL) ++ goto error_alloc_state; ++ ++ if (flush == NULL) { ++ b.out = out; ++ b.out_size = (size_t)-1; ++ } else { ++ b.out_size = XZ_IOBUF_SIZE; ++ b.out = malloc(XZ_IOBUF_SIZE); ++ if (b.out == NULL) ++ goto error_alloc_out; ++ } ++ ++ if (in == NULL) { ++ must_free_in = true; ++ in = malloc(XZ_IOBUF_SIZE); ++ if (in == NULL) ++ goto error_alloc_in; ++ } ++ ++ b.in = in; ++ b.in_pos = 0; ++ b.in_size = in_size; ++ b.out_pos = 0; ++ ++ if (fill == NULL && flush == NULL) { ++ ret = xz_dec_run(s, &b); ++ } else { ++ do { ++ if (b.in_pos == b.in_size && fill != NULL) { ++ if (in_used != NULL) ++ *in_used += b.in_pos; ++ ++ b.in_pos = 0; ++ ++ in_size = fill(in, XZ_IOBUF_SIZE); ++ if (in_size < 0) { ++ /* ++ * This isn't an optimal error code ++ * but it probably isn't worth making ++ * a new one either. ++ */ ++ ret = XZ_BUF_ERROR; ++ break; ++ } ++ ++ b.in_size = in_size; ++ } ++ ++ ret = xz_dec_run(s, &b); ++ ++ if (flush != NULL && (b.out_pos == b.out_size ++ || (ret != XZ_OK && b.out_pos > 0))) { ++ /* ++ * Setting ret here may hide an error ++ * returned by xz_dec_run(), but probably ++ * it's not too bad. ++ */ ++ if (flush(b.out, b.out_pos) != (int)b.out_pos) ++ ret = XZ_BUF_ERROR; ++ ++ b.out_pos = 0; ++ } ++ } while (ret == XZ_OK); ++ ++ if (must_free_in) ++ free(in); ++ ++ if (flush != NULL) ++ free(b.out); ++ } ++ ++ if (in_used != NULL) ++ *in_used += b.in_pos; ++ ++ xz_dec_end(s); ++ ++ switch (ret) { ++ case XZ_STREAM_END: ++ return 0; ++ ++ case XZ_MEM_ERROR: ++ /* This can occur only in multi-call mode. */ ++ error("XZ decompressor ran out of memory"); ++ break; ++ ++ case XZ_FORMAT_ERROR: ++ error("Input is not in the XZ format (wrong magic bytes)"); ++ break; ++ ++ case XZ_OPTIONS_ERROR: ++ error("Input was encoded with settings that are not " ++ "supported by this XZ decoder"); ++ break; ++ ++ case XZ_DATA_ERROR: ++ case XZ_BUF_ERROR: ++ error("XZ-compressed data is corrupt"); ++ break; ++ ++ default: ++ error("Bug in the XZ decompressor"); ++ break; ++ } ++ ++ return -1; ++ ++error_alloc_in: ++ if (flush != NULL) ++ free(b.out); ++ ++error_alloc_out: ++ xz_dec_end(s); ++ ++error_alloc_state: ++ error("XZ decompressor ran out of memory"); ++ return -1; ++} ++ ++/* ++ * This macro is used by architecture-specific files to decompress ++ * the kernel image. ++ */ ++#define decompress unxz +diff --git a/xen/common/xz/crc32.c b/xen/common/xz/crc32.c +new file mode 100644 +--- /dev/null ++++ b/xen/common/xz/crc32.c +@@ -0,0 +1,51 @@ ++/* ++ * CRC32 using the polynomial from IEEE-802.3 ++ * ++ * Authors: Lasse Collin <[email protected]> ++ * Igor Pavlov <http://7-zip.org/> ++ * ++ * This file has been put into the public domain. ++ * You can do whatever you want with this file. ++ */ ++ ++/* ++ * This is not the fastest implementation, but it is pretty compact. ++ * The fastest versions of xz_crc32() on modern CPUs without hardware ++ * accelerated CRC instruction are 3-5 times as fast as this version, ++ * but they are bigger and use more memory for the lookup table. ++ */ ++ ++#include "private.h" ++ ++XZ_EXTERN uint32_t INITDATA xz_crc32_table[256]; ++ ++XZ_EXTERN void INIT xz_crc32_init(void) ++{ ++ const uint32_t poly = 0xEDB88320; ++ ++ uint32_t i; ++ uint32_t j; ++ uint32_t r; ++ ++ for (i = 0; i < 256; ++i) { ++ r = i; ++ for (j = 0; j < 8; ++j) ++ r = (r >> 1) ^ (poly & ~((r & 1) - 1)); ++ ++ xz_crc32_table[i] = r; ++ } ++ ++ return; ++} ++ ++XZ_EXTERN uint32_t INIT xz_crc32(const uint8_t *buf, size_t size, uint32_t crc) ++{ ++ crc = ~crc; ++ ++ while (size != 0) { ++ crc = xz_crc32_table[*buf++ ^ (crc & 0xFF)] ^ (crc >> 8); ++ --size; ++ } ++ ++ return ~crc; ++} +diff --git a/xen/common/xz/dec_bcj.c b/xen/common/xz/dec_bcj.c +new file mode 100644 +--- /dev/null ++++ b/xen/common/xz/dec_bcj.c +@@ -0,0 +1,562 @@ ++/* ++ * Branch/Call/Jump (BCJ) filter decoders ++ * ++ * Authors: Lasse Collin <[email protected]> ++ * Igor Pavlov <http://7-zip.org/> ++ * ++ * This file has been put into the public domain. ++ * You can do whatever you want with this file. ++ */ ++ ++#include "private.h" ++ ++/* ++ * The rest of the file is inside this ifdef. It makes things a little more ++ * convenient when building without support for any BCJ filters. ++ */ ++#ifdef XZ_DEC_BCJ ++ ++struct xz_dec_bcj { ++ /* Type of the BCJ filter being used */ ++ enum { ++ BCJ_X86 = 4, /* x86 or x86-64 */ ++ BCJ_POWERPC = 5, /* Big endian only */ ++ BCJ_IA64 = 6, /* Big or little endian */ ++ BCJ_ARM = 7, /* Little endian only */ ++ BCJ_ARMTHUMB = 8, /* Little endian only */ ++ BCJ_SPARC = 9 /* Big or little endian */ ++ } type; ++ ++ /* ++ * Return value of the next filter in the chain. We need to preserve ++ * this information across calls, because we must not call the next ++ * filter anymore once it has returned XZ_STREAM_END. ++ */ ++ enum xz_ret ret; ++ ++ /* True if we are operating in single-call mode. */ ++ bool_t single_call; ++ ++ /* ++ * Absolute position relative to the beginning of the uncompressed ++ * data (in a single .xz Block). We care only about the lowest 32 ++ * bits so this doesn't need to be uint64_t even with big files. ++ */ ++ uint32_t pos; ++ ++ /* x86 filter state */ ++ uint32_t x86_prev_mask; ++ ++ /* Temporary space to hold the variables from struct xz_buf */ ++ uint8_t *out; ++ size_t out_pos; ++ size_t out_size; ++ ++ struct { ++ /* Amount of already filtered data in the beginning of buf */ ++ size_t filtered; ++ ++ /* Total amount of data currently stored in buf */ ++ size_t size; ++ ++ /* ++ * Buffer to hold a mix of filtered and unfiltered data. This ++ * needs to be big enough to hold Alignment + 2 * Look-ahead: ++ * ++ * Type Alignment Look-ahead ++ * x86 1 4 ++ * PowerPC 4 0 ++ * IA-64 16 0 ++ * ARM 4 0 ++ * ARM-Thumb 2 2 ++ * SPARC 4 0 ++ */ ++ uint8_t buf[16]; ++ } temp; ++}; ++ ++#ifdef XZ_DEC_X86 ++/* ++ * This is used to test the most significant byte of a memory address ++ * in an x86 instruction. ++ */ ++static inline int INIT bcj_x86_test_msbyte(uint8_t b) ++{ ++ return b == 0x00 || b == 0xFF; ++} ++ ++static size_t INIT bcj_x86(struct xz_dec_bcj *s, uint8_t *buf, size_t size) ++{ ++ static /*const*/ bool_t INITDATA mask_to_allowed_status[8] ++ = { true, true, true, false, true, false, false, false }; ++ ++ static /*const*/ uint8_t INITDATA mask_to_bit_num[8] ++ = { 0, 1, 2, 2, 3, 3, 3, 3 }; ++ ++ size_t i; ++ size_t prev_pos = (size_t)-1; ++ uint32_t prev_mask = s->x86_prev_mask; ++ uint32_t src; ++ uint32_t dest; ++ uint32_t j; ++ uint8_t b; ++ ++ if (size <= 4) ++ return 0; ++ ++ size -= 4; ++ for (i = 0; i < size; ++i) { ++ if ((buf[i] & 0xFE) != 0xE8) ++ continue; ++ ++ prev_pos = i - prev_pos; ++ if (prev_pos > 3) { ++ prev_mask = 0; ++ } else { ++ prev_mask = (prev_mask << (prev_pos - 1)) & 7; ++ if (prev_mask != 0) { ++ b = buf[i + 4 - mask_to_bit_num[prev_mask]]; ++ if (!mask_to_allowed_status[prev_mask] ++ || bcj_x86_test_msbyte(b)) { ++ prev_pos = i; ++ prev_mask = (prev_mask << 1) | 1; ++ continue; ++ } ++ } ++ } ++ ++ prev_pos = i; ++ ++ if (bcj_x86_test_msbyte(buf[i + 4])) { ++ src = get_unaligned_le32(buf + i + 1); ++ while (true) { ++ dest = src - (s->pos + (uint32_t)i + 5); ++ if (prev_mask == 0) ++ break; ++ ++ j = mask_to_bit_num[prev_mask] * 8; ++ b = (uint8_t)(dest >> (24 - j)); ++ if (!bcj_x86_test_msbyte(b)) ++ break; ++ ++ src = dest ^ (((uint32_t)1 << (32 - j)) - 1); ++ } <<Diff was trimmed, longer than 597 lines>> ---- CVS-web: http://cvs.pld-linux.org/cgi-bin/cvsweb.cgi/packages/xen/xen.spec?r1=1.90&r2=1.91&f=u _______________________________________________ pld-cvs-commit mailing list [email protected] http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit
