diff --git a/xen/common/bunzip2.c b/xen/common/bunzip2.c
index 4466426941..a854046524 100644
--- a/xen/common/bunzip2.c
+++ b/xen/common/bunzip2.c
@@ -1,4 +1,4 @@
-/* vi: set sw = 4 ts = 4: */
+/* vi: set sw=4 ts=4: */
 /*	Small bzip2 deflate implementation, by Rob Landley (rob@landley.net).
 
 	Based on bzip2 decompression code by Julian R Seward (jseward@acm.org),
@@ -86,7 +86,7 @@ struct bunzip_data {
 	/* State for interrupting output loop */
 	int writeCopies, writePos, writeRunCountdown, writeCount, writeCurrent;
 	/* I/O tracking data (file handles, buffers, positions, etc.) */
-	int (*fill)(void*, unsigned int);
+	int (*fill)(void*, unsigned int, void*);
 	int inbufCount, inbufPos /*, outbufPos*/;
 	unsigned char *inbuf /*,*outbuf*/;
 	unsigned int inbufBitCount, inbufBits;
@@ -99,6 +99,7 @@ struct bunzip_data {
 	unsigned char selectors[32768];		/* nSelectors = 15 bits */
 	struct group_data groups[MAX_GROUPS];	/* Huffman coding tables */
 	int io_error;			/* non-zero if we have IO error */
+	void *userptr;			/* user pointer to pass to fill */
 };
 
 
@@ -117,7 +118,7 @@ static unsigned int __init get_bits(struct bunzip_data *bd, char bits_wanted)
 		if (bd->inbufPos == bd->inbufCount) {
 			if (bd->io_error)
 				return 0;
-			bd->inbufCount = bd->fill(bd->inbuf, BZIP2_IOBUF_SIZE);
+			bd->inbufCount = bd->fill(bd->inbuf, BZIP2_IOBUF_SIZE, bd->userptr);
 			if (bd->inbufCount <= 0) {
 				bd->io_error = RETVAL_UNEXPECTED_INPUT_EOF;
 				return 0;
@@ -612,7 +613,7 @@ decode_next_byte:
 	goto decode_next_byte;
 }
 
-static int __init cf_check nofill(void *buf, unsigned int len)
+static int __init cf_check nofill(void *buf, unsigned int len, void *userptr)
 {
 	return -1;
 }
@@ -621,7 +622,7 @@ static int __init cf_check nofill(void *buf, unsigned int len)
    a complete bunzip file (len bytes long).  If in_fd!=-1, inbuf and len are
    ignored, and data is read from file handle into temporary buffer. */
 static int __init start_bunzip(struct bunzip_data **bdp, void *inbuf, int len,
-			       int (*fill)(void*, unsigned int))
+			       int (*fill)(void*, unsigned int, void*), void *userptr)
 {
 	struct bunzip_data *bd;
 	unsigned int i, j, c;
@@ -644,6 +645,7 @@ static int __init start_bunzip(struct bunzip_data **bdp, void *inbuf, int len,
 		bd->fill = fill;
 	else
 		bd->fill = nofill;
+	bd->userptr = userptr;
 
 	/* Init the CRC32 table (big endian) */
 	for (i = 0; i < 256; i++) {
@@ -671,10 +673,11 @@ static int __init start_bunzip(struct bunzip_data **bdp, void *inbuf, int len,
 /* Example usage: decompress src_fd to dst_fd.  (Stops at end of bzip2 data,
    not end of file.) */
 int __init bunzip2(unsigned char *buf, unsigned int len,
-		   int(*fill)(void*, unsigned int),
-		   int(*flush)(void*, unsigned int),
+		   int(*fill)(void*, unsigned int, void*),
+		   int(*flush)(void*, unsigned int, void*),
 		   unsigned char *outbuf, unsigned int *pos,
-		   void(*error)(const char *x))
+		   void(*error)(const char *x),
+		   void *userptr)
 {
 	struct bunzip_data *bd;
 	int i = -1;
@@ -696,7 +699,7 @@ int __init bunzip2(unsigned char *buf, unsigned int len,
 		i = RETVAL_OUT_OF_MEMORY;
 		goto exit_0;
 	}
-	i = start_bunzip(&bd, inbuf, len, fill);
+	i = start_bunzip(&bd, inbuf, len, fill, userptr);
 	if (!i) {
 		for (;;) {
 			i = read_bunzip(bd, outbuf, BZIP2_IOBUF_SIZE);
@@ -705,7 +708,7 @@ int __init bunzip2(unsigned char *buf, unsigned int len,
 			if (!flush)
 				outbuf += i;
 			else
-				if (i != flush(outbuf, i)) {
+				if (i != flush(outbuf, i, userptr)) {
 					i = RETVAL_UNEXPECTED_OUTPUT_EOF;
 					break;
 				}
diff --git a/xen/common/unlz4.c b/xen/common/unlz4.c
index 2096b98f36..00c179732e 100644
--- a/xen/common/unlz4.c
+++ b/xen/common/unlz4.c
@@ -23,10 +23,11 @@
 #define ARCHIVE_MAGICNUMBER 0x184C2102
 
 int __init unlz4(unsigned char *input, unsigned int in_len,
-		 int (*fill)(void *, unsigned int),
-		 int (*flush)(void *, unsigned int),
+		 int (*fill)(void *, unsigned int, void*),
+		 int (*flush)(void *, unsigned int, void*),
 		 unsigned char *output, unsigned int *posp,
-		 void (*error)(const char *x))
+		 void (*error)(const char *x),
+		 void *userptr)
 {
 	int ret = -1;
 	size_t chunksize = 0;
@@ -75,7 +76,7 @@ int __init unlz4(unsigned char *input, unsigned int in_len,
 		*posp = 0;
 
 	if (fill)
-		fill(inp, 4);
+		fill(inp, 4, userptr);
 
 	chunksize = get_unaligned_le32(inp);
 	if (chunksize == ARCHIVE_MAGICNUMBER) {
@@ -92,7 +93,7 @@ int __init unlz4(unsigned char *input, unsigned int in_len,
 	for (;;) {
 
 		if (fill)
-			fill(inp, 4);
+			fill(inp, 4, userptr);
 
 		chunksize = get_unaligned_le32(inp);
 		if (chunksize == ARCHIVE_MAGICNUMBER) {
@@ -113,7 +114,7 @@ int __init unlz4(unsigned char *input, unsigned int in_len,
 				error("chunk length is longer than allocated");
 				goto exit_2;
 			}
-			fill(inp, chunksize);
+			fill(inp, chunksize, userptr);
 		}
 #if defined(__XEN__) || defined(__MINIOS__)
 		if (out_len >= uncomp_chunksize) {
@@ -133,7 +134,7 @@ int __init unlz4(unsigned char *input, unsigned int in_len,
 		}
 
 		ret = -1;
-		if (flush && flush(outp, dest_len) != dest_len)
+		if (flush && flush(outp, dest_len, userptr) != dest_len)
 			goto exit_2;
 		if (output)
 			outp += dest_len;
diff --git a/xen/common/unlzma.c b/xen/common/unlzma.c
index 6cd99023ad..d5dbc44881 100644
--- a/xen/common/unlzma.c
+++ b/xen/common/unlzma.c
@@ -59,7 +59,7 @@ static long long __init read_int(unsigned char *ptr, int size)
 #define LZMA_IOBUF_SIZE	0x10000
 
 struct rc {
-	int (*fill)(void*, unsigned int);
+	int (*fill)(void*, unsigned int, void*);
 	uint8_t *ptr;
 	uint8_t *buffer;
 	uint8_t *buffer_end;
@@ -68,6 +68,7 @@ struct rc {
 	uint32_t range;
 	uint32_t bound;
 	void (*error)(const char *);
+	void *userptr;
 };
 
 
@@ -76,7 +77,7 @@ struct rc {
 #define RC_MODEL_TOTAL_BITS 11
 
 
-static int __init cf_check nofill(void *buffer, unsigned int len)
+static int __init cf_check nofill(void *buffer, unsigned int len, void *userptr)
 {
 	return -1;
 }
@@ -84,7 +85,7 @@ static int __init cf_check nofill(void *buffer, unsigned int len)
 /* Called twice: once at startup and once in rc_normalize() */
 static void __init rc_read(struct rc *rc)
 {
-	rc->buffer_size = rc->fill((char *)rc->buffer, LZMA_IOBUF_SIZE);
+	rc->buffer_size = rc->fill((char *)rc->buffer, LZMA_IOBUF_SIZE, rc->userptr);
 	if (rc->buffer_size <= 0)
 		rc->error("unexpected EOF");
 	rc->ptr = rc->buffer;
@@ -93,8 +94,9 @@ static void __init rc_read(struct rc *rc)
 
 /* Called once */
 static inline void __init rc_init(struct rc *rc,
-				  int (*fill)(void*, unsigned int),
-				  unsigned char *buffer, int buffer_size)
+				  int (*fill)(void*, unsigned int, void*),
+				  unsigned char *buffer, int buffer_size,
+				  void *userptr)
 {
 	if (fill)
 		rc->fill = fill;
@@ -104,6 +106,7 @@ static inline void __init rc_init(struct rc *rc,
 	rc->buffer_size = buffer_size;
 	rc->buffer_end = rc->buffer + rc->buffer_size;
 	rc->ptr = rc->buffer;
+	rc->userptr = userptr;
 
 	rc->code = 0;
 	rc->range = 0xFFFFFFFF;
@@ -274,8 +277,9 @@ struct writer {
 	size_t buffer_pos;
 	int bufsize;
 	size_t global_pos;
-	int(*flush)(void*, unsigned int);
+	int(*flush)(void*, unsigned int, void*);
 	struct lzma_header *header;
+	void *userptr;
 };
 
 struct cstate {
@@ -313,7 +317,7 @@ static inline int __init write_byte(struct writer *wr, uint8_t byte)
 	if (wr->flush && wr->buffer_pos == wr->header->dict_size) {
 		wr->buffer_pos = 0;
 		wr->global_pos += wr->header->dict_size;
-		if (wr->flush((char *)wr->buffer, wr->header->dict_size)
+		if (wr->flush((char *)wr->buffer, wr->header->dict_size, wr->userptr)
 				!= wr->header->dict_size)
 			return -1;
 	}
@@ -529,10 +533,11 @@ static inline int __init process_bit1(struct writer *wr, struct rc *rc,
 
 
 int __init unlzma(unsigned char *buf, unsigned int in_len,
-		  int(*fill)(void*, unsigned int),
-		  int(*flush)(void*, unsigned int),
+		  int(*fill)(void*, unsigned int, void*),
+		  int(*flush)(void*, unsigned int, void*),
 		  unsigned char *output, unsigned int *posp,
-		  void(*error)(const char *x))
+		  void(*error)(const char *x),
+		  void *userptr)
 {
 	struct lzma_header header;
 	int lc, pb, lp;
@@ -566,8 +571,9 @@ int __init unlzma(unsigned char *buf, unsigned int in_len,
 	wr.global_pos = 0;
 	wr.previous_byte = 0;
 	wr.buffer_pos = 0;
+	wr.userptr = userptr;
 
-	rc_init(&rc, fill, inbuf, in_len);
+	rc_init(&rc, fill, inbuf, in_len, userptr);
 
 	for (i = 0; i < sizeof(header); i++) {
 		if (rc.ptr >= rc.buffer_end)
@@ -644,7 +650,7 @@ int __init unlzma(unsigned char *buf, unsigned int in_len,
 
 	if (posp)
 		*posp = rc.ptr-rc.buffer;
-	if (!wr.flush || wr.flush(wr.buffer, wr.buffer_pos) == wr.buffer_pos)
+	if (!wr.flush || wr.flush(wr.buffer, wr.buffer_pos, wr.userptr) == wr.buffer_pos)
 		ret = 0;
 exit_3:
 	large_free(p);
diff --git a/xen/common/unlzo.c b/xen/common/unlzo.c
index 74056778eb..8908790425 100644
--- a/xen/common/unlzo.c
+++ b/xen/common/unlzo.c
@@ -115,10 +115,11 @@ static int __init parse_header(u8 *input, int *skip, int in_len)
 }
 
 int __init unlzo(unsigned char *input, unsigned int in_len,
-		 int (*fill) (void *, unsigned int),
-		 int (*flush) (void *, unsigned int),
+		 int (*fill) (void *, unsigned int, void*),
+		 int (*flush) (void *, unsigned int, void*),
 		 unsigned char *output, unsigned int *posp,
-		 void (*error) (const char *x))
+		 void (*error) (const char *x),
+		 void *userptr)
 {
 	u8 r = 0;
 	int skip = 0;
@@ -161,7 +162,7 @@ int __init unlzo(unsigned char *input, unsigned int in_len,
 		*posp = 0;
 
 	if (fill)
-		fill(in_buf, lzo1x_worst_compress(LZO_BLOCK_SIZE));
+		fill(in_buf, lzo1x_worst_compress(LZO_BLOCK_SIZE), userptr);
 
 	if (!parse_header(input, &skip, in_len)) {
 		error("invalid header");
@@ -227,7 +228,7 @@ int __init unlzo(unsigned char *input, unsigned int in_len,
 			}
 		}
 
-		if (flush && flush(out_buf, dst_len) != dst_len)
+		if (flush && flush(out_buf, dst_len, userptr) != dst_len)
 			goto exit_2;
 		if (output)
 			out_buf += dst_len;
@@ -235,7 +236,7 @@ int __init unlzo(unsigned char *input, unsigned int in_len,
 			*posp += src_len + 12;
 		if (fill) {
 			in_buf = in_buf_save;
-			fill(in_buf, lzo1x_worst_compress(LZO_BLOCK_SIZE));
+			fill(in_buf, lzo1x_worst_compress(LZO_BLOCK_SIZE), userptr);
 		} else {
 			in_buf += src_len;
 			in_len -= src_len;
diff --git a/xen/common/unxz.c b/xen/common/unxz.c
index 17aead0adf..6f005170d3 100644
--- a/xen/common/unxz.c
+++ b/xen/common/unxz.c
@@ -158,10 +158,11 @@
  * fill() and flush() won't be used.
  */
 int __init unxz(unsigned char *in, unsigned int in_size,
-		int (*fill)(void *dest, unsigned int size),
-		int (*flush)(void *src, unsigned int size),
+		int (*fill)(void *dest, unsigned int size, void *userptr),
+		int (*flush)(void *src, unsigned int size, void *userptr),
 		unsigned char *out, unsigned int *in_used,
-		void (*error)(const char *x))
+		void (*error)(const char *x),
+		void *userptr)
 {
 	struct xz_buf b;
 	struct xz_dec *s;
@@ -213,7 +214,7 @@ int __init unxz(unsigned char *in, unsigned int in_size,
 
 				b.in_pos = 0;
 
-				in_size = fill(in, XZ_IOBUF_SIZE);
+				in_size = fill(in, XZ_IOBUF_SIZE, userptr);
 				if ((int) in_size < 0) {
 					/*
 					 * This isn't an optimal error code
@@ -236,7 +237,7 @@ int __init unxz(unsigned char *in, unsigned int in_size,
 				 * returned by xz_dec_run(), but probably
 				 * it's not too bad.
 				 */
-				if (flush(b.out, b.out_pos) != (int)b.out_pos)
+				if (flush(b.out, b.out_pos, userptr) != (int)b.out_pos)
 					ret = XZ_BUF_ERROR;
 
 				b.out_pos = 0;
diff --git a/xen/common/unzstd.c b/xen/common/unzstd.c
index 47073dd3e3..09e8fdef04 100644
--- a/xen/common/unzstd.c
+++ b/xen/common/unzstd.c
@@ -143,10 +143,11 @@ out:
 }
 
 int __init unzstd(unsigned char *in_buf, unsigned int in_len,
-		  int (*fill)(void*, unsigned int),
-		  int (*flush)(void*, unsigned int),
+		  int (*fill)(void*, unsigned int, void*),
+		  int (*flush)(void*, unsigned int, void*),
 		  unsigned char *out_buf, unsigned int *in_pos,
-		  void (*error)(const char *x))
+		  void (*error)(const char *x),
+		  void *userptr)
 {
 	ZSTD_inBuffer in;
 	ZSTD_outBuffer out;
@@ -190,7 +191,7 @@ int __init unzstd(unsigned char *in_buf, unsigned int in_len,
 	}
 	/* Read the first chunk, since we need to decode the frame header. */
 	if (fill != NULL)
-		in_len = fill(in_buf, ZSTD_IOBUF_SIZE);
+		in_len = fill(in_buf, ZSTD_IOBUF_SIZE, userptr);
 	if ((int)in_len < 0) {
 		error("ZSTD-compressed data is truncated");
 		err = -1;
@@ -267,7 +268,7 @@ int __init unzstd(unsigned char *in_buf, unsigned int in_len,
 		if (in.pos == in.size) {
 			if (in_pos != NULL)
 				*in_pos += in.pos;
-			in_len = fill ? fill(in_buf, ZSTD_IOBUF_SIZE) : -1;
+			in_len = fill ? fill(in_buf, ZSTD_IOBUF_SIZE, userptr) : -1;
 			if ((int)in_len < 0) {
 				error("ZSTD-compressed data is truncated");
 				err = -1;
@@ -283,7 +284,7 @@ int __init unzstd(unsigned char *in_buf, unsigned int in_len,
 			goto out;
 		/* Flush all of the data produced if using flush(). */
 		if (flush != NULL && out.pos > 0) {
-			if (out.pos != flush(out.dst, out.pos)) {
+			if (out.pos != flush(out.dst, out.pos, userptr)) {
 				error("Failed to flush()");
 				err = -1;
 				goto out;
diff --git a/xen/include/xen/decompress.h b/xen/include/xen/decompress.h
index f5bc17f2b6..804dbca963 100644
--- a/xen/include/xen/decompress.h
+++ b/xen/include/xen/decompress.h
@@ -2,10 +2,11 @@
 #define __XEN_GENERIC_H
 
 typedef int decompress_fn(unsigned char *inbuf, unsigned int len,
-                          int (*fill)(void*, unsigned int),
-                          int (*flush)(void*, unsigned int),
+                          int (*fill)(void*, unsigned int, void*),
+                          int (*flush)(void*, unsigned int, void*),
                           unsigned char *outbuf, unsigned int *posp,
-                          void (*error)(const char *x));
+                          void (*error)(const char *x),
+                          void *userptr);
 
 /* inbuf   - input buffer
  * len     - len of pre-read data in inbuf
@@ -15,6 +16,7 @@ typedef int decompress_fn(unsigned char *inbuf, unsigned int len,
  * posp    - if non-null, input position (number of bytes read) will be
  *           returned here
  * error   - error reporting function
+ * userptr - user pointer to pass to flush and fill
  *
  * If len != 0, inbuf should contain all the necessary input data, and fill
  * should be NULL
@@ -29,6 +31,8 @@ typedef int decompress_fn(unsigned char *inbuf, unsigned int len,
  * decompressor (outbuf = NULL), and the flush function will be called to
  * flush the output buffer at the appropriate time (decompressor and stream
  * dependent).
+ *
+ * Flush and fill's third argument is a user pointer for book keeping purposes.
  */
 
 decompress_fn bunzip2, unxz, unlzma, unlzo, unlz4, unzstd;
