+ b.in_pos = 0;
+
+ in_size = fill(in, XZ_IOBUF_SIZE);
-+ if (in_size < 0) {
++ if ((int) in_size < 0) {
+ /*
+ * This isn't an optimal error code
+ * but it probably isn't worth making
new file mode 100644
--- /dev/null
+++ b/xen/common/xz/dec_bcj.c
-@@ -0,0 +1,562 @@
+@@ -0,0 +1,575 @@
+/*
+ * Branch/Call/Jump (BCJ) filter decoders
+ *
+ * next filter in the chain. Apply the BCJ filter on the new data
+ * in the output buffer. If everything cannot be filtered, copy it
+ * to temp and rewind the output buffer position accordingly.
++ *
++ * This needs to be always run when temp.size == 0 to handle a special
++ * case where the output buffer is full and the next filter has no
++ * more output coming but hasn't returned XZ_STREAM_END yet.
+ */
-+ if (s->temp.size < b->out_size - b->out_pos) {
++ if (s->temp.size < b->out_size - b->out_pos || s->temp.size == 0) {
+ out_start = b->out_pos;
+ memcpy(b->out + b->out_pos, s->temp.buf, s->temp.size);
+ b->out_pos += s->temp.size;
+ s->temp.size = b->out_pos - out_start;
+ b->out_pos -= s->temp.size;
+ memcpy(s->temp.buf, b->out + b->out_pos, s->temp.size);
++
++ /*
++ * If there wasn't enough input to the next filter to fill
++ * the output buffer with unfiltered data, there's no point
++ * to try decoding more data to temp.
++ */
++ if (b->out_pos + s->temp.size < b->out_size)
++ return XZ_OK;
+ }
+
+ /*
-+ * If we have unfiltered data in temp, try to fill by decoding more
-+ * data from the next filter. Apply the BCJ filter on temp. Then we
-+ * hopefully can fill the actual output buffer by copying filtered
-+ * data from temp. A mix of filtered and unfiltered data may be left
-+ * in temp; it will be taken care on the next call to this function.
++ * We have unfiltered data in temp. If the output buffer isn't full
++ * yet, try to fill the temp buffer by decoding more data from the
++ * next filter. Apply the BCJ filter on temp. Then we hopefully can
++ * fill the actual output buffer by copying filtered data from temp.
++ * A mix of filtered and unfiltered data may be left in temp; it will
++ * be taken care on the next call to this function.
+ */
-+ if (s->temp.size > 0) {
++ if (b->out_pos < b->out_size) {
+ /* Make b->out{,_pos,_size} temporarily point to s->temp. */
+ s->out = b->out;
+ s->out_pos = b->out_pos;
+ */
+ tmp = b->in[b->in_pos++];
+
++ if (tmp == 0x00)
++ return XZ_STREAM_END;
++
+ if (tmp >= 0xE0 || tmp == 0x01) {
+ s->lzma2.need_props = true;
+ s->lzma2.need_dict_reset = false;
+ lzma_reset(s);
+ }
+ } else {
-+ if (tmp == 0x00)
-+ return XZ_STREAM_END;
-+
+ if (tmp > 0x02)
+ return XZ_DATA_ERROR;
+
int decompress(void *inbuf, unsigned int len, void *outbuf);
+--- a/tools/libxc/xc_dom_bzimageloader.c 2011-10-20 19:05:42.000000000 +0200
++++ b/tools/libxc/xc_dom_bzimageloader.c 2012-03-04 23:34:53.797635804 +0100
+@@ -163,11 +163,10 @@
+
+ #include <lzma.h>
+
+-static int xc_try_lzma_decode(
+- struct xc_dom_image *dom, void **blob, size_t *size)
++static int _xc_try_lzma_decode(
++ struct xc_dom_image *dom, void **blob, size_t *size,
++ lzma_stream *stream, lzma_ret ret, const char *what)
+ {
+- lzma_stream stream = LZMA_STREAM_INIT;
+- lzma_ret ret;
+ lzma_action action = LZMA_RUN;
+ unsigned char *out_buf;
+ unsigned char *tmp_buf;
+@@ -175,10 +174,9 @@
+ int outsize;
+ const char *msg;
+
+- ret = lzma_alone_decoder(&stream, 128*1024*1024);
+ if ( ret != LZMA_OK )
+ {
+- DOMPRINTF("LZMA: Failed to init stream decoder");
++ DOMPRINTF("%s: Failed to init decoder", what);
+ return -1;
+ }
+
+@@ -190,22 +188,22 @@
+ out_buf = malloc(outsize);
+ if ( out_buf == NULL )
+ {
+- DOMPRINTF("LZMA: Failed to alloc memory");
++ DOMPRINTF("%s: Failed to alloc memory", what);
+ goto lzma_cleanup;
+ }
+
+- stream.next_in = dom->kernel_blob;
+- stream.avail_in = dom->kernel_size;
++ stream->next_in = dom->kernel_blob;
++ stream->avail_in = dom->kernel_size;
+
+- stream.next_out = out_buf;
+- stream.avail_out = dom->kernel_size;
++ stream->next_out = out_buf;
++ stream->avail_out = dom->kernel_size;
+
+ for ( ; ; )
+ {
+- ret = lzma_code(&stream, action);
++ ret = lzma_code(stream, action);
+ if ( ret == LZMA_STREAM_END )
+ {
+- DOMPRINTF("LZMA: Saw data stream end");
++ DOMPRINTF("%s: Saw data stream end", what);
+ retval = 0;
+ break;
+ }
+@@ -242,18 +240,18 @@
+ msg = "Internal program error (bug)";
+ break;
+ }
+- DOMPRINTF("%s: LZMA decompression error %s",
+- __FUNCTION__, msg);
++ DOMPRINTF("%s: %s decompression error %s",
++ __FUNCTION__, what, msg);
+ free(out_buf);
+ goto lzma_cleanup;
+ }
+
+- if ( stream.avail_out == 0 )
++ if ( stream->avail_out == 0 )
+ {
+ /* Protect against output buffer overflow */
+ if ( outsize > INT_MAX / 2 )
+ {
+- DOMPRINTF("LZMA: output buffer overflow");
++ DOMPRINTF("%s: output buffer overflow", what);
+ free(out_buf);
+ goto lzma_cleanup;
+ }
+@@ -261,32 +259,61 @@
+ tmp_buf = realloc(out_buf, outsize * 2);
+ if ( tmp_buf == NULL )
+ {
+- DOMPRINTF("LZMA: Failed to realloc memory");
++ DOMPRINTF("%s: Failed to realloc memory", what);
+ free(out_buf);
+ goto lzma_cleanup;
+ }
+ out_buf = tmp_buf;
+
+- stream.next_out = out_buf + outsize;
+- stream.avail_out = (outsize * 2) - outsize;
++ stream->next_out = out_buf + outsize;
++ stream->avail_out = (outsize * 2) - outsize;
+ outsize *= 2;
+ }
+ }
+
+- DOMPRINTF("%s: LZMA decompress OK, 0x%zx -> 0x%zx",
+- __FUNCTION__, *size, (size_t)stream.total_out);
++ DOMPRINTF("%s: %s decompress OK, 0x%zx -> 0x%zx",
++ __FUNCTION__, what, *size, (size_t)stream->total_out);
+
+ *blob = out_buf;
+- *size = stream.total_out;
++ *size = stream->total_out;
+
+ lzma_cleanup:
+- lzma_end(&stream);
++ lzma_end(stream);
+
+ return retval;
+ }
+
++/* 128 Mb is the minimum size (half-way) documented to work for all inputs. */
++#define LZMA_BLOCK_SIZE (128*1024*1024)
++
++static int xc_try_xz_decode(
++ struct xc_dom_image *dom, void **blob, size_t *size)
++{
++ lzma_stream stream = LZMA_STREAM_INIT;
++ lzma_ret ret = lzma_stream_decoder(&stream, LZMA_BLOCK_SIZE, 0);
++
++ return _xc_try_lzma_decode(dom, blob, size, &stream, ret, "XZ");
++}
++
++static int xc_try_lzma_decode(
++ struct xc_dom_image *dom, void **blob, size_t *size)
++{
++ lzma_stream stream = LZMA_STREAM_INIT;
++ lzma_ret ret = lzma_alone_decoder(&stream, LZMA_BLOCK_SIZE);
++
++ return _xc_try_lzma_decode(dom, blob, size, &stream, ret, "LZMA");
++}
++
+ #else /* !defined(HAVE_LZMA) */
+
++static int xc_try_xz_decode(
++ struct xc_dom_image *dom, void **blob, size_t *size)
++{
++ DOMPRINTF("%s: XZ decompress support unavailable",
++ __FUNCTION__);
++ return -1;
++}
++
+ static int xc_try_lzma_decode(
+ struct xc_dom_image *dom, void **blob, size_t *size)
+ {
+@@ -607,6 +634,17 @@
+ __FUNCTION__);
+ return -EINVAL;
+ }
++ }
++ else if ( check_magic(dom, "\3757zXZ", 6) )
++ {
++ ret = xc_try_xz_decode(dom, &dom->kernel_blob, &dom->kernel_size);
++ if ( ret < 0 )
++ {
++ xc_dom_panic(dom->xch, XC_INVALID_KERNEL,
++ "%s unable to XZ decompress kernel",
++ __FUNCTION__);
++ return -EINVAL;
++ }
+ }
+ else if ( check_magic(dom, "\135\000", 2) )
+ {