diff --git a/0001-add-pflib-PixelFormat-conversion-library.patch b/0001-add-pflib-PixelFormat-conversion-library.patch
deleted file mode 100644
index de9805e..0000000
--- a/0001-add-pflib-PixelFormat-conversion-library.patch
+++ /dev/null
@@ -1,259 +0,0 @@
-From 09992bc6b432987ed3871dd7e4327ab6a589b865 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Mon, 14 Jun 2010 09:54:27 +0200
-Subject: [PATCH 01/39] add pflib: PixelFormat conversion library.
-
----
- Makefile.objs |    1 +
- pflib.c       |  213 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- pflib.h       |    6 ++
- 3 files changed, 220 insertions(+), 0 deletions(-)
- create mode 100644 pflib.c
- create mode 100644 pflib.h
-
-diff --git a/Makefile.objs b/Makefile.objs
-index dbee210..147051f 100644
---- a/Makefile.objs
-+++ b/Makefile.objs
-@@ -84,6 +84,7 @@ common-obj-y += qemu-char.o savevm.o #aio.o
- common-obj-y += msmouse.o ps2.o
- common-obj-y += qdev.o qdev-properties.o
- common-obj-y += block-migration.o
-+common-obj-y += pflib.o
-
- common-obj-$(CONFIG_BRLAPI) += baum.o
- common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o
-diff --git a/pflib.c b/pflib.c
-new file mode 100644
-index 0000000..1154d0c
---- /dev/null
-+++ b/pflib.c
-@@ -0,0 +1,213 @@
-+/*
-+ * PixelFormat conversion library.
-+ *
-+ * Author: Gerd Hoffmann <kraxel@redhat.com>
-+ *
-+ * This work is licensed under the terms of the GNU GPL, version 2.  See
-+ * the COPYING file in the top-level directory.
-+ *
-+ */
-+#include "qemu-common.h"
-+#include "console.h"
-+#include "pflib.h"
-+
-+typedef struct QemuPixel QemuPixel;
-+
-+typedef void (*pf_convert)(QemuPfConv *conv,
-+                           void *dst, void *src, uint32_t cnt);
-+typedef void (*pf_convert_from)(PixelFormat *pf,
-+                                QemuPixel *dst, void *src, uint32_t cnt);
-+typedef void (*pf_convert_to)(PixelFormat *pf,
-+                              void *dst, QemuPixel *src, uint32_t cnt);
-+
-+struct QemuPfConv {
-+    pf_convert        convert;
-+    PixelFormat       src;
-+    PixelFormat       dst;
-+
-+    /* for copy_generic() */
-+    pf_convert_from   conv_from;
-+    pf_convert_to     conv_to;
-+    QemuPixel         *conv_buf;
-+    uint32_t          conv_cnt;
-+};
-+
-+struct QemuPixel {
-+    uint8_t red;
-+    uint8_t green;
-+    uint8_t blue;
-+    uint8_t alpha;
-+};
-+
-+/* ----------------------------------------------------------------------- */
-+/* PixelFormat -> QemuPixel conversions                                    */
-+
-+static void conv_16_to_pixel(PixelFormat *pf,
-+                             QemuPixel *dst, void *src, uint32_t cnt)
-+{
-+    uint16_t *src16 = src;
-+
-+    while (cnt > 0) {
-+        dst->red   = ((*src16 & pf->rmask) >> pf->rshift) << (8 - pf->rbits);
-+        dst->green = ((*src16 & pf->gmask) >> pf->gshift) << (8 - pf->gbits);
-+        dst->blue  = ((*src16 & pf->bmask) >> pf->bshift) << (8 - pf->bbits);
-+        dst->alpha = ((*src16 & pf->amask) >> pf->ashift) << (8 - pf->abits);
-+        dst++, src16++, cnt--;
-+    }
-+}
-+
-+/* assumes pf->{r,g,b,a}bits == 8 */
-+static void conv_32_to_pixel_fast(PixelFormat *pf,
-+                                  QemuPixel *dst, void *src, uint32_t cnt)
-+{
-+    uint32_t *src32 = src;
-+
-+    while (cnt > 0) {
-+        dst->red   = (*src32 & pf->rmask) >> pf->rshift;
-+        dst->green = (*src32 & pf->gmask) >> pf->gshift;
-+        dst->blue  = (*src32 & pf->bmask) >> pf->bshift;
-+        dst->alpha = (*src32 & pf->amask) >> pf->ashift;
-+        dst++, src32++, cnt--;
-+    }
-+}
-+
-+static void conv_32_to_pixel_generic(PixelFormat *pf,
-+                                     QemuPixel *dst, void *src, uint32_t cnt)
-+{
-+    uint32_t *src32 = src;
-+
-+    while (cnt > 0) {
-+        if (pf->rbits < 8) {
-+            dst->red   = ((*src32 & pf->rmask) >> pf->rshift) << (8 - pf->rbits);
-+        } else {
-+            dst->red   = ((*src32 & pf->rmask) >> pf->rshift) >> (pf->rbits - 8);
-+        }
-+        if (pf->gbits < 8) {
-+            dst->green = ((*src32 & pf->gmask) >> pf->gshift) << (8 - pf->gbits);
-+        } else {
-+            dst->green = ((*src32 & pf->gmask) >> pf->gshift) >> (pf->gbits - 8);
-+        }
-+        if (pf->bbits < 8) {
-+            dst->blue  = ((*src32 & pf->bmask) >> pf->bshift) << (8 - pf->bbits);
-+        } else {
-+            dst->blue  = ((*src32 & pf->bmask) >> pf->bshift) >> (pf->bbits - 8);
-+        }
-+        if (pf->abits < 8) {
-+            dst->alpha = ((*src32 & pf->amask) >> pf->ashift) << (8 - pf->abits);
-+        } else {
-+            dst->alpha = ((*src32 & pf->amask) >> pf->ashift) >> (pf->abits - 8);
-+        }
-+        dst++, src32++, cnt--;
-+    }
-+}
-+
-+/* ----------------------------------------------------------------------- */
-+/* QemuPixel -> PixelFormat conversions                                    */
-+
-+static void conv_pixel_to_16(PixelFormat *pf,
-+                             void *dst, QemuPixel *src, uint32_t cnt)
-+{
-+    uint16_t *dst16 = dst;
-+
-+    while (cnt > 0) {
-+        *dst16  = ((uint16_t)src->red   >> (8 - pf->rbits)) << pf->rshift;
-+        *dst16 |= ((uint16_t)src->green >> (8 - pf->gbits)) << pf->gshift;
-+        *dst16 |= ((uint16_t)src->blue  >> (8 - pf->bbits)) << pf->bshift;
-+        *dst16 |= ((uint16_t)src->alpha >> (8 - pf->abits)) << pf->ashift;
-+        dst16++, src++, cnt--;
-+    }
-+}
-+
-+static void conv_pixel_to_32(PixelFormat *pf,
-+                             void *dst, QemuPixel *src, uint32_t cnt)
-+{
-+    uint32_t *dst32 = dst;
-+
-+    while (cnt > 0) {
-+        *dst32  = ((uint32_t)src->red   >> (8 - pf->rbits)) << pf->rshift;
-+        *dst32 |= ((uint32_t)src->green >> (8 - pf->gbits)) << pf->gshift;
-+        *dst32 |= ((uint32_t)src->blue  >> (8 - pf->bbits)) << pf->bshift;
-+        *dst32 |= ((uint32_t)src->alpha >> (8 - pf->abits)) << pf->ashift;
-+        dst32++, src++, cnt--;
-+    }
-+}
-+
-+/* ----------------------------------------------------------------------- */
-+/* PixelFormat -> PixelFormat conversions                                  */
-+
-+static void convert_copy(QemuPfConv *conv, void *dst, void *src, uint32_t cnt)
-+{
-+    uint32_t bytes = cnt * conv->src.bytes_per_pixel;
-+    memcpy(dst, src, bytes);
-+}
-+
-+static void convert_generic(QemuPfConv *conv, void *dst, void *src, uint32_t cnt)
-+{
-+    if (conv->conv_cnt < cnt) {
-+        conv->conv_cnt = cnt;
-+        conv->conv_buf = qemu_realloc(conv->conv_buf, sizeof(QemuPixel) * conv->conv_cnt);
-+    }
-+    conv->conv_from(&conv->src, conv->conv_buf, src, cnt);
-+    conv->conv_to(&conv->dst, dst, conv->conv_buf, cnt);
-+}
-+
-+/* ----------------------------------------------------------------------- */
-+/* public interface                                                        */
-+
-+QemuPfConv *qemu_pf_conv_get(PixelFormat *dst, PixelFormat *src)
-+{
-+    QemuPfConv *conv = qemu_mallocz(sizeof(QemuPfConv));
-+
-+    conv->src = *src;
-+    conv->dst = *dst;
-+
-+    if (memcmp(&conv->src, &conv->dst, sizeof(PixelFormat)) == 0) {
-+        /* formats identical, can simply copy */
-+        conv->convert = convert_copy;
-+    } else {
-+        /* generic two-step conversion: src -> QemuPixel -> dst  */
-+        switch (conv->src.bytes_per_pixel) {
-+        case 2:
-+            conv->conv_from = conv_16_to_pixel;
-+            break;
-+        case 4:
-+            if (conv->src.rbits == 8 && conv->src.gbits == 8 && conv->src.bbits == 8) {
-+                conv->conv_from = conv_32_to_pixel_fast;
-+            } else {
-+                conv->conv_from = conv_32_to_pixel_generic;
-+            }
-+            break;
-+        default:
-+            goto err;
-+        }
-+        switch (conv->dst.bytes_per_pixel) {
-+        case 2:
-+            conv->conv_to = conv_pixel_to_16;
-+            break;
-+        case 4:
-+            conv->conv_to = conv_pixel_to_32;
-+            break;
-+        default:
-+            goto err;
-+        }
-+        conv->convert = convert_generic;
-+    }
-+    return conv;
-+
-+err:
-+    qemu_free(conv);
-+    return NULL;
-+}
-+
-+void qemu_pf_conv_run(QemuPfConv *conv, void *dst, void *src, uint32_t cnt)
-+{
-+    conv->convert(conv, dst, src, cnt);
-+}
-+
-+void qemu_pf_conv_put(QemuPfConv *conv)
-+{
-+    if (conv) {
-+        qemu_free(conv->conv_buf);
-+        qemu_free(conv);
-+    }
-+}
-diff --git a/pflib.h b/pflib.h
-new file mode 100644
-index 0000000..8d73fdd
---- /dev/null
-+++ b/pflib.h
-@@ -0,0 +1,6 @@
-+/* public */
-+typedef struct QemuPfConv QemuPfConv;
-+
-+QemuPfConv *qemu_pf_conv_get(PixelFormat *dst, PixelFormat *src);
-+void qemu_pf_conv_run(QemuPfConv *conv, void *dst, void *src, uint32_t cnt);
-+void qemu_pf_conv_put(QemuPfConv *conv);
--- 
-1.7.2.3
-
diff --git a/0001-qxl-spice-display-move-pipe-to-ssd.patch b/0001-qxl-spice-display-move-pipe-to-ssd.patch
new file mode 100644
index 0000000..b542f54
--- /dev/null
+++ b/0001-qxl-spice-display-move-pipe-to-ssd.patch
@@ -0,0 +1,143 @@
+>From fd04276a00b172e6fbba3e3c72b1d13a0f179414 Mon Sep 17 00:00:00 2001
+From: Alon Levy <alevy@redhat.com>
+Date: Wed, 16 Mar 2011 15:21:03 +0100
+Subject: [PATCH 1/4] qxl/spice-display: move pipe to ssd
+
+This moves the int pipe[2] and pthread_t main data from the
+PCIQXLDevice struct to the SimpleSpiceDisplay. This will let us
+reuse it in the next patch for both -spice with no -qxl usage and
+for vga mode from qxl.
+
+Also move the pipe creation function (which is effectively completely rewritten
+by this patch anyways) from hw/qxl.c to ui/spice-display.c, since
+spice-display will depend on it after the next patch and qemu can be build
+with ui/spice-display.c in combination with no hw/qxl.c.
+---
+ hw/qxl.c           |   22 +++++-----------------
+ hw/qxl.h           |    4 ----
+ ui/spice-display.c |   21 +++++++++++++++++++++
+ ui/spice-display.h |    8 ++++++++
+ 4 files changed, 34 insertions(+), 21 deletions(-)
+
+diff --git a/hw/qxl.c b/hw/qxl.c
+index fe4212b..201698f 100644
+--- a/hw/qxl.c
++++ b/hw/qxl.c
+@@ -1062,7 +1062,7 @@ static void pipe_read(void *opaque)
+     int len;
+ 
+     do {
+-        len = read(d->pipe[0], &dummy, sizeof(dummy));
++        len = read(d->ssd.pipe[0], &dummy, sizeof(dummy));
+     } while (len == sizeof(dummy));
+     qxl_set_irq(d);
+ }
+@@ -1078,10 +1078,11 @@ static void qxl_send_events(PCIQXLDevice *d, uint32_t events)
+     if ((old_pending & le_events) == le_events) {
+         return;
+     }
+-    if (pthread_self() == d->main) {
++    if (pthread_self() == d->ssd.main) {
++        /* running in io_thread thread */
+         qxl_set_irq(d);
+     } else {
+-        if (write(d->pipe[1], d, 1) != 1) {
++        if (write(d->ssd.pipe[1], d, 1) != 1) {
+             dprint(d, 1, "%s: write to pipe failed\n", __FUNCTION__);
+         }
+     }
+@@ -1089,20 +1090,7 @@ static void qxl_send_events(PCIQXLDevice *d, uint32_t events)
+ 
+ static void init_pipe_signaling(PCIQXLDevice *d)
+ {
+-   if (pipe(d->pipe) < 0) {
+-       dprint(d, 1, "%s: pipe creation failed\n", __FUNCTION__);
+-       return;
+-   }
+-#ifdef CONFIG_IOTHREAD
+-   fcntl(d->pipe[0], F_SETFL, O_NONBLOCK);
+-#else
+-   fcntl(d->pipe[0], F_SETFL, O_NONBLOCK /* | O_ASYNC */);
+-#endif
+-   fcntl(d->pipe[1], F_SETFL, O_NONBLOCK);
+-   fcntl(d->pipe[0], F_SETOWN, getpid());
+-
+-   d->main = pthread_self();
+-   qemu_set_fd_handler(d->pipe[0], pipe_read, NULL, d);
++   qxl_create_server_to_iothread_pipe(&d->ssd, pipe_read);
+ }
+ 
+ /* graphics console */
+diff --git a/hw/qxl.h b/hw/qxl.h
+index f6c450d..701245f 100644
+--- a/hw/qxl.h
++++ b/hw/qxl.h
+@@ -55,10 +55,6 @@ typedef struct PCIQXLDevice {
+     } guest_surfaces;
+     QXLPHYSICAL        guest_cursor;
+ 
+-    /* thread signaling */
+-    pthread_t          main;
+-    int                pipe[2];
+-
+     /* ram pci bar */
+     QXLRam             *ram;
+     VGACommonState     vga;
+diff --git a/ui/spice-display.c b/ui/spice-display.c
+index 020b423..ec6e0cb 100644
+--- a/ui/spice-display.c
++++ b/ui/spice-display.c
+@@ -394,6 +394,27 @@ static DisplayChangeListener display_listener = {
+     .dpy_refresh = display_refresh,
+ };
+ 
++void qxl_create_server_to_iothread_pipe(SimpleSpiceDisplay *ssd,
++    IOHandler *pipe_read)
++{
++    if (pipe(ssd->pipe) < 0) {
++        fprintf(stderr, "%s: pipe creation failed\n", __FUNCTION__);
++        return;
++    }
++
++#ifdef CONFIG_IOTHREAD
++    fcntl(ssd->pipe[0], F_SETFL, O_NONBLOCK);
++#else
++    fcntl(ssd->pipe[0], F_SETFL, O_NONBLOCK /* | O_ASYNC */);
++#endif
++    fcntl(ssd->pipe[1], F_SETFL, O_NONBLOCK);
++
++    fcntl(ssd->pipe[0], F_SETOWN, getpid());
++
++    qemu_set_fd_handler(ssd->pipe[0], pipe_read, NULL, ssd);
++    ssd->main = pthread_self();
++}
++
+ void qemu_spice_display_init(DisplayState *ds)
+ {
+     assert(sdpy.ds == NULL);
+diff --git a/ui/spice-display.h b/ui/spice-display.h
+index aef0464..3e6cf7c 100644
+--- a/ui/spice-display.h
++++ b/ui/spice-display.h
+@@ -43,6 +43,11 @@ typedef struct SimpleSpiceDisplay {
+     QXLRect dirty;
+     int notify;
+     int running;
++
++    /* thread signaling - used both in qxl (in vga mode
++     * and in native mode) and without qxl */
++    pthread_t          main;
++    int                pipe[2];     /* to iothread */
+ } SimpleSpiceDisplay;
+ 
+ typedef struct SimpleSpiceUpdate {
+@@ -66,3 +71,6 @@ void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
+                                int x, int y, int w, int h);
+ void qemu_spice_display_resize(SimpleSpiceDisplay *ssd);
+ void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd);
++/* used by both qxl and spice-display */
++void qxl_create_server_to_iothread_pipe(SimpleSpiceDisplay *ssd,
++    IOHandler *pipe_read);
+-- 
+1.7.3.2
+
diff --git a/0002-configure-add-logging.patch b/0002-configure-add-logging.patch
deleted file mode 100644
index 34f374c..0000000
--- a/0002-configure-add-logging.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 89df4f8cf7ecde07e3dc5e2ea3c19cbcd02165d0 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Fri, 23 Apr 2010 13:44:10 +0200
-Subject: [PATCH 02/39] configure: add logging
-
-Write compile commands and messages to config.log.
-Useful for debugging configure.
----
- configure |    7 +++++--
- 1 files changed, 5 insertions(+), 2 deletions(-)
-
-diff --git a/configure b/configure
-index b85590f..e09c442 100755
---- a/configure
-+++ b/configure
-@@ -16,15 +16,18 @@ TMPO="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.o"
- TMPE="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.exe"
-
- trap "rm -f $TMPC $TMPO $TMPE ; exit" EXIT INT QUIT TERM
-+rm -f config.log
-
- compile_object() {
--  $cc $QEMU_CFLAGS -c -o $TMPO $TMPC > /dev/null 2> /dev/null
-+  echo $cc $QEMU_CFLAGS -c -o $TMPO $TMPC >> config.log
-+  $cc $QEMU_CFLAGS -c -o $TMPO $TMPC >> config.log 2>&1
- }
-
- compile_prog() {
-   local_cflags="$1"
-   local_ldflags="$2"
--  $cc $QEMU_CFLAGS $local_cflags -o $TMPE $TMPC $LDFLAGS $local_ldflags > /dev/null 2> /dev/null
-+  echo $cc $QEMU_CFLAGS $local_cflags -o $TMPE $TMPC $LDFLAGS $local_ldflags >> config.log
-+  $cc $QEMU_CFLAGS $local_cflags -o $TMPE $TMPC $LDFLAGS $local_ldflags >> config.log 2>&1
- }
-
- # check whether a command is available to this shell (may be either an
--- 
-1.7.2.3
-
diff --git a/0002-qxl-implement-get_command-in-vga-mode-without-locks.patch b/0002-qxl-implement-get_command-in-vga-mode-without-locks.patch
new file mode 100644
index 0000000..d221d5f
--- /dev/null
+++ b/0002-qxl-implement-get_command-in-vga-mode-without-locks.patch
@@ -0,0 +1,312 @@
+>From 97e291086fef45762e0278e85ab1d231a9902bbb Mon Sep 17 00:00:00 2001
+From: Uri Lublin <uril@redhat.com>
+Date: Wed, 16 Mar 2011 15:43:45 +0100
+Subject: [PATCH 2/4] qxl: implement get_command in vga mode without locks
+
+This patch and the next drop the requirement to lose the global qemu
+mutex during dispatcher calls. This patch enables it, the next drops
+the unlock/lock pairs around dispatcher calls.
+
+The current solution of dropping the locks is buggy:
+ * it allows multiple dispatcher calls from two vcpu threads, the
+ dispatcher doesn't handle that by design (single fd, not locked, can't
+ handle writes from two threads)
+ * it requires us to keep track of cpu_single_env, which is magic.
+
+The solution implemented in this patch and the next (the next just
+drops the locks, this patch allows that to work):
+ * the only operation that needed locking was qemu_create_simple_update,
+ * it required locking because it was called from the spice-server thread.
+ * do it in the iothread by reusing the existing pipe used for set_irq.
+
+The current flow implemented is now:
+spice-server thread:
+ qxl.c:interface_get_command (called either by polling or from wakeup)
+  if update!=NULL:
+   waiting_for_update=0
+   update=NULL
+   return update
+  else:
+   if not waiting_for_update:
+    waiting_for_update=1
+    write to pipe, which is read by iothread (main thread)
+
+iothread:
+ wakeup from select,
+ qxl.c:pipe_read
+  update=qemu_create_simple_update()
+  wakeup spice-server thread by calling d.worker->wakeup(d.worker)
+---
+ hw/qxl.c           |   81 +++++++++++++++++++++++++++++++++++++++------------
+ ui/spice-display.c |   75 +++++++++++++++++++++++++++++++++++++++++++----
+ ui/spice-display.h |   16 ++++++++++
+ 3 files changed, 146 insertions(+), 26 deletions(-)
+
+diff --git a/hw/qxl.c b/hw/qxl.c
+index 201698f..64580f1 100644
+--- a/hw/qxl.c
++++ b/hw/qxl.c
+@@ -340,7 +340,6 @@ static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info)
+ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
+ {
+     PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
+-    SimpleSpiceUpdate *update;
+     QXLCommandRing *ring;
+     QXLCommand *cmd;
+     int notify;
+@@ -348,16 +347,25 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
+     switch (qxl->mode) {
+     case QXL_MODE_VGA:
+         dprint(qxl, 2, "%s: vga\n", __FUNCTION__);
+-        update = qemu_spice_create_update(&qxl->ssd);
+-        if (update == NULL) {
+-            return false;
++        if (qxl_vga_mode_get_command(&qxl->ssd, ext)) {
++            qxl_log_command(qxl, "vga", ext);
++            return true;
+         }
+-        *ext = update->ext;
+-        qxl_log_command(qxl, "vga", ext);
+-        return true;
++        return false;
+     case QXL_MODE_COMPAT:
+     case QXL_MODE_NATIVE:
+     case QXL_MODE_UNDEFINED:
++        /* flush any existing updates that we didn't send to the guest.
++         * since update != NULL it means the server didn't get it, and
++         * because we changed mode to != QXL_MODE_VGA, it won't. */
++        if (qxl->ssd.update != NULL) {
++            if (qxl->ssd.update != QXL_EMPTY_UPDATE) {
++                qemu_spice_destroy_update(&qxl->ssd, qxl->ssd.update);
++            }
++            qxl->ssd.update = NULL;
++            qxl->ssd.waiting_for_update = 0;
++        }
++        /* */
+         dprint(qxl, 2, "%s: %s\n", __FUNCTION__,
+                qxl->cmdflags ? "compat" : "native");
+         ring = &qxl->ram->cmd_ring;
+@@ -1057,17 +1065,50 @@ static void qxl_map(PCIDevice *pci, int region_num,
+ 
+ static void pipe_read(void *opaque)
+ {
+-    PCIQXLDevice *d = opaque;
+-    char dummy;
+-    int len;
+-
+-    do {
+-        len = read(d->ssd.pipe[0], &dummy, sizeof(dummy));
+-    } while (len == sizeof(dummy));
+-    qxl_set_irq(d);
++    SimpleSpiceDisplay *ssd = opaque;
++    unsigned char cmd;
++    int len, set_irq = 0;
++    int create_update = 0;
++
++    while (1) {
++        cmd = 0;
++        len = read(ssd->pipe[0], &cmd, sizeof(cmd));
++        if (len < 0) {
++            if (errno == EINTR) {
++                continue;
++            }
++            if (errno == EAGAIN) {
++                break;
++            }
++            perror("qxl: pipe_read: read failed");
++            break;
++        }
++        switch (cmd) {
++        case QXL_SERVER_SET_IRQ:
++            set_irq = 1;
++            break;
++        case QXL_SERVER_CREATE_UPDATE:
++            create_update = 1;
++            break;
++        default:
++            fprintf(stderr, "%s: unknown cmd %u\n", __FUNCTION__, cmd);
++            abort();
++        }
++    }
++    /* no need to do either operation more than once */
++    if (create_update) {
++        assert(ssd->update == NULL);
++        ssd->update = qemu_spice_create_update(ssd);
++        if (ssd->update == NULL) {
++            ssd->update = QXL_EMPTY_UPDATE;
++        }
++        ssd->worker->wakeup(ssd->worker);
++    }
++    if (set_irq) {
++        qxl_set_irq(container_of(ssd, PCIQXLDevice, ssd));
++    }
+ }
+ 
+-/* called from spice server thread context only */
+ static void qxl_send_events(PCIQXLDevice *d, uint32_t events)
+ {
+     uint32_t old_pending;
+@@ -1082,9 +1123,11 @@ static void qxl_send_events(PCIQXLDevice *d, uint32_t events)
+         /* running in io_thread thread */
+         qxl_set_irq(d);
+     } else {
+-        if (write(d->ssd.pipe[1], d, 1) != 1) {
+-            dprint(d, 1, "%s: write to pipe failed\n", __FUNCTION__);
+-        }
++        /* called from spice-server thread */
++        int ret;
++        unsigned char ack = QXL_SERVER_SET_IRQ;
++        ret = write(d->ssd.pipe[1], &ack, 1);
++        assert(ret == 1);
+     }
+ }
+ 
+diff --git a/ui/spice-display.c b/ui/spice-display.c
+index ec6e0cb..bdd14b8 100644
+--- a/ui/spice-display.c
++++ b/ui/spice-display.c
+@@ -294,18 +294,39 @@ static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info)
+     info->n_surfaces = NUM_SURFACES;
+ }
+ 
++/* Called from spice server thread context (via interface_get_command) */
++int qxl_vga_mode_get_command(
++    SimpleSpiceDisplay *ssd, struct QXLCommandExt *ext)
++{
++    SimpleSpiceUpdate *update;
++    unsigned char req;
++    int r;
++
++    update = ssd->update;
++    if (update != NULL) {
++        ssd->waiting_for_update = 0;
++        ssd->update = NULL;
++        if (update != QXL_EMPTY_UPDATE) {
++            *ext = update->ext;
++            return true;
++        }
++    } else {
++        if (!ssd->waiting_for_update) {
++            ssd->waiting_for_update = 1;
++            req = QXL_SERVER_CREATE_UPDATE;
++            r = write(ssd->pipe[1], &req , 1);
++            assert(r == 1);
++        }
++    }
++    return false;
++}
++
+ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
+ {
+     SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
+-    SimpleSpiceUpdate *update;
+ 
+     dprint(3, "%s:\n", __FUNCTION__);
+-    update = qemu_spice_create_update(ssd);
+-    if (update == NULL) {
+-        return false;
+-    }
+-    *ext = update->ext;
+-    return true;
++    return qxl_vga_mode_get_command(ssd, ext);
+ }
+ 
+ static int interface_req_cmd_notification(QXLInstance *sin)
+@@ -394,6 +415,45 @@ static DisplayChangeListener display_listener = {
+     .dpy_refresh = display_refresh,
+ };
+ 
++static void pipe_read(void *opaque)
++{
++    SimpleSpiceDisplay *ssd = opaque;
++    unsigned char cmd;
++    int len, create_update = 0;
++
++    while (1) {
++        cmd = 0;
++        len = read(ssd->pipe[0], &cmd, sizeof(cmd));
++        if (len < 0) {
++            if (errno == EINTR) {
++                continue;
++            }
++            if (errno == EAGAIN) {
++                break;
++            }
++            perror("qxl: pipe_read: read failed");
++            break;
++        }
++        switch (cmd) {
++        case QXL_SERVER_CREATE_UPDATE:
++            create_update = 1;
++            break;
++        default:
++            fprintf(stderr, "%s: unknown cmd %u\n", __FUNCTION__, cmd);
++            abort();
++        }
++    }
++    /* no need to do this more than once */
++    if (create_update) {
++        assert(ssd->update == NULL);
++        ssd->update = qemu_spice_create_update(ssd);
++        if (ssd->update == NULL) {
++            ssd->update = QXL_EMPTY_UPDATE;
++        }
++        ssd->worker->wakeup(ssd->worker);
++    }
++}
++
+ void qxl_create_server_to_iothread_pipe(SimpleSpiceDisplay *ssd,
+     IOHandler *pipe_read)
+ {
+@@ -427,6 +487,7 @@ void qemu_spice_display_init(DisplayState *ds)
+     qemu_spice_add_interface(&sdpy.qxl.base);
+     assert(sdpy.worker);
+ 
++    qxl_create_server_to_iothread_pipe(&sdpy, pipe_read);
+     qemu_add_vm_change_state_handler(qemu_spice_vm_change_state_handler, &sdpy);
+     qemu_spice_create_host_memslot(&sdpy);
+     qemu_spice_create_host_primary(&sdpy);
+diff --git a/ui/spice-display.h b/ui/spice-display.h
+index 3e6cf7c..2be6a34 100644
+--- a/ui/spice-display.h
++++ b/ui/spice-display.h
+@@ -31,6 +31,15 @@
+ 
+ #define NUM_SURFACES 1024
+ 
++/* For commands/requests from server thread to iothread */
++#define QXL_EMPTY_UPDATE ((void *)-1)
++enum {
++    QXL_SERVER_SET_IRQ = 1,
++    QXL_SERVER_CREATE_UPDATE,
++};
++
++struct SimpleSpiceUpdate;
++
+ typedef struct SimpleSpiceDisplay {
+     DisplayState *ds;
+     void *buf;
+@@ -48,6 +57,10 @@ typedef struct SimpleSpiceDisplay {
+      * and in native mode) and without qxl */
+     pthread_t          main;
+     int                pipe[2];     /* to iothread */
++
++    /* ssd updates (one request/command at a time) */
++    struct SimpleSpiceUpdate *update;
++    int waiting_for_update;
+ } SimpleSpiceDisplay;
+ 
+ typedef struct SimpleSpiceUpdate {
+@@ -71,6 +84,9 @@ void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
+                                int x, int y, int w, int h);
+ void qemu_spice_display_resize(SimpleSpiceDisplay *ssd);
+ void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd);
++/* shared with qxl.c in vga mode and ui/spice-display (no qxl mode) */
++int qxl_vga_mode_get_command(
++    SimpleSpiceDisplay *ssd, struct QXLCommandExt *ext);
+ /* used by both qxl and spice-display */
+ void qxl_create_server_to_iothread_pipe(SimpleSpiceDisplay *ssd,
+     IOHandler *pipe_read);
+-- 
+1.7.3.2
+
diff --git a/0003-add-spice-into-the-configure-file.patch b/0003-add-spice-into-the-configure-file.patch
deleted file mode 100644
index 3d4eb0a..0000000
--- a/0003-add-spice-into-the-configure-file.patch
+++ /dev/null
@@ -1,94 +0,0 @@
-From 0034da7fb15d1225e0fd725009743d48511a90b7 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Wed, 24 Mar 2010 10:26:51 +0100
-Subject: [PATCH 03/39] add spice into the configure file
-
----
- configure |   36 ++++++++++++++++++++++++++++++++++++
- 1 files changed, 36 insertions(+), 0 deletions(-)
-
-diff --git a/configure b/configure
-index e09c442..2aaa6d7 100755
---- a/configure
-+++ b/configure
-@@ -331,6 +331,7 @@ cpu_emulation="yes"
- check_utests="no"
- user_pie="no"
- zero_malloc=""
-+spice=""
-
- # OS specific
- if check_define __linux__ ; then
-@@ -647,6 +648,10 @@ for opt do
-   ;;
-   --enable-kvm-device-assignment) kvm_cap_device_assignment="yes"
-   ;;
-+  --disable-spice) spice="no"
-+  ;;
-+  --enable-spice) spice="yes"
-+  ;;
-   --enable-profiler) profiler="yes"
-   ;;
-   --enable-cocoa)
-@@ -933,6 +938,8 @@ echo "  --enable-docs            enable documentation build"
- echo "  --disable-docs           disable documentation build"
- echo "  --disable-vhost-net      disable vhost-net acceleration support"
- echo "  --enable-vhost-net       enable vhost-net acceleration support"
-+echo "  --disable-spice          disable spice"
-+echo "  --enable-spice           enable spice"
- echo ""
- echo "NOTE: The object files are built at the place where configure is launched"
- exit 1
-@@ -2184,6 +2191,30 @@ if compile_prog "" ""; then
-     gcc_attribute_warn_unused_result=yes
- fi
-
-+# spice probe
-+if test "$spice" != "no" ; then
-+  cat > $TMPC << EOF
-+#include <spice.h>
-+int main(void) { spice_server_new(); return 0; }
-+EOF
-+  spice_proto_ver=$($pkgconfig --modversion spice-protocol 2>/dev/null)
-+  spice_server_ver=$($pkgconfig --modversion spice-server 2>/dev/null)
-+  spice_cflags=$($pkgconfig --cflags spice-protocol spice-server 2>/dev/null)
-+  spice_libs=$($pkgconfig --libs spice-protocol spice-server 2>/dev/null)
-+  if compile_prog "$spice_cflags" "$spice_libs" ; then
-+    spice="yes"
-+    libs_softmmu="$libs_softmmu $spice_libs"
-+    QEMU_CFLAGS="$QEMU_CFLAGS $spice_cflags"
-+  else
-+    if test "$spice" = "yes" ; then
-+      feature_not_found "spice"
-+    fi
-+    spice="no"
-+  fi
-+fi
-+
-+##########################################
-+
- ##########################################
- # check if we have fdatasync
-
-@@ -2329,6 +2360,7 @@ echo "preadv support    $preadv"
- echo "fdatasync         $fdatasync"
- echo "uuid support      $uuid"
- echo "vhost-net support $vhost_net"
-+echo "spice support     $spice"
-
- if test $sdl_too_old = "yes"; then
- echo "-> Your SDL version is too old - please upgrade to have SDL support"
-@@ -2574,6 +2606,10 @@ else
-   echo "CONFIG_NO_CPU_EMULATION=y" >> $config_host_mak
- fi
-
-+if test "$spice" = "yes" ; then
-+  echo "CONFIG_SPICE=y" >> $config_host_mak
-+fi
-+
- # XXX: suppress that
- if [ "$bsd" = "yes" ] ; then
-   echo "CONFIG_BSD=y" >> $config_host_mak
--- 
-1.7.2.3
-
diff --git a/0003-qxl-spice-remove-qemu_mutex_-un-lock_iothread-around.patch b/0003-qxl-spice-remove-qemu_mutex_-un-lock_iothread-around.patch
new file mode 100644
index 0000000..92a148e
--- /dev/null
+++ b/0003-qxl-spice-remove-qemu_mutex_-un-lock_iothread-around.patch
@@ -0,0 +1,148 @@
+>From d413b3c36cbd9820c5b9492b52caa421abccf745 Mon Sep 17 00:00:00 2001
+From: Alon Levy <alevy@redhat.com>
+Date: Wed, 16 Mar 2011 15:46:22 +0100
+Subject: [PATCH 3/4] qxl/spice: remove qemu_mutex_{un,}lock_iothread around dispatcher
+
+with the previous patch making sure get_command no longer needs to lock,
+there is no reason to drop the qemu iothread mutex in qxl.c and in
+ui/spice-display.c
+
+The only location where the lock remains are the cursor related callbacks,
+that path is currently broken. It is only triggered if running spice and sdl,
+which is broken already before that.
+---
+ hw/qxl.c           |    8 --------
+ ui/spice-display.c |   19 +++----------------
+ 2 files changed, 3 insertions(+), 24 deletions(-)
+
+diff --git a/hw/qxl.c b/hw/qxl.c
+index 64580f1..cf3c938 100644
+--- a/hw/qxl.c
++++ b/hw/qxl.c
+@@ -670,10 +670,8 @@ static void qxl_hard_reset(PCIQXLDevice *d, int loadvm)
+     dprint(d, 1, "%s: start%s\n", __FUNCTION__,
+            loadvm ? " (loadvm)" : "");
+ 
+-    qemu_mutex_unlock_iothread();
+     d->ssd.worker->reset_cursor(d->ssd.worker);
+     d->ssd.worker->reset_image_cache(d->ssd.worker);
+-    qemu_mutex_lock_iothread();
+     qxl_reset_surfaces(d);
+     qxl_reset_memslots(d);
+ 
+@@ -803,9 +801,7 @@ static void qxl_reset_surfaces(PCIQXLDevice *d)
+ {
+     dprint(d, 1, "%s:\n", __FUNCTION__);
+     d->mode = QXL_MODE_UNDEFINED;
+-    qemu_mutex_unlock_iothread();
+     d->ssd.worker->destroy_surfaces(d->ssd.worker);
+-    qemu_mutex_lock_iothread();
+     memset(&d->guest_surfaces.cmds, 0, sizeof(d->guest_surfaces.cmds));
+ }
+ 
+@@ -874,9 +870,7 @@ static void qxl_destroy_primary(PCIQXLDevice *d)
+     dprint(d, 1, "%s\n", __FUNCTION__);
+ 
+     d->mode = QXL_MODE_UNDEFINED;
+-    qemu_mutex_unlock_iothread();
+     d->ssd.worker->destroy_primary_surface(d->ssd.worker, 0);
+-    qemu_mutex_lock_iothread();
+ }
+ 
+ static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
+@@ -946,10 +940,8 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
+     case QXL_IO_UPDATE_AREA:
+     {
+         QXLRect update = d->ram->update_area;
+-        qemu_mutex_unlock_iothread();
+         d->ssd.worker->update_area(d->ssd.worker, d->ram->update_surface,
+                                    &update, NULL, 0, 0);
+-        qemu_mutex_lock_iothread();
+         break;
+     }
+     case QXL_IO_NOTIFY_CMD:
+diff --git a/ui/spice-display.c b/ui/spice-display.c
+index bdd14b8..ecb22cc 100644
+--- a/ui/spice-display.c
++++ b/ui/spice-display.c
+@@ -62,13 +62,7 @@ void qemu_spice_rect_union(QXLRect *dest, const QXLRect *r)
+     dest->right = MAX(dest->right, r->right);
+ }
+ 
+-/*
+- * Called from spice server thread context (via interface_get_command).
+- *
+- * We must aquire the global qemu mutex here to make sure the
+- * DisplayState (+DisplaySurface) we are accessing doesn't change
+- * underneath us.
+- */
++/* Called from io-thread context (via pipe_read) */
+ SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
+ {
+     SimpleSpiceUpdate *update;
+@@ -78,9 +72,7 @@ SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
+     uint8_t *src, *dst;
+     int by, bw, bh;
+ 
+-    qemu_mutex_lock_iothread();
+     if (qemu_spice_rect_is_empty(&ssd->dirty)) {
+-        qemu_mutex_unlock_iothread();
+         return NULL;
+     };
+ 
+@@ -141,7 +133,6 @@ SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
+     cmd->data = (intptr_t)drawable;
+ 
+     memset(&ssd->dirty, 0, sizeof(ssd->dirty));
+-    qemu_mutex_unlock_iothread();
+     return update;
+ }
+ 
+@@ -169,6 +160,7 @@ void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd)
+     ssd->worker->add_memslot(ssd->worker, &memslot);
+ }
+ 
++/* called from iothread (main) or a vcpu-thread */
+ void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
+ {
+     QXLDevSurfaceCreate surface;
+@@ -186,18 +178,14 @@ void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
+     surface.mem        = (intptr_t)ssd->buf;
+     surface.group_id   = MEMSLOT_GROUP_HOST;
+ 
+-    qemu_mutex_unlock_iothread();
+     ssd->worker->create_primary_surface(ssd->worker, 0, &surface);
+-    qemu_mutex_lock_iothread();
+ }
+ 
+ void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd)
+ {
+     dprint(1, "%s:\n", __FUNCTION__);
+ 
+-    qemu_mutex_unlock_iothread();
+     ssd->worker->destroy_primary_surface(ssd->worker, 0);
+-    qemu_mutex_lock_iothread();
+ }
+ 
+ void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason)
+@@ -207,9 +195,7 @@ void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason)
+     if (running) {
+         ssd->worker->start(ssd->worker);
+     } else {
+-        qemu_mutex_unlock_iothread();
+         ssd->worker->stop(ssd->worker);
+-        qemu_mutex_lock_iothread();
+     }
+     ssd->running = running;
+ }
+@@ -233,6 +219,7 @@ void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
+     qemu_spice_rect_union(&ssd->dirty, &update_area);
+ }
+ 
++/* called only from iothread (main) */
+ void qemu_spice_display_resize(SimpleSpiceDisplay *ssd)
+ {
+     dprint(1, "%s:\n", __FUNCTION__);
+-- 
+1.7.3.2
+
diff --git a/0004-hw-qxl-render-drop-cursor-locks-replace-with-pipe.patch b/0004-hw-qxl-render-drop-cursor-locks-replace-with-pipe.patch
new file mode 100644
index 0000000..03daba4
--- /dev/null
+++ b/0004-hw-qxl-render-drop-cursor-locks-replace-with-pipe.patch
@@ -0,0 +1,249 @@
+>From 1a33e5f2fa6de800047517a6f3251dc7191c97b5 Mon Sep 17 00:00:00 2001
+From: Alon Levy <alevy@redhat.com>
+Date: Wed, 16 Mar 2011 16:02:16 +0100
+Subject: [PATCH 4/4] hw/qxl-render: drop cursor locks, replace with pipe
+
+Switching locking protection of ds->cursor_set/cursor_move to moving
+every call to these functions into the iothread and using the ssd->pipe
+to transfer that, adding QXL_SERVER_CURSOR_SET, QXL_SERVER_CURSOR_MOVE.
+
+This is tested with both -vnc :0 -spice and -sdl -spice.
+---
+ hw/qxl-render.c    |   25 +++++++++-----
+ hw/qxl.c           |   90 ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ hw/qxl.h           |    4 ++
+ ui/spice-display.h |   13 +++++++-
+ 4 files changed, 122 insertions(+), 10 deletions(-)
+
+diff --git a/hw/qxl-render.c b/hw/qxl-render.c
+index 58965e0..6759edb 100644
+--- a/hw/qxl-render.c
++++ b/hw/qxl-render.c
+@@ -178,7 +178,6 @@ fail:
+     return NULL;
+ }
+ 
+-
+ /* called from spice server thread context only */
+ void qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext)
+ {
+@@ -209,18 +208,26 @@ void qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext)
+         if (c == NULL) {
+             c = cursor_builtin_left_ptr();
+         }
+-        qemu_mutex_lock_iothread();
+-        qxl->ssd.ds->cursor_define(c);
+-        qxl->ssd.ds->mouse_set(x, y, 1);
+-        qemu_mutex_unlock_iothread();
+-        cursor_put(c);
++        qxl_server_request_cursor_set(qxl, c, x, y);
+         break;
+     case QXL_CURSOR_MOVE:
+         x = cmd->u.position.x;
+         y = cmd->u.position.y;
+-        qemu_mutex_lock_iothread();
+-        qxl->ssd.ds->mouse_set(x, y, 1);
+-        qemu_mutex_unlock_iothread();
++        qxl_server_request_cursor_move(qxl, x, y);
+         break;
+     }
+ }
++
++/* called from iothread only (via qxl.c:pipe_read) */
++void qxl_render_cursor_set(SimpleSpiceDisplay *ssd, QEMUCursor *c, int x, int y)
++{
++    ssd->ds->cursor_define(c);
++    ssd->ds->mouse_set(x, y, 1);
++    cursor_put(c);
++}
++
++/* called from iothread only (via qxl.c:pipe_read) */
++void qxl_render_cursor_move(SimpleSpiceDisplay *ssd, int x, int y)
++{
++    ssd->ds->mouse_set(x, y, 1);
++}
+diff --git a/hw/qxl.c b/hw/qxl.c
+index cf3c938..4c27deb 100644
+--- a/hw/qxl.c
++++ b/hw/qxl.c
+@@ -117,6 +117,27 @@ static QXLMode qxl_modes[] = {
+ #endif
+ };
+ 
++typedef struct __attribute__ ((__packed__)) {
++    QEMUCursor *c;
++    int x;
++    int y;
++} QXLServerCursorSet;
++
++typedef struct __attribute__ ((__packed__)) {
++    int x;
++    int y;
++} QXLServerCursorMove;
++
++typedef struct __attribute__ ((__packed__)) {
++    unsigned char req;
++    QXLServerCursorMove data;
++} QXLServerCursorMoveRequest;
++
++typedef struct __attribute__ ((__packed__)) {
++    unsigned char req;
++    QXLServerCursorSet data;
++} QXLServerCursorSetRequest;
++
+ static PCIQXLDevice *qxl0;
+ 
+ static void qxl_send_events(PCIQXLDevice *d, uint32_t events);
+@@ -337,6 +358,33 @@ static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info)
+ }
+ 
+ /* called from spice server thread context only */
++void qxl_server_request_cursor_set(PCIQXLDevice *qxl, QEMUCursor *c, int x, int y)
++{
++    QXLServerCursorSetRequest req;
++    int r;
++
++    req.req = QXL_SERVER_CURSOR_SET;
++    req.data.c = c;
++    req.data.x = x;
++    req.data.y = y;
++    r = write(qxl->ssd.pipe[1], &req, sizeof(req));
++    assert(r == sizeof(req));
++}
++
++/* called from spice server thread context only */
++void qxl_server_request_cursor_move(PCIQXLDevice *qxl, int x, int y)
++{
++    QXLServerCursorMoveRequest req;
++    int r;
++
++    req.req = QXL_SERVER_CURSOR_MOVE;
++    req.data.x = x;
++    req.data.y = y;
++    r = write(qxl->ssd.pipe[1], &req, sizeof(req));
++    assert(r == sizeof(req));
++}
++
++/* called from spice server thread context only */
+ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
+ {
+     PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
+@@ -1055,12 +1103,37 @@ static void qxl_map(PCIDevice *pci, int region_num,
+     }
+ }
+ 
++static void read_bytes(int fd, void *buf, int len_requested)
++{
++    int len;
++    int total_len = 0;
++
++    do {
++        len = read(fd, buf, len_requested - total_len);
++        if (len < 0) {
++            if (errno == EINTR || errno == EAGAIN) {
++                continue;
++            }
++            perror("qxl: pipe_read: read failed");
++            /* will abort once it's out of the while loop */
++            break;
++        }
++        total_len += len;
++        buf = (uint8_t *)buf + len;
++    } while (total_len < len_requested);
++    assert(total_len == len_requested);
++}
++
+ static void pipe_read(void *opaque)
+ {
+     SimpleSpiceDisplay *ssd = opaque;
+     unsigned char cmd;
+     int len, set_irq = 0;
+     int create_update = 0;
++    int cursor_set = 0;
++    int cursor_move = 0;
++    QXLServerCursorSet cursor_set_data;
++    QXLServerCursorMove cursor_move_data;
+ 
+     while (1) {
+         cmd = 0;
+@@ -1082,6 +1155,17 @@ static void pipe_read(void *opaque)
+         case QXL_SERVER_CREATE_UPDATE:
+             create_update = 1;
+             break;
++        case QXL_SERVER_CURSOR_SET:
++            if (cursor_set == 1) {
++                cursor_put(cursor_set_data.c);
++            }
++            cursor_set = 1;
++            read_bytes(ssd->pipe[0], &cursor_set_data, sizeof(cursor_set_data));
++            break;
++        case QXL_SERVER_CURSOR_MOVE:
++            cursor_move = 1;
++            read_bytes(ssd->pipe[0], &cursor_move_data, sizeof(cursor_move_data));
++            break;
+         default:
+             fprintf(stderr, "%s: unknown cmd %u\n", __FUNCTION__, cmd);
+             abort();
+@@ -1099,6 +1183,12 @@ static void pipe_read(void *opaque)
+     if (set_irq) {
+         qxl_set_irq(container_of(ssd, PCIQXLDevice, ssd));
+     }
++    if (cursor_move) {
++        qxl_render_cursor_move(ssd, cursor_move_data.x, cursor_move_data.y);
++    }
++    if (cursor_set) {
++        qxl_render_cursor_set(ssd, cursor_set_data.c, cursor_set_data.x, cursor_set_data.y);
++    }
+ }
+ 
+ static void qxl_send_events(PCIQXLDevice *d, uint32_t events)
+diff --git a/hw/qxl.h b/hw/qxl.h
+index 701245f..f4f99ec 100644
+--- a/hw/qxl.h
++++ b/hw/qxl.h
+@@ -93,6 +93,8 @@ typedef struct PCIQXLDevice {
+ 
+ /* qxl.c */
+ void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id);
++void qxl_server_request_cursor_set(PCIQXLDevice *qxl, QEMUCursor *c, int x, int y);
++void qxl_server_request_cursor_move(PCIQXLDevice *qxl, int x, int y);
+ 
+ /* qxl-logger.c */
+ void qxl_log_cmd_cursor(PCIQXLDevice *qxl, QXLCursorCmd *cmd, int group_id);
+@@ -102,3 +104,5 @@ void qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext);
+ void qxl_render_resize(PCIQXLDevice *qxl);
+ void qxl_render_update(PCIQXLDevice *qxl);
+ void qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext);
++void qxl_render_cursor_set(SimpleSpiceDisplay *ssd, QEMUCursor *c, int x, int y);
++void qxl_render_cursor_move(SimpleSpiceDisplay *ssd, int x, int y);
+diff --git a/ui/spice-display.h b/ui/spice-display.h
+index 2be6a34..bbfd689 100644
+--- a/ui/spice-display.h
++++ b/ui/spice-display.h
+@@ -31,11 +31,22 @@
+ 
+ #define NUM_SURFACES 1024
+ 
+-/* For commands/requests from server thread to iothread */
++/*
++ * Commands/requests from server thread to iothread.
++ * Note that CREATE_UPDATE is used both with qxl and without it (spice-display)
++ * the others are only used with the qxl device.
++ *
++ * SET_IRQ - just the request is sent (1 byte)
++ * CREATE_UPDATE - jus the request is sent (1 byte)
++ * CURSOR_SET - send QXLServerRequestCursorSet
++ * CURSOR_MOVE - send QXLServerRequestCursorMove
++ */
+ #define QXL_EMPTY_UPDATE ((void *)-1)
+ enum {
+     QXL_SERVER_SET_IRQ = 1,
+     QXL_SERVER_CREATE_UPDATE,
++    QXL_SERVER_CURSOR_SET,
++    QXL_SERVER_CURSOR_MOVE
+ };
+ 
+ struct SimpleSpiceUpdate;
+-- 
+1.7.3.2
+
diff --git a/0004-spice-core-bits.patch b/0004-spice-core-bits.patch
deleted file mode 100644
index a4b156b..0000000
--- a/0004-spice-core-bits.patch
+++ /dev/null
@@ -1,333 +0,0 @@
-From 67361a4ad5c99c5dfecdb9d2fc1ba794c38c44ff Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Thu, 11 Mar 2010 11:13:27 -0300
-Subject: [PATCH 04/39] spice: core bits
-
-Add -spice command line switch.  Has support setting passwd and port for
-now.  With this patch applied the spice client can successfully connect
-to qemu.  You can't do anything useful yet though.
----
- Makefile.objs   |    2 +
- qemu-config.c   |   23 ++++++++
- qemu-config.h   |    1 +
- qemu-options.hx |    8 +++
- qemu-spice.h    |   22 ++++++++
- spice.c         |  151 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
- vl.c            |   15 ++++++
- 7 files changed, 222 insertions(+), 0 deletions(-)
- create mode 100644 qemu-spice.h
- create mode 100644 spice.c
-
-diff --git a/Makefile.objs b/Makefile.objs
-index 147051f..569b458 100644
---- a/Makefile.objs
-+++ b/Makefile.objs
-@@ -89,6 +89,8 @@ common-obj-y += pflib.o
- common-obj-$(CONFIG_BRLAPI) += baum.o
- common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o
-
-+common-obj-$(CONFIG_SPICE) += spice.o
-+
- audio-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
- audio-obj-$(CONFIG_SDL) += sdlaudio.o
- audio-obj-$(CONFIG_OSS) += ossaudio.o
-diff --git a/qemu-config.c b/qemu-config.c
-index 08ee553..8a894cf 100644
---- a/qemu-config.c
-+++ b/qemu-config.c
-@@ -346,6 +346,26 @@ QemuOptsList qemu_cpudef_opts = {
-     },
- };
-
-+#ifdef CONFIG_SPICE
-+QemuOptsList qemu_spice_opts = {
-+    .name = "spice",
-+    .head = QTAILQ_HEAD_INITIALIZER(qemu_spice_opts.head),
-+    .desc = {
-+        {
-+            .name = "port",
-+            .type = QEMU_OPT_NUMBER,
-+        },{
-+            .name = "password",
-+            .type = QEMU_OPT_STRING,
-+        },{
-+            .name = "disable-ticketing",
-+            .type = QEMU_OPT_BOOL,
-+        },
-+        { /* end if list */ }
-+    },
-+};
-+#endif
-+
- static QemuOptsList *vm_config_groups[] = {
-     &qemu_drive_opts,
-     &qemu_chardev_opts,
-@@ -356,6 +376,9 @@ static QemuOptsList *vm_config_groups[] = {
-     &qemu_global_opts,
-     &qemu_mon_opts,
-     &qemu_cpudef_opts,
-+#ifdef CONFIG_SPICE
-+    &qemu_spice_opts,
-+#endif
-     NULL,
- };
-
-diff --git a/qemu-config.h b/qemu-config.h
-index dca69d4..3a90213 100644
---- a/qemu-config.h
-+++ b/qemu-config.h
-@@ -14,6 +14,7 @@ extern QemuOptsList qemu_rtc_opts;
- extern QemuOptsList qemu_global_opts;
- extern QemuOptsList qemu_mon_opts;
- extern QemuOptsList qemu_cpudef_opts;
-+extern QemuOptsList qemu_spice_opts;
-
- QemuOptsList *qemu_find_opts(const char *group);
- int qemu_set_option(const char *str);
-diff --git a/qemu-options.hx b/qemu-options.hx
-index 66c84a0..85551cc 100644
---- a/qemu-options.hx
-+++ b/qemu-options.hx
-@@ -676,6 +676,14 @@ STEXI
- Enable SDL.
- ETEXI
-
-+#ifdef CONFIG_SPICE
-+DEF("spice", HAS_ARG, QEMU_OPTION_spice,
-+    "-spice <args>   use spice\n", QEMU_ARCH_ALL)
-+STEXI
-+Use Spice.
-+ETEXI
-+#endif
-+
- DEF("portrait", 0, QEMU_OPTION_portrait,
-     "-portrait       rotate graphical output 90 deg left (only PXA LCD)\n",
-     QEMU_ARCH_ALL)
-diff --git a/qemu-spice.h b/qemu-spice.h
-new file mode 100644
-index 0000000..5597576
---- /dev/null
-+++ b/qemu-spice.h
-@@ -0,0 +1,22 @@
-+#ifndef QEMU_SPICE_H
-+#define QEMU_SPICE_H
-+
-+#ifdef CONFIG_SPICE
-+
-+#include <spice.h>
-+
-+#include "qemu-option.h"
-+#include "qemu-config.h"
-+
-+extern SpiceServer *spice_server;
-+extern int using_spice;
-+
-+void qemu_spice_init(void);
-+
-+#else  /* CONFIG_SPICE */
-+
-+#define using_spice 0
-+
-+#endif /* CONFIG_SPICE */
-+
-+#endif /* QEMU_SPICE_H */
-diff --git a/spice.c b/spice.c
-new file mode 100644
-index 0000000..50fa5ca
---- /dev/null
-+++ b/spice.c
-@@ -0,0 +1,151 @@
-+#include <stdlib.h>
-+#include <stdio.h>
-+#include <string.h>
-+
-+#include <spice.h>
-+#include <spice-experimental.h>
-+
-+#include "qemu-common.h"
-+#include "qemu-spice.h"
-+#include "qemu-timer.h"
-+#include "qemu-queue.h"
-+#include "monitor.h"
-+
-+/* core bits */
-+
-+SpiceServer *spice_server;
-+int using_spice = 0;
-+
-+struct SpiceTimer {
-+    QEMUTimer *timer;
-+    QTAILQ_ENTRY(SpiceTimer) next;
-+};
-+static QTAILQ_HEAD(, SpiceTimer) timers = QTAILQ_HEAD_INITIALIZER(timers);
-+
-+static SpiceTimer *timer_add(SpiceTimerFunc func, void *opaque)
-+{
-+    SpiceTimer *timer;
-+
-+    timer = qemu_mallocz(sizeof(*timer));
-+    timer->timer = qemu_new_timer(rt_clock, func, opaque);
-+    QTAILQ_INSERT_TAIL(&timers, timer, next);
-+    return timer;
-+}
-+
-+static void timer_start(SpiceTimer *timer, uint32_t ms)
-+{
-+    qemu_mod_timer(timer->timer, qemu_get_clock(rt_clock) + ms);
-+}
-+
-+static void timer_cancel(SpiceTimer *timer)
-+{
-+    qemu_del_timer(timer->timer);
-+}
-+
-+static void timer_remove(SpiceTimer *timer)
-+{
-+    qemu_del_timer(timer->timer);
-+    qemu_free_timer(timer->timer);
-+    QTAILQ_REMOVE(&timers, timer, next);
-+    free(timer);
-+}
-+
-+struct SpiceWatch {
-+    int fd;
-+    int event_mask;
-+    SpiceWatchFunc func;
-+    void *opaque;
-+    QTAILQ_ENTRY(SpiceWatch) next;
-+};
-+static QTAILQ_HEAD(, SpiceWatch) watches = QTAILQ_HEAD_INITIALIZER(watches);
-+
-+static void watch_read(void *opaque)
-+{
-+    SpiceWatch *watch = opaque;
-+    watch->func(watch->fd, SPICE_WATCH_EVENT_READ, watch->opaque);
-+}
-+
-+static void watch_write(void *opaque)
-+{
-+    SpiceWatch *watch = opaque;
-+    watch->func(watch->fd, SPICE_WATCH_EVENT_WRITE, watch->opaque);
-+}
-+
-+static void watch_update_mask(SpiceWatch *watch, int event_mask)
-+{
-+    IOHandler *on_read = NULL;
-+    IOHandler *on_write = NULL;
-+
-+    watch->event_mask = event_mask;
-+    if (watch->event_mask & SPICE_WATCH_EVENT_READ)
-+        on_read = watch_read;
-+    if (watch->event_mask & SPICE_WATCH_EVENT_WRITE)
-+        on_read = watch_write;
-+    qemu_set_fd_handler(watch->fd, on_read, on_write, watch);
-+}
-+
-+static SpiceWatch *watch_add(int fd, int event_mask, SpiceWatchFunc func, void *opaque)
-+{
-+    SpiceWatch *watch;
-+
-+    watch = qemu_mallocz(sizeof(*watch));
-+    watch->fd     = fd;
-+    watch->func   = func;
-+    watch->opaque = opaque;
-+    QTAILQ_INSERT_TAIL(&watches, watch, next);
-+
-+    watch_update_mask(watch, event_mask);
-+    return watch;
-+}
-+
-+static void watch_remove(SpiceWatch *watch)
-+{
-+    watch_update_mask(watch, 0);
-+    QTAILQ_REMOVE(&watches, watch, next);
-+    qemu_free(watch);
-+}
-+
-+static SpiceCoreInterface core_interface = {
-+    .base.type          = SPICE_INTERFACE_CORE,
-+    .base.description   = "qemu core services",
-+    .base.major_version = SPICE_INTERFACE_CORE_MAJOR,
-+    .base.minor_version = SPICE_INTERFACE_CORE_MINOR,
-+
-+    .timer_add          = timer_add,
-+    .timer_start        = timer_start,
-+    .timer_cancel       = timer_cancel,
-+    .timer_remove       = timer_remove,
-+
-+    .watch_add          = watch_add,
-+    .watch_update_mask  = watch_update_mask,
-+    .watch_remove       = watch_remove,
-+};
-+
-+/* functions for the rest of qemu */
-+
-+void qemu_spice_init(void)
-+{
-+    QemuOpts *opts = QTAILQ_FIRST(&qemu_spice_opts.head);
-+    const char *password;
-+    int port;
-+
-+    if (!opts)
-+        return;
-+    port = qemu_opt_get_number(opts, "port", 0);
-+    if (!port)
-+        return;
-+    password = qemu_opt_get(opts, "password");
-+
-+    spice_server = spice_server_new();
-+    spice_server_set_port(spice_server, port);
-+    if (password)
-+        spice_server_set_ticket(spice_server, password, 0, 0, 0);
-+    if (qemu_opt_get_bool(opts, "disable-ticketing", 0))
-+        spice_server_set_noauth(spice_server);
-+
-+    /* TODO: make configurable via cmdline */
-+    spice_server_set_image_compression(spice_server, SPICE_IMAGE_COMPRESS_AUTO_GLZ);
-+
-+    spice_server_init(spice_server, &core_interface);
-+    using_spice = 1;
-+}
-diff --git a/vl.c b/vl.c
-index de8bad1..97897e0 100644
---- a/vl.c
-+++ b/vl.c
-@@ -162,6 +162,8 @@ int main(int argc, char **argv)
- #include "cpus.h"
- #include "arch_init.h"
-
-+#include "qemu-spice.h"
-+
- //#define DEBUG_NET
- //#define DEBUG_SLIRP
-
-@@ -2677,6 +2679,15 @@ int main(int argc, char **argv, char **envp)
-                     }
-                     break;
-                 }
-+#ifdef CONFIG_SPICE
-+            case QEMU_OPTION_spice:
-+                opts = qemu_opts_parse(&qemu_spice_opts, optarg, 0);
-+                if (!opts) {
-+                    fprintf(stderr, "parse error: %s\n", optarg);
-+                    exit(1);
-+                }
-+                break;
-+#endif
-             case QEMU_OPTION_writeconfig:
-                 {
-                     FILE *fp;
-@@ -2951,6 +2962,10 @@ int main(int argc, char **argv, char **envp)
-     }
-     qemu_add_globals();
-
-+#ifdef CONFIG_SPICE
-+    qemu_spice_init();
-+#endif
-+
-     machine->init(ram_size, boot_devices,
-                   kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
-
--- 
-1.7.2.3
-
diff --git a/0005-spice-add-keyboard.patch b/0005-spice-add-keyboard.patch
deleted file mode 100644
index 6394c15..0000000
--- a/0005-spice-add-keyboard.patch
+++ /dev/null
@@ -1,118 +0,0 @@
-From 90f6ec84332857752c252b1c3b89d86eb9714b0e Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Thu, 11 Mar 2010 11:13:28 -0300
-Subject: [PATCH 05/39] spice: add keyboard
-
-Open keyboard channel.  Now you can type into the spice client and the
-keyboard events are sent to your guest.  You'll need some other display
-like vnc to actually see the guest responding to them though.
----
- Makefile.objs |    2 +-
- qemu-spice.h  |    1 +
- spice-input.c |   57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- spice.c       |    2 ++
- 4 files changed, 61 insertions(+), 1 deletions(-)
- create mode 100644 spice-input.c
-
-diff --git a/Makefile.objs b/Makefile.objs
-index 569b458..023a0dc 100644
---- a/Makefile.objs
-+++ b/Makefile.objs
-@@ -89,7 +89,7 @@ common-obj-y += pflib.o
- common-obj-$(CONFIG_BRLAPI) += baum.o
- common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o
-
--common-obj-$(CONFIG_SPICE) += spice.o
-+common-obj-$(CONFIG_SPICE) += spice.o spice-input.o
-
- audio-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
- audio-obj-$(CONFIG_SDL) += sdlaudio.o
-diff --git a/qemu-spice.h b/qemu-spice.h
-index 5597576..ceb3db2 100644
---- a/qemu-spice.h
-+++ b/qemu-spice.h
-@@ -12,6 +12,7 @@ extern SpiceServer *spice_server;
- extern int using_spice;
-
- void qemu_spice_init(void);
-+void qemu_spice_input_init(void);
-
- #else  /* CONFIG_SPICE */
-
-diff --git a/spice-input.c b/spice-input.c
-new file mode 100644
-index 0000000..e1014d7
---- /dev/null
-+++ b/spice-input.c
-@@ -0,0 +1,57 @@
-+#include <stdlib.h>
-+#include <stdio.h>
-+#include <string.h>
-+
-+#include <spice.h>
-+
-+#include "qemu-common.h"
-+#include "qemu-spice.h"
-+#include "console.h"
-+
-+/* keyboard bits */
-+
-+typedef struct QemuSpiceKbd {
-+    SpiceKbdInstance sin;
-+    int ledstate;
-+} QemuSpiceKbd;
-+
-+static void kbd_push_key(SpiceKbdInstance *sin, uint8_t frag);
-+static uint8_t kbd_get_leds(SpiceKbdInstance *sin);
-+static void kbd_leds(void *opaque, int l);
-+
-+static const SpiceKbdInterface kbd_interface = {
-+    .base.type          = SPICE_INTERFACE_KEYBOARD,
-+    .base.description   = "qemu keyboard",
-+    .base.major_version = SPICE_INTERFACE_KEYBOARD_MAJOR,
-+    .base.minor_version = SPICE_INTERFACE_KEYBOARD_MINOR,
-+    .push_scan_freg     = kbd_push_key,
-+    .get_leds           = kbd_get_leds,
-+};
-+
-+static void kbd_push_key(SpiceKbdInstance *sin, uint8_t frag)
-+{
-+    kbd_put_keycode(frag);
-+}
-+
-+static uint8_t kbd_get_leds(SpiceKbdInstance *sin)
-+{
-+    QemuSpiceKbd *kbd = container_of(sin, QemuSpiceKbd, sin);
-+    return kbd->ledstate;
-+}
-+
-+static void kbd_leds(void *opaque, int ledstate)
-+{
-+    QemuSpiceKbd *kbd = opaque;
-+    kbd->ledstate = ledstate;
-+    spice_server_kbd_leds(&kbd->sin, ledstate);
-+}
-+
-+void qemu_spice_input_init(void)
-+{
-+    QemuSpiceKbd *kbd;
-+
-+    kbd = qemu_mallocz(sizeof(*kbd));
-+    kbd->sin.base.sif = &kbd_interface.base;
-+    spice_server_add_interface(spice_server, &kbd->sin.base);
-+    qemu_add_led_event_handler(kbd_leds, kbd);
-+}
-diff --git a/spice.c b/spice.c
-index 50fa5ca..c763d52 100644
---- a/spice.c
-+++ b/spice.c
-@@ -148,4 +148,6 @@ void qemu_spice_init(void)
-
-     spice_server_init(spice_server, &core_interface);
-     using_spice = 1;
-+
-+    qemu_spice_input_init();
- }
--- 
-1.7.2.3
-
diff --git a/0006-spice-add-mouse.patch b/0006-spice-add-mouse.patch
deleted file mode 100644
index ea41880..0000000
--- a/0006-spice-add-mouse.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From e18846175191cbc590ac46fa3820726aeebd6d48 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Thu, 11 Mar 2010 11:13:29 -0300
-Subject: [PATCH 06/39] spice: add mouse
-
-Open mouse channel.  Now you can move the guests mouse pointer.
-No tablet / absolute positioning (yet) though.
----
- spice-input.c |   31 +++++++++++++++++++++++++++++++
- 1 files changed, 31 insertions(+), 0 deletions(-)
-
-diff --git a/spice-input.c b/spice-input.c
-index e1014d7..8f3deb4 100644
---- a/spice-input.c
-+++ b/spice-input.c
-@@ -46,12 +46,43 @@ static void kbd_leds(void *opaque, int ledstate)
-     spice_server_kbd_leds(&kbd->sin, ledstate);
- }
-
-+/* mouse bits */
-+
-+typedef struct QemuSpiceMouse {
-+    SpiceMouseInstance sin;
-+} QemuSpiceMouse;
-+
-+static void mouse_motion(SpiceMouseInstance *sin, int dx, int dy, int dz,
-+                         uint32_t buttons_state)
-+{
-+    kbd_mouse_event(dx, dy, dz, buttons_state);
-+}
-+
-+static void mouse_buttons(SpiceMouseInstance *sin, uint32_t buttons_state)
-+{
-+    kbd_mouse_event(0, 0, 0, buttons_state);
-+}
-+
-+static const SpiceMouseInterface mouse_interface = {
-+    .base.type          = SPICE_INTERFACE_MOUSE,
-+    .base.description   = "mouse",
-+    .base.major_version = SPICE_INTERFACE_MOUSE_MAJOR,
-+    .base.minor_version = SPICE_INTERFACE_MOUSE_MINOR,
-+    .motion             = mouse_motion,
-+    .buttons            = mouse_buttons,
-+};
-+
- void qemu_spice_input_init(void)
- {
-     QemuSpiceKbd *kbd;
-+    QemuSpiceMouse *mouse;
-
-     kbd = qemu_mallocz(sizeof(*kbd));
-     kbd->sin.base.sif = &kbd_interface.base;
-     spice_server_add_interface(spice_server, &kbd->sin.base);
-     qemu_add_led_event_handler(kbd_leds, kbd);
-+
-+    mouse = qemu_mallocz(sizeof(*mouse));
-+    mouse->sin.base.sif = &mouse_interface.base;
-+    spice_server_add_interface(spice_server, &mouse->sin.base);
- }
--- 
-1.7.2.3
-
diff --git a/0007-spice-simple-display.patch b/0007-spice-simple-display.patch
deleted file mode 100644
index e59caa1..0000000
--- a/0007-spice-simple-display.patch
+++ /dev/null
@@ -1,532 +0,0 @@
-From 0143117eb5e6233fdeff3b679492b51148cc8f85 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Wed, 24 Mar 2010 15:47:18 +0100
-Subject: [PATCH 07/39] spice: simple display
-
-With that patch applied you'll actually see the guests screen in the
-spice client.  This does *not* bring qxl and full spice support though.
-This is basically the qxl vga mode made more generic, so it plays
-together with any qemu-emulated gfx card.  You can display stdvga or
-cirrus via spice client.  You can have both vnc and spice enabled and
-clients connected at the same time.
----
- Makefile.objs   |    2 +-
- qemu-spice.h    |    1 +
- spice-display.c |  394 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
- spice-display.h |   52 ++++++++
- vl.c            |    7 +-
- 5 files changed, 454 insertions(+), 2 deletions(-)
- create mode 100644 spice-display.c
- create mode 100644 spice-display.h
-
-diff --git a/Makefile.objs b/Makefile.objs
-index 023a0dc..d05643f 100644
---- a/Makefile.objs
-+++ b/Makefile.objs
-@@ -89,7 +89,7 @@ common-obj-y += pflib.o
- common-obj-$(CONFIG_BRLAPI) += baum.o
- common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o
-
--common-obj-$(CONFIG_SPICE) += spice.o spice-input.o
-+common-obj-$(CONFIG_SPICE) += spice.o spice-input.o spice-display.o
-
- audio-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
- audio-obj-$(CONFIG_SDL) += sdlaudio.o
-diff --git a/qemu-spice.h b/qemu-spice.h
-index ceb3db2..f061004 100644
---- a/qemu-spice.h
-+++ b/qemu-spice.h
-@@ -13,6 +13,7 @@ extern int using_spice;
-
- void qemu_spice_init(void);
- void qemu_spice_input_init(void);
-+void qemu_spice_display_init(DisplayState *ds);
-
- #else  /* CONFIG_SPICE */
-
-diff --git a/spice-display.c b/spice-display.c
-new file mode 100644
-index 0000000..13a620e
---- /dev/null
-+++ b/spice-display.c
-@@ -0,0 +1,394 @@
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <stdbool.h>
-+#include <stdint.h>
-+#include <string.h>
-+#include <pthread.h>
-+
-+#include "qemu-common.h"
-+#include "qemu-spice.h"
-+#include "qemu-timer.h"
-+#include "qemu-queue.h"
-+#include "monitor.h"
-+#include "console.h"
-+#include "sysemu.h"
-+
-+#include "spice-display.h"
-+
-+static int debug = 1;
-+
-+int qemu_spice_rect_is_empty(const QXLRect* r)
-+{
-+    return r->top == r->bottom || r->left == r->right;
-+}
-+
-+void qemu_spice_rect_union(QXLRect *dest, const QXLRect *r)
-+{
-+    if (qemu_spice_rect_is_empty(r)) {
-+        return;
-+    }
-+
-+    if (qemu_spice_rect_is_empty(dest)) {
-+        *dest = *r;
-+        return;
-+    }
-+
-+    dest->top = MIN(dest->top, r->top);
-+    dest->left = MIN(dest->left, r->left);
-+    dest->bottom = MAX(dest->bottom, r->bottom);
-+    dest->right = MAX(dest->right, r->right);
-+}
-+
-+SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
-+{
-+    SimpleSpiceUpdate *update;
-+    QXLDrawable *drawable;
-+    QXLImage *image;
-+    QXLCommand *cmd;
-+    uint8_t *src, *dst;
-+    int by, bw, bh;
-+
-+    if (qemu_spice_rect_is_empty(&ssd->dirty)) {
-+        return NULL;
-+    };
-+
-+    pthread_mutex_lock(&ssd->lock);
-+    if (debug > 1)
-+        fprintf(stderr, "%s: lr %d -> %d,  tb -> %d -> %d\n", __FUNCTION__,
-+                ssd->dirty.left, ssd->dirty.right,
-+                ssd->dirty.top, ssd->dirty.bottom);
-+
-+    update   = qemu_mallocz(sizeof(*update));
-+    drawable = &update->drawable;
-+    image    = &update->image;
-+    cmd      = &update->ext.cmd;
-+
-+    bw       = ssd->dirty.right - ssd->dirty.left;
-+    bh       = ssd->dirty.bottom - ssd->dirty.top;
-+    update->bitmap = qemu_malloc(bw * bh * 4);
-+
-+    drawable->bbox            = ssd->dirty;
-+    drawable->clip.type       = SPICE_CLIP_TYPE_NONE;
-+    drawable->effect          = QXL_EFFECT_OPAQUE;
-+    drawable->release_info.id = (intptr_t)update;
-+    drawable->type            = QXL_DRAW_COPY;
-+
-+    drawable->u.copy.rop_descriptor  = SPICE_ROPD_OP_PUT;
-+    drawable->u.copy.src_bitmap      = (intptr_t)image;
-+    drawable->u.copy.src_area.right  = bw;
-+    drawable->u.copy.src_area.bottom = bh;
-+
-+    QXL_SET_IMAGE_ID(image, QXL_IMAGE_GROUP_DEVICE, ssd->unique++);
-+    image->descriptor.type   = SPICE_IMAGE_TYPE_BITMAP;
-+    image->bitmap.flags      = QXL_BITMAP_DIRECT | QXL_BITMAP_TOP_DOWN;
-+    image->bitmap.stride     = bw * 4;
-+    image->descriptor.width  = image->bitmap.x = bw;
-+    image->descriptor.height = image->bitmap.y = bh;
-+    image->bitmap.data = (intptr_t)(update->bitmap);
-+    image->bitmap.palette = 0;
-+    image->bitmap.format = SPICE_BITMAP_FMT_32BIT;
-+
-+    if (ssd->conv == NULL) {
-+        PixelFormat dst = qemu_default_pixelformat(32);
-+        ssd->conv = qemu_pf_conv_get(&dst, &ssd->ds->surface->pf);
-+        assert(ssd->conv);
-+    }
-+
-+    src = ds_get_data(ssd->ds) +
-+        ssd->dirty.top * ds_get_linesize(ssd->ds) +
-+        ssd->dirty.left * ds_get_bytes_per_pixel(ssd->ds);
-+    dst = update->bitmap;
-+    for (by = 0; by < bh; by++) {
-+        qemu_pf_conv_run(ssd->conv, dst, src, bw);
-+        src += ds_get_linesize(ssd->ds);
-+        dst += image->bitmap.stride;
-+    }
-+
-+    cmd->type = QXL_CMD_DRAW;
-+    cmd->data = (intptr_t)drawable;
-+
-+    memset(&ssd->dirty, 0, sizeof(ssd->dirty));
-+    pthread_mutex_unlock(&ssd->lock);
-+    return update;
-+}
-+
-+void qemu_spice_destroy_update(SimpleSpiceDisplay *sdpy, SimpleSpiceUpdate *update)
-+{
-+    qemu_free(update->bitmap);
-+    qemu_free(update);
-+}
-+
-+void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd)
-+{
-+    QXLDevMemSlot memslot;
-+
-+    if (debug)
-+        fprintf(stderr, "%s:\n", __FUNCTION__);
-+
-+    memset(&memslot, 0, sizeof(memslot));
-+    memslot.slot_group_id = MEMSLOT_GROUP_HOST;
-+    memslot.virt_end = ~0;
-+    ssd->worker->add_memslot(ssd->worker, &memslot);
-+}
-+
-+void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
-+{
-+    QXLDevSurfaceCreate surface;
-+
-+    if (debug)
-+        fprintf(stderr, "%s: %dx%d\n", __FUNCTION__,
-+                ds_get_width(ssd->ds), ds_get_height(ssd->ds));
-+
-+    surface.format     = SPICE_SURFACE_FMT_32_xRGB;
-+    surface.width      = ds_get_width(ssd->ds);
-+    surface.height     = ds_get_height(ssd->ds);
-+    surface.stride     = -surface.width * 4;
-+    surface.mouse_mode = 0;
-+    surface.flags      = 0;
-+    surface.type       = 0;
-+    surface.mem        = (intptr_t)ssd->buf;
-+    surface.group_id   = MEMSLOT_GROUP_HOST;
-+    ssd->worker->create_primary_surface(ssd->worker, 0, &surface);
-+}
-+
-+void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd)
-+{
-+    if (debug)
-+        fprintf(stderr, "%s:\n", __FUNCTION__);
-+
-+    ssd->worker->destroy_primary_surface(ssd->worker, 0);
-+}
-+
-+void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason)
-+{
-+    SimpleSpiceDisplay *ssd = opaque;
-+
-+    if (running) {
-+        ssd->worker->start(ssd->worker);
-+    } else {
-+        ssd->worker->stop(ssd->worker);
-+    }
-+    ssd->running = running;
-+}
-+
-+/* display listener callbacks */
-+
-+void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
-+                               int x, int y, int w, int h)
-+{
-+    QXLRect update_area;
-+
-+    if (debug > 1)
-+        fprintf(stderr, "%s: x %d y %d w %d h %d\n", __FUNCTION__, x, y, w, h);
-+    update_area.left = x,
-+    update_area.right = x + w;
-+    update_area.top = y;
-+    update_area.bottom = y + h;
-+
-+    pthread_mutex_lock(&ssd->lock);
-+    if (qemu_spice_rect_is_empty(&ssd->dirty)) {
-+        ssd->notify++;
-+    }
-+    qemu_spice_rect_union(&ssd->dirty, &update_area);
-+    pthread_mutex_unlock(&ssd->lock);
-+}
-+
-+void qemu_spice_display_resize(SimpleSpiceDisplay *ssd)
-+{
-+    if (debug)
-+        fprintf(stderr, "%s:\n", __FUNCTION__);
-+
-+    pthread_mutex_lock(&ssd->lock);
-+    memset(&ssd->dirty, 0, sizeof(ssd->dirty));
-+    pthread_mutex_unlock(&ssd->lock);
-+
-+    qemu_spice_destroy_host_primary(ssd);
-+    qemu_spice_create_host_primary(ssd);
-+    qemu_pf_conv_put(ssd->conv);
-+    ssd->conv = NULL;
-+
-+    pthread_mutex_lock(&ssd->lock);
-+    ssd->dirty.left   = 0;
-+    ssd->dirty.right  = ds_get_width(ssd->ds);
-+    ssd->dirty.top    = 0;
-+    ssd->dirty.bottom = ds_get_height(ssd->ds);
-+    ssd->notify++;
-+    pthread_mutex_unlock(&ssd->lock);
-+}
-+
-+void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd)
-+{
-+    if (debug > 2)
-+        fprintf(stderr, "%s:\n", __FUNCTION__);
-+    vga_hw_update();
-+    if (ssd->notify) {
-+        ssd->notify = 0;
-+        ssd->worker->wakeup(ssd->worker);
-+        if (debug > 1)
-+            fprintf(stderr, "%s: notify\n", __FUNCTION__);
-+    }
-+}
-+
-+/* spice display interface callbacks */
-+
-+static void interface_attach_worker(QXLInstance *sin, QXLWorker *qxl_worker)
-+{
-+    SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
-+
-+    if (debug)
-+        fprintf(stderr, "%s:\n", __FUNCTION__);
-+    ssd->worker = qxl_worker;
-+}
-+
-+static void interface_set_compression_level(QXLInstance *sin, int level)
-+{
-+    if (debug)
-+        fprintf(stderr, "%s:\n", __FUNCTION__);
-+    /* nothing to do */
-+}
-+
-+static void interface_set_mm_time(QXLInstance *sin, uint32_t mm_time)
-+{
-+    if (debug > 2)
-+        fprintf(stderr, "%s:\n", __FUNCTION__);
-+    /* nothing to do */
-+}
-+
-+static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info)
-+{
-+    SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
-+
-+    info->memslot_gen_bits = MEMSLOT_GENERATION_BITS;
-+    info->memslot_id_bits  = MEMSLOT_SLOT_BITS;
-+    info->num_memslots = NUM_MEMSLOTS;
-+    info->num_memslots_groups = NUM_MEMSLOTS_GROUPS;
-+    info->internal_groupslot_id = 0;
-+    info->qxl_ram_size = ssd->bufsize;
-+    info->n_surfaces = NUM_SURFACES;
-+}
-+
-+static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
-+{
-+    SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
-+    SimpleSpiceUpdate *update;
-+
-+    if (debug > 2)
-+        fprintf(stderr, "%s:\n", __FUNCTION__);
-+    update = qemu_spice_create_update(ssd);
-+    if (update == NULL) {
-+        return false;
-+    }
-+    *ext = update->ext;
-+    return true;
-+}
-+
-+static int interface_req_cmd_notification(QXLInstance *sin)
-+{
-+    if (debug)
-+        fprintf(stderr, "%s:\n", __FUNCTION__);
-+    return 1;
-+}
-+
-+static void interface_release_resource(QXLInstance *sin,
-+                                       struct QXLReleaseInfoExt ext)
-+{
-+    SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
-+    uintptr_t id;
-+
-+    if (debug > 1)
-+        fprintf(stderr, "%s:\n", __FUNCTION__);
-+    id = ext.info->id;
-+    qemu_spice_destroy_update(ssd, (void*)id);
-+}
-+
-+static int interface_get_cursor_command(QXLInstance *sin, struct QXLCommandExt *ext)
-+{
-+    if (debug > 2)
-+        fprintf(stderr, "%s:\n", __FUNCTION__);
-+    return false;
-+}
-+
-+static int interface_req_cursor_notification(QXLInstance *sin)
-+{
-+    if (debug)
-+        fprintf(stderr, "%s:\n", __FUNCTION__);
-+    return 1;
-+}
-+
-+static void interface_notify_update(QXLInstance *sin, uint32_t update_id)
-+{
-+    fprintf(stderr, "%s: abort()\n", __FUNCTION__);
-+    abort();
-+}
-+
-+static int interface_flush_resources(QXLInstance *sin)
-+{
-+    fprintf(stderr, "%s: abort()\n", __FUNCTION__);
-+    abort();
-+    return 0;
-+}
-+
-+static const QXLInterface dpy_interface = {
-+    .base.type               = SPICE_INTERFACE_QXL,
-+    .base.description        = "qemu simple display",
-+    .base.major_version      = SPICE_INTERFACE_QXL_MAJOR,
-+    .base.minor_version      = SPICE_INTERFACE_QXL_MINOR,
-+
-+    .pci_vendor              = REDHAT_PCI_VENDOR_ID,
-+    .pci_id                  = QXL_DEVICE_ID,
-+    .pci_revision            = QXL_REVISION,
-+
-+    .attache_worker          = interface_attach_worker,
-+    .set_compression_level   = interface_set_compression_level,
-+    .set_mm_time             = interface_set_mm_time,
-+
-+    .get_init_info           = interface_get_init_info,
-+    .get_command             = interface_get_command,
-+    .req_cmd_notification    = interface_req_cmd_notification,
-+    .release_resource        = interface_release_resource,
-+    .get_cursor_command      = interface_get_cursor_command,
-+    .req_cursor_notification = interface_req_cursor_notification,
-+    .notify_update           = interface_notify_update,
-+    .flush_resources         = interface_flush_resources,
-+};
-+
-+static SimpleSpiceDisplay sdpy;
-+
-+static void display_update(struct DisplayState *ds, int x, int y, int w, int h)
-+{
-+    qemu_spice_display_update(&sdpy, x, y, w, h);
-+}
-+
-+static void display_resize(struct DisplayState *ds)
-+{
-+    qemu_spice_display_resize(&sdpy);
-+}
-+
-+static void display_refresh(struct DisplayState *ds)
-+{
-+    qemu_spice_display_refresh(&sdpy);
-+}
-+
-+static DisplayChangeListener display_listener = {
-+    .dpy_update  = display_update,
-+    .dpy_resize  = display_resize,
-+    .dpy_refresh = display_refresh,
-+};
-+
-+void qemu_spice_display_init(DisplayState *ds)
-+{
-+    assert(sdpy.ds == NULL);
-+    sdpy.ds = ds;
-+    sdpy.bufsize = (16 * 1024 * 1024);
-+    sdpy.buf = qemu_malloc(sdpy.bufsize);
-+    pthread_mutex_init(&sdpy.lock, NULL);
-+    register_displaychangelistener(ds, &display_listener);
-+
-+    sdpy.qxl.base.sif = &dpy_interface.base;
-+    spice_server_add_interface(spice_server, &sdpy.qxl.base);
-+    assert(sdpy.worker);
-+
-+    qemu_add_vm_change_state_handler(qemu_spice_vm_change_state_handler, &sdpy);
-+    qemu_spice_create_host_memslot(&sdpy);
-+    qemu_spice_create_host_primary(&sdpy);
-+}
-diff --git a/spice-display.h b/spice-display.h
-new file mode 100644
-index 0000000..70a7be4
---- /dev/null
-+++ b/spice-display.h
-@@ -0,0 +1,52 @@
-+#include <spice/ipc_ring.h>
-+#include <spice/draw.h>
-+#include <spice/qxl_dev.h>
-+
-+#include "pflib.h"
-+
-+#define NUM_MEMSLOTS 8
-+#define MEMSLOT_GENERATION_BITS 8
-+#define MEMSLOT_SLOT_BITS 8
-+
-+#define MEMSLOT_GROUP_HOST  0
-+#define MEMSLOT_GROUP_GUEST 1
-+#define NUM_MEMSLOTS_GROUPS 2
-+
-+#define NUM_SURFACES 1024
-+
-+typedef struct SimpleSpiceDisplay {
-+    DisplayState *ds;
-+    void *buf;
-+    int bufsize;
-+    QXLWorker *worker;
-+    QXLInstance qxl;
-+    uint32_t unique;
-+    QemuPfConv *conv;
-+
-+    pthread_mutex_t lock;
-+    QXLRect dirty;
-+    int notify;
-+    int running;
-+} SimpleSpiceDisplay;
-+
-+typedef struct SimpleSpiceUpdate {
-+    QXLDrawable drawable;
-+    QXLImage image;
-+    QXLCommandExt ext;
-+    uint8_t *bitmap;
-+} SimpleSpiceUpdate;
-+
-+int qemu_spice_rect_is_empty(const QXLRect* r);
-+void qemu_spice_rect_union(QXLRect *dest, const QXLRect *r);
-+
-+SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *sdpy);
-+void qemu_spice_destroy_update(SimpleSpiceDisplay *sdpy, SimpleSpiceUpdate *update);
-+void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd);
-+void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd);
-+void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd);
-+void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason);
-+
-+void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
-+                               int x, int y, int w, int h);
-+void qemu_spice_display_resize(SimpleSpiceDisplay *ssd);
-+void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd);
-diff --git a/vl.c b/vl.c
-index 97897e0..2ccebc8 100644
---- a/vl.c
-+++ b/vl.c
-@@ -2993,7 +2993,7 @@ int main(int argc, char **argv, char **envp)
-     /* just use the first displaystate for the moment */
-     ds = get_displaystate();
-
--    if (display_type == DT_DEFAULT) {
-+    if (display_type == DT_DEFAULT && !using_spice) {
- #if defined(CONFIG_SDL) || defined(CONFIG_COCOA)
-         display_type = DT_SDL;
- #else
-@@ -3033,6 +3033,11 @@ int main(int argc, char **argv, char **envp)
-     default:
-         break;
-     }
-+#ifdef CONFIG_SPICE
-+    if (using_spice) {
-+        qemu_spice_display_init(ds);
-+    }
-+#endif
-     dpy_resize(ds);
-
-     dcl = ds->listeners;
--- 
-1.7.2.3
-
diff --git a/0008-spice-add-tablet-support.patch b/0008-spice-add-tablet-support.patch
deleted file mode 100644
index 6f37c81..0000000
--- a/0008-spice-add-tablet-support.patch
+++ /dev/null
@@ -1,160 +0,0 @@
-From e3c6e18e27f0d598b37e9be1795dbcb42f740071 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Tue, 13 Apr 2010 09:05:03 +0200
-Subject: [PATCH 08/39] spice: add tablet support
-
-Add support for the spice tablet interface.  The tablet interface will
-be registered (and then used by the spice client) as soon as a absolute
-pointing device is available and used by the guest, i.e. you'll have to
-configure your guest with '-usbdevice tablet'.
----
- spice-display.c |    2 +-
- spice-input.c   |   99 +++++++++++++++++++++++++++++++++++++++++++++++++++----
- 2 files changed, 93 insertions(+), 8 deletions(-)
-
-diff --git a/spice-display.c b/spice-display.c
-index 13a620e..a749e64 100644
---- a/spice-display.c
-+++ b/spice-display.c
-@@ -143,7 +143,7 @@ void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
-     surface.width      = ds_get_width(ssd->ds);
-     surface.height     = ds_get_height(ssd->ds);
-     surface.stride     = -surface.width * 4;
--    surface.mouse_mode = 0;
-+    surface.mouse_mode = true;
-     surface.flags      = 0;
-     surface.type       = 0;
-     surface.mem        = (intptr_t)ssd->buf;
-diff --git a/spice-input.c b/spice-input.c
-index 8f3deb4..5646ff9 100644
---- a/spice-input.c
-+++ b/spice-input.c
-@@ -1,5 +1,6 @@
- #include <stdlib.h>
- #include <stdio.h>
-+#include <stdbool.h>
- #include <string.h>
-
- #include <spice.h>
-@@ -48,9 +49,13 @@ static void kbd_leds(void *opaque, int ledstate)
-
- /* mouse bits */
-
--typedef struct QemuSpiceMouse {
--    SpiceMouseInstance sin;
--} QemuSpiceMouse;
-+typedef struct QemuSpicePointer {
-+    SpiceMouseInstance  mouse;
-+    SpiceTabletInstance tablet;
-+    int width, height, x, y;
-+    Notifier mouse_mode;
-+    bool absolute;
-+} QemuSpicePointer;
-
- static void mouse_motion(SpiceMouseInstance *sin, int dx, int dy, int dz,
-                          uint32_t buttons_state)
-@@ -72,17 +77,97 @@ static const SpiceMouseInterface mouse_interface = {
-     .buttons            = mouse_buttons,
- };
-
-+static void tablet_set_logical_size(SpiceTabletInstance* sin, int width, int height)
-+{
-+    QemuSpicePointer *pointer = container_of(sin, QemuSpicePointer, tablet);
-+
-+    fprintf(stderr, "%s: %dx%d\n", __FUNCTION__, width, height);
-+    if (height < 16)
-+        height = 16;
-+    if (width < 16)
-+        width = 16;
-+    pointer->width  = width;
-+    pointer->height = height;
-+}
-+
-+static void tablet_position(SpiceTabletInstance* sin, int x, int y,
-+                            uint32_t buttons_state)
-+{
-+    QemuSpicePointer *pointer = container_of(sin, QemuSpicePointer, tablet);
-+
-+    pointer->x = x * 0x7FFF / (pointer->width - 1);
-+    pointer->y = y * 0x7FFF / (pointer->height - 1);
-+    kbd_mouse_event(pointer->x, pointer->y, 0, buttons_state);
-+}
-+
-+
-+static void tablet_wheel(SpiceTabletInstance* sin, int wheel,
-+                         uint32_t buttons_state)
-+{
-+    QemuSpicePointer *pointer = container_of(sin, QemuSpicePointer, tablet);
-+
-+    kbd_mouse_event(pointer->x, pointer->y, wheel, buttons_state);
-+}
-+
-+static void tablet_buttons(SpiceTabletInstance *sin,
-+                           uint32_t buttons_state)
-+{
-+    QemuSpicePointer *pointer = container_of(sin, QemuSpicePointer, tablet);
-+
-+    kbd_mouse_event(pointer->x, pointer->y, 0, buttons_state);
-+}
-+
-+static const SpiceTabletInterface tablet_interface = {
-+    .base.type          = SPICE_INTERFACE_TABLET,
-+    .base.description   = "tablet",
-+    .base.major_version = SPICE_INTERFACE_TABLET_MAJOR,
-+    .base.minor_version = SPICE_INTERFACE_TABLET_MINOR,
-+    .set_logical_size   = tablet_set_logical_size,
-+    .position           = tablet_position,
-+    .wheel              = tablet_wheel,
-+    .buttons            = tablet_buttons,
-+};
-+
-+static void mouse_mode_notifier(Notifier *notifier)
-+{
-+    QemuSpicePointer *pointer = container_of(notifier, QemuSpicePointer, mouse_mode);
-+    bool is_absolute  = kbd_mouse_is_absolute();
-+    bool has_absolute = kbd_mouse_has_absolute();
-+
-+    fprintf(stderr, "%s: absolute pointer: %s%s\n", __FUNCTION__,
-+            has_absolute ? "present" : "not available",
-+            is_absolute  ? "+active" : "");
-+
-+    if (pointer->absolute == is_absolute)
-+        return;
-+
-+    if (is_absolute) {
-+        fprintf(stderr, "%s: using absolute pointer (client mode)\n", __FUNCTION__);
-+        spice_server_add_interface(spice_server, &pointer->tablet.base);
-+    } else {
-+        fprintf(stderr, "%s: using relative pointer (server mode)\n", __FUNCTION__);
-+        spice_server_remove_interface(&pointer->tablet.base);
-+    }
-+    pointer->absolute = is_absolute;
-+}
-+
- void qemu_spice_input_init(void)
- {
-     QemuSpiceKbd *kbd;
--    QemuSpiceMouse *mouse;
-+    QemuSpicePointer *pointer;
-
-     kbd = qemu_mallocz(sizeof(*kbd));
-     kbd->sin.base.sif = &kbd_interface.base;
-     spice_server_add_interface(spice_server, &kbd->sin.base);
-     qemu_add_led_event_handler(kbd_leds, kbd);
-
--    mouse = qemu_mallocz(sizeof(*mouse));
--    mouse->sin.base.sif = &mouse_interface.base;
--    spice_server_add_interface(spice_server, &mouse->sin.base);
-+    pointer = qemu_mallocz(sizeof(*pointer));
-+    pointer->mouse.base.sif  = &mouse_interface.base;
-+    pointer->tablet.base.sif = &tablet_interface.base;
-+    spice_server_add_interface(spice_server, &pointer->mouse.base);
-+
-+    pointer->absolute = false;
-+    pointer->mouse_mode.notify = mouse_mode_notifier;
-+    qemu_add_mouse_mode_change_notifier(&pointer->mouse_mode);
-+    mouse_mode_notifier(&pointer->mouse_mode);
- }
--- 
-1.7.2.3
-
diff --git a/0009-vgabios-update-to-0.6c-pcibios-patches.patch b/0009-vgabios-update-to-0.6c-pcibios-patches.patch
deleted file mode 100644
index 29ff6f4..0000000
--- a/0009-vgabios-update-to-0.6c-pcibios-patches.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 0920337756cdf82dcd585efb23ae18f8086696c8 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Wed, 24 Mar 2010 11:16:54 +0100
-Subject: [PATCH 09/39] vgabios update to 0.6c + pcibios patches.
-
----
- Makefile |    5 +++--
- 1 files changed, 3 insertions(+), 2 deletions(-)
-
-diff --git a/Makefile b/Makefile
-index 3cd07e0..e40c9a2 100644
---- a/Makefile
-+++ b/Makefile
-@@ -154,8 +154,9 @@ ar      de     en-us  fi  fr-be  hr     it  lv  nl         pl  ru     th \
- common  de-ch  es     fo  fr-ca  hu     ja  mk  nl-be      pt  sl     tr
-
- ifdef INSTALL_BLOBS
--BLOBS=bios.bin vgabios.bin vgabios-cirrus.bin ppc_rom.bin \
--video.x openbios-sparc32 openbios-sparc64 openbios-ppc \
-+BLOBS=bios.bin vgabios.bin vgabios-cirrus.bin \
-+vgabios-stdvga.bin vgabios-vmware.bin vgabios-qxl.bin vgabios-qxldev.bin \
-+ppc_rom.bin video.x openbios-sparc32 openbios-sparc64 openbios-ppc \
- gpxe-eepro100-80861209.rom \
- gpxe-eepro100-80861229.rom \
- pxe-e1000.bin \
--- 
-1.7.2.3
-
diff --git a/0010-switch-stdvga-to-pci-vgabios.patch b/0010-switch-stdvga-to-pci-vgabios.patch
deleted file mode 100644
index ccb71ac..0000000
--- a/0010-switch-stdvga-to-pci-vgabios.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 6ac04dff1ee3932d2ef94c1e42f4e8208fbf92bf Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Thu, 6 May 2010 11:13:11 +0200
-Subject: [PATCH 10/39] switch stdvga to pci vgabios
-
----
- hw/vga-pci.c |    7 +++----
- 1 files changed, 3 insertions(+), 4 deletions(-)
-
-diff --git a/hw/vga-pci.c b/hw/vga-pci.c
-index 3907871..8e1ed35 100644
---- a/hw/vga-pci.c
-+++ b/hw/vga-pci.c
-@@ -105,11 +105,10 @@ static int pci_vga_initfn(PCIDevice *dev)
-             bios_total_size <<= 1;
-         pci_register_bar(&d->dev, PCI_ROM_SLOT, bios_total_size,
-                          PCI_BASE_ADDRESS_MEM_PREFETCH, vga_map);
-+     } else {
-+         if (dev->romfile == NULL)
-+             dev->romfile = qemu_strdup("vgabios-stdvga.bin");
-      }
--
--    vga_init_vbe(s);
--     /* ROM BIOS */
--     rom_add_vga(VGABIOS_FILENAME);
-      return 0;
- }
-
--- 
-1.7.2.3
-
diff --git a/0011-switch-vmware_vga-to-pci-vgabios.patch b/0011-switch-vmware_vga-to-pci-vgabios.patch
deleted file mode 100644
index 30bfa9c..0000000
--- a/0011-switch-vmware_vga-to-pci-vgabios.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From 07cdc867f1e12a4e8b4096e7f1f3ffda2f4e7d02 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Thu, 6 May 2010 11:14:11 +0200
-Subject: [PATCH 11/39] switch vmware_vga to pci vgabios
-
----
- hw/vmware_vga.c |    7 +------
- 1 files changed, 1 insertions(+), 6 deletions(-)
-
-diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
-index 12bff48..682f287 100644
---- a/hw/vmware_vga.c
-+++ b/hw/vmware_vga.c
-@@ -114,14 +114,12 @@ struct pci_vmsvga_state_s {
- # define SVGA_IO_BASE		SVGA_LEGACY_BASE_PORT
- # define SVGA_IO_MUL		1
- # define SVGA_FIFO_SIZE		0x10000
--# define SVGA_MEM_BASE		0xe0000000
- # define SVGA_PCI_DEVICE_ID	PCI_DEVICE_ID_VMWARE_SVGA2
- #else
- # define SVGA_ID		SVGA_ID_1
- # define SVGA_IO_BASE		SVGA_LEGACY_BASE_PORT
- # define SVGA_IO_MUL		4
- # define SVGA_FIFO_SIZE		0x10000
--# define SVGA_MEM_BASE		0xe0000000
- # define SVGA_PCI_DEVICE_ID	PCI_DEVICE_ID_VMWARE_SVGA
- #endif
-
-@@ -1171,10 +1169,6 @@ static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size)
-     vga_init(&s->vga);
-     vmstate_register(NULL, 0, &vmstate_vga_common, &s->vga);
-
--    vga_init_vbe(&s->vga);
--
--    rom_add_vga(VGABIOS_FILENAME);
--
-     vmsvga_reset(s);
- }
-
-@@ -1272,6 +1266,7 @@ static PCIDeviceInfo vmsvga_info = {
-     .qdev.size    = sizeof(struct pci_vmsvga_state_s),
-     .qdev.vmsd    = &vmstate_vmware_vga,
-     .init         = pci_vmsvga_initfn,
-+    .romfile      = "vgabios-vmware.bin",
- };
-
- static void vmsvga_register(void)
--- 
-1.7.2.3
-
diff --git a/0012-all-vga-refuse-hotplugging.patch b/0012-all-vga-refuse-hotplugging.patch
deleted file mode 100644
index 393b1b2..0000000
--- a/0012-all-vga-refuse-hotplugging.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From a659f6b472d95503657ac68a52242ce769006f17 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Tue, 11 May 2010 22:28:44 +0200
-Subject: [PATCH 12/39] all vga: refuse hotplugging.
-
-Try to pci hotplug a vga card, watch qemu die with hw_error().
-This patch fixes it.
----
- hw/cirrus_vga.c |    4 ++++
- hw/vga-pci.c    |    4 ++++
- hw/vmware_vga.c |    4 ++++
- 3 files changed, 12 insertions(+), 0 deletions(-)
-
-diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
-index efa7a42..dadaa80 100644
---- a/hw/cirrus_vga.c
-+++ b/hw/cirrus_vga.c
-@@ -3206,6 +3206,10 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev)
-      uint8_t *pci_conf = d->dev.config;
-      int device_id = CIRRUS_ID_CLGD5446;
-
-+     if (dev->qdev.hotplugged) {
-+         return -1;
-+     }
-+
-      /* setup VGA */
-      vga_common_init(&s->vga, VGA_RAM_SIZE);
-      cirrus_init_common(s, device_id, 1);
-diff --git a/hw/vga-pci.c b/hw/vga-pci.c
-index 8e1ed35..4e673a5 100644
---- a/hw/vga-pci.c
-+++ b/hw/vga-pci.c
-@@ -81,6 +81,10 @@ static int pci_vga_initfn(PCIDevice *dev)
-      VGACommonState *s = &d->vga;
-      uint8_t *pci_conf = d->dev.config;
-
-+     if (dev->qdev.hotplugged) {
-+         return -1;
-+     }
-+
-      // vga + console init
-      vga_common_init(s, VGA_RAM_SIZE);
-      vga_init(s);
-diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
-index 682f287..7ff89aa 100644
---- a/hw/vmware_vga.c
-+++ b/hw/vmware_vga.c
-@@ -1232,6 +1232,10 @@ static int pci_vmsvga_initfn(PCIDevice *dev)
-     struct pci_vmsvga_state_s *s =
-         DO_UPCAST(struct pci_vmsvga_state_s, card, dev);
-
-+    if (dev->qdev.hotplugged) {
-+        return -1;
-+    }
-+
-     pci_config_set_vendor_id(s->card.config, PCI_VENDOR_ID_VMWARE);
-     pci_config_set_device_id(s->card.config, SVGA_PCI_DEVICE_ID);
-     pci_config_set_class(s->card.config, PCI_CLASS_DISPLAY_VGA);
--- 
-1.7.2.3
-
diff --git a/0013-spice-tls-support.patch b/0013-spice-tls-support.patch
deleted file mode 100644
index da247af..0000000
--- a/0013-spice-tls-support.patch
+++ /dev/null
@@ -1,168 +0,0 @@
-From e0d06d42a83e7796b2c39ad6cab3630c0a8c2845 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Thu, 11 Mar 2010 11:13:32 -0300
-Subject: [PATCH 13/39] spice: tls support
-
-Add options to the -spice command line switch to setup tls:
-
-tls-port
-	listening port
-
-x509-dir
-	x509 file directory.  Expects same filenames as
-	-vnc $display,x509=$dir
-
-x509-key-file
-x509-key-password
-x509-cert-file
-x509-cacert-file
-x509-dh-key-file
-	x509 files can also be set individually.
-
-tls-ciphers
-	which ciphers to use.
----
- qemu-config.c |   24 ++++++++++++++++++++
- spice.c       |   66 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
- 2 files changed, 86 insertions(+), 4 deletions(-)
-
-diff --git a/qemu-config.c b/qemu-config.c
-index 8a894cf..74bfc62 100644
---- a/qemu-config.c
-+++ b/qemu-config.c
-@@ -355,11 +355,35 @@ QemuOptsList qemu_spice_opts = {
-             .name = "port",
-             .type = QEMU_OPT_NUMBER,
-         },{
-+            .name = "tls-port",
-+            .type = QEMU_OPT_NUMBER,
-+        },{
-             .name = "password",
-             .type = QEMU_OPT_STRING,
-         },{
-             .name = "disable-ticketing",
-             .type = QEMU_OPT_BOOL,
-+        },{
-+            .name = "x509-dir",
-+            .type = QEMU_OPT_STRING,
-+        },{
-+            .name = "x509-key-file",
-+            .type = QEMU_OPT_STRING,
-+        },{
-+            .name = "x509-key-password",
-+            .type = QEMU_OPT_STRING,
-+        },{
-+            .name = "x509-cert-file",
-+            .type = QEMU_OPT_STRING,
-+        },{
-+            .name = "x509-cacert-file",
-+            .type = QEMU_OPT_STRING,
-+        },{
-+            .name = "x509-dh-key-file",
-+            .type = QEMU_OPT_STRING,
-+        },{
-+            .name = "tls-ciphers",
-+            .type = QEMU_OPT_STRING,
-         },
-         { /* end if list */ }
-     },
-diff --git a/spice.c b/spice.c
-index c763d52..3fe76cd 100644
---- a/spice.c
-+++ b/spice.c
-@@ -9,6 +9,7 @@
- #include "qemu-spice.h"
- #include "qemu-timer.h"
- #include "qemu-queue.h"
-+#include "qemu-x509.h"
- #include "monitor.h"
-
- /* core bits */
-@@ -126,18 +127,71 @@ static SpiceCoreInterface core_interface = {
- void qemu_spice_init(void)
- {
-     QemuOpts *opts = QTAILQ_FIRST(&qemu_spice_opts.head);
--    const char *password;
--    int port;
-+    const char *password, *str, *x509_dir,
-+        *x509_key_password = NULL,
-+        *x509_dh_file = NULL,
-+        *tls_ciphers = NULL;
-+    char *x509_key_file = NULL,
-+        *x509_cert_file = NULL,
-+        *x509_cacert_file = NULL;
-+    int port, tls_port, len;
-
-     if (!opts)
-         return;
-     port = qemu_opt_get_number(opts, "port", 0);
--    if (!port)
-+    tls_port = qemu_opt_get_number(opts, "tls-port", 0);
-+    if (!port && !tls_port)
-         return;
-     password = qemu_opt_get(opts, "password");
-
-+    if (tls_port) {
-+        x509_dir = qemu_opt_get(opts, "x509-dir");
-+        if (NULL == x509_dir)
-+            x509_dir = ".";
-+        len = strlen(x509_dir) + 32;
-+
-+        str = qemu_opt_get(opts, "x509-key-file");
-+        if (str) {
-+            x509_key_file = qemu_strdup(str);
-+        } else {
-+            x509_key_file = qemu_malloc(len);
-+            snprintf(x509_key_file, len, "%s/%s", x509_dir, X509_SERVER_KEY_FILE);
-+        }
-+
-+        str = qemu_opt_get(opts, "x509-cert-file");
-+        if (str) {
-+            x509_cert_file = qemu_strdup(str);
-+        } else {
-+            x509_cert_file = qemu_malloc(len);
-+            snprintf(x509_cert_file, len, "%s/%s", x509_dir, X509_SERVER_CERT_FILE);
-+        }
-+
-+        str = qemu_opt_get(opts, "x509-cacert-file");
-+        if (str) {
-+            x509_cacert_file = qemu_strdup(str);
-+        } else {
-+            x509_cacert_file = qemu_malloc(len);
-+            snprintf(x509_cacert_file, len, "%s/%s", x509_dir, X509_CA_CERT_FILE);
-+        }
-+
-+        x509_key_password = qemu_opt_get(opts, "x509-key-password");
-+        x509_dh_file = qemu_opt_get(opts, "x509-dh-file");
-+        tls_ciphers = qemu_opt_get(opts, "tls-ciphers");
-+    }
-+
-     spice_server = spice_server_new();
--    spice_server_set_port(spice_server, port);
-+    if (port) {
-+        spice_server_set_port(spice_server, port);
-+    }
-+    if (tls_port) {
-+        spice_server_set_tls(spice_server, tls_port,
-+                             x509_cacert_file,
-+                             x509_cert_file,
-+                             x509_key_file,
-+                             x509_key_password,
-+                             x509_dh_file,
-+                             tls_ciphers);
-+    }
-     if (password)
-         spice_server_set_ticket(spice_server, password, 0, 0, 0);
-     if (qemu_opt_get_bool(opts, "disable-ticketing", 0))
-@@ -150,4 +204,8 @@ void qemu_spice_init(void)
-     using_spice = 1;
-
-     qemu_spice_input_init();
-+
-+    qemu_free(x509_key_file);
-+    qemu_free(x509_cert_file);
-+    qemu_free(x509_cacert_file);
- }
--- 
-1.7.2.3
-
diff --git a/0014-spice-add-qxl-device.patch b/0014-spice-add-qxl-device.patch
deleted file mode 100644
index 4ea90ba..0000000
--- a/0014-spice-add-qxl-device.patch
+++ /dev/null
@@ -1,2085 +0,0 @@
-From 4cd79eae3a476fda86b67a8075735a03c1254a08 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Tue, 27 Apr 2010 11:50:11 +0200
-Subject: [PATCH 14/39] spice: add qxl device
-
-qxl is a paravirtual graphics card.  The qxl device is the bridge
-between the guest and the spice server (aka libspice-server).  The
-spice server will send the rendering commands to the spice client, which
-will actually render them.
-
-The spice server is also able to render locally, which is done in case
-the guest wants read something from video memory.  Local rendering is
-also used to support display over vnc and sdl.
-
-qxl is activated using "-vga qxl".  qxl supports multihead, additional
-cards can be added via '-device qxl".
----
- Makefile.target |    1 +
- hw/hw.h         |   14 +
- hw/pc.c         |    8 +
- hw/qxl-logger.c |  179 +++++++
- hw/qxl-render.c |  207 ++++++++
- hw/qxl.c        | 1411 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
- hw/qxl.h        |  102 ++++
- hw/vga_int.h    |    2 +-
- sysemu.h        |    3 +-
- vl.c            |    4 +-
- 10 files changed, 1928 insertions(+), 3 deletions(-)
- create mode 100644 hw/qxl-logger.c
- create mode 100644 hw/qxl-render.c
- create mode 100644 hw/qxl.c
- create mode 100644 hw/qxl.h
-
-diff --git a/Makefile.target b/Makefile.target
-index 9e13d99..4da33b5 100644
---- a/Makefile.target
-+++ b/Makefile.target
-@@ -216,6 +216,7 @@ obj-i386-y += debugcon.o multiboot.o
- obj-i386-y += pc_piix.o
- obj-i386-y += testdev.o
- obj-i386-y += acpi.o acpi_piix4.o
-+obj-i386-$(CONFIG_SPICE) += qxl.o qxl-logger.o qxl-render.o
-
- obj-i386-y += pcspk.o i8254.o
- obj-i386-$(CONFIG_KVM_PIT) += i8254-kvm.o
-diff --git a/hw/hw.h b/hw/hw.h
-index ec6985d..044ebfb 100644
---- a/hw/hw.h
-+++ b/hw/hw.h
-@@ -528,6 +528,17 @@ extern const VMStateInfo vmstate_info_unused_buffer;
-     .start        = (_start),                                        \
- }
-
-+#define VMSTATE_VBUFFER_UINT32(_field, _state, _version, _test, _start, _field_size) { \
-+    .name         = (stringify(_field)),                             \
-+    .version_id   = (_version),                                      \
-+    .field_exists = (_test),                                         \
-+    .size_offset  = vmstate_offset_value(_state, _field_size, uint32_t),\
-+    .info         = &vmstate_info_buffer,                            \
-+    .flags        = VMS_VBUFFER|VMS_POINTER,                         \
-+    .offset       = offsetof(_state, _field),                        \
-+    .start        = (_start),                                        \
-+}
-+
- #define VMSTATE_BUFFER_UNSAFE_INFO(_field, _state, _version, _info, _size) { \
-     .name       = (stringify(_field)),                               \
-     .version_id = (_version),                                        \
-@@ -742,6 +753,9 @@ extern const VMStateDescription vmstate_i2c_slave;
- #define VMSTATE_PARTIAL_VBUFFER(_f, _s, _size)                        \
-     VMSTATE_VBUFFER(_f, _s, 0, NULL, 0, _size)
-
-+#define VMSTATE_PARTIAL_VBUFFER_UINT32(_f, _s, _size)                        \
-+    VMSTATE_VBUFFER_UINT32(_f, _s, 0, NULL, 0, _size)
-+
- #define VMSTATE_SUB_VBUFFER(_f, _s, _start, _size)                    \
-     VMSTATE_VBUFFER(_f, _s, 0, NULL, _start, _size)
-
-diff --git a/hw/pc.c b/hw/pc.c
-index 77b1592..1f2df2f 100644
---- a/hw/pc.c
-+++ b/hw/pc.c
-@@ -41,6 +41,7 @@
- #include "sysemu.h"
- #include "device-assignment.h"
- #include "kvm.h"
-+#include "qemu-spice.h"
-
- /* output Bochs bios info messages */
- //#define DEBUG_BIOS
-@@ -1002,6 +1003,13 @@ void pc_vga_init(PCIBus *pci_bus)
-             pci_vmsvga_init(pci_bus);
-         else
-             fprintf(stderr, "%s: vmware_vga: no PCI bus\n", __FUNCTION__);
-+#ifdef CONFIG_SPICE
-+    } else if (qxl_enabled) {
-+        if (pci_bus)
-+            pci_create_simple(pci_bus, -1, "qxl");
-+        else
-+            fprintf(stderr, "%s: qxl: no PCI bus\n", __FUNCTION__);
-+#endif
-     } else if (std_vga_enabled) {
-         if (pci_bus) {
-             pci_vga_init(pci_bus, 0, 0);
-diff --git a/hw/qxl-logger.c b/hw/qxl-logger.c
-new file mode 100644
-index 0000000..d4a935a
---- /dev/null
-+++ b/hw/qxl-logger.c
-@@ -0,0 +1,179 @@
-+/*
-+ * qxl command logging -- for debug purposes
-+ */
-+
-+#include <stdio.h>
-+#include <stdbool.h>
-+#include <stdint.h>
-+#include <string.h>
-+
-+#include "qxl.h"
-+
-+static const char *qxl_type[] = {
-+    [ QXL_CMD_NOP ]     = "nop",
-+    [ QXL_CMD_DRAW ]    = "draw",
-+    [ QXL_CMD_UPDATE ]  = "update",
-+    [ QXL_CMD_CURSOR ]  = "cursor",
-+    [ QXL_CMD_MESSAGE ] = "message",
-+    [ QXL_CMD_SURFACE ] = "surface",
-+};
-+
-+static const char *qxl_draw_type[] = {
-+    [ QXL_DRAW_NOP         ] = "nop",
-+    [ QXL_DRAW_FILL        ] = "fill",
-+    [ QXL_DRAW_OPAQUE      ] = "opaque",
-+    [ QXL_DRAW_COPY        ] = "copy",
-+    [ QXL_COPY_BITS        ] = "copy-bits",
-+    [ QXL_DRAW_BLEND       ] = "blend",
-+    [ QXL_DRAW_BLACKNESS   ] = "blackness",
-+    [ QXL_DRAW_WHITENESS   ] = "whitemess",
-+    [ QXL_DRAW_INVERS      ] = "invers",
-+    [ QXL_DRAW_ROP3        ] = "rop3",
-+    [ QXL_DRAW_STROKE      ] = "stroke",
-+    [ QXL_DRAW_TEXT        ] = "text",
-+    [ QXL_DRAW_TRANSPARENT ] = "transparent",
-+    [ QXL_DRAW_ALPHA_BLEND ] = "alpha-blend",
-+};
-+
-+static const char *qxl_draw_effect[] = {
-+    [ QXL_EFFECT_BLEND            ] = "blend",
-+    [ QXL_EFFECT_OPAQUE           ] = "opaque",
-+    [ QXL_EFFECT_REVERT_ON_DUP    ] = "revert-on-dup",
-+    [ QXL_EFFECT_BLACKNESS_ON_DUP ] = "blackness-on-dup",
-+    [ QXL_EFFECT_WHITENESS_ON_DUP ] = "whiteness-on-dup",
-+    [ QXL_EFFECT_NOP_ON_DUP       ] = "nop-on-dup",
-+    [ QXL_EFFECT_NOP              ] = "nop",
-+    [ QXL_EFFECT_OPAQUE_BRUSH     ] = "opaque-brush",
-+};
-+
-+static const char *qxl_surface_cmd[] = {
-+   [ QXL_SURFACE_CMD_CREATE  ] = "create",
-+   [ QXL_SURFACE_CMD_DESTROY ] = "destroy",
-+};
-+
-+static const char *spice_surface_fmt[] = {
-+   [ SPICE_SURFACE_FMT_INVALID  ] = "invalid",
-+   [ SPICE_SURFACE_FMT_1_A      ] = "alpha/1",
-+   [ SPICE_SURFACE_FMT_8_A      ] = "alpha/8",
-+   [ SPICE_SURFACE_FMT_16_555   ] = "555/16",
-+   [ SPICE_SURFACE_FMT_16_565   ] = "565/16",
-+   [ SPICE_SURFACE_FMT_32_xRGB  ] = "xRGB/32",
-+   [ SPICE_SURFACE_FMT_32_ARGB  ] = "ARGB/32",
-+};
-+
-+static const char *qxl_cursor_cmd[] = {
-+   [ QXL_CURSOR_SET   ] = "set",
-+   [ QXL_CURSOR_MOVE  ] = "move",
-+   [ QXL_CURSOR_HIDE  ] = "hide",
-+   [ QXL_CURSOR_TRAIL ] = "trail",
-+};
-+
-+static const char *spice_cursor_type[] = {
-+   [ SPICE_CURSOR_TYPE_ALPHA   ] = "alpha",
-+   [ SPICE_CURSOR_TYPE_MONO    ] = "mono",
-+   [ SPICE_CURSOR_TYPE_COLOR4  ] = "color4",
-+   [ SPICE_CURSOR_TYPE_COLOR8  ] = "color8",
-+   [ SPICE_CURSOR_TYPE_COLOR16 ] = "color16",
-+   [ SPICE_CURSOR_TYPE_COLOR24 ] = "color24",
-+   [ SPICE_CURSOR_TYPE_COLOR32 ] = "color32",
-+};
-+
-+static const char *qxl_v2n(const char *n[], size_t l, int v)
-+{
-+    if (v >= l || !n[v])
-+        return "???";
-+    return n[v];
-+}
-+#define qxl_name(_list, _value) qxl_v2n(_list, ARRAY_SIZE(_list), _value)
-+
-+static void qxl_log_cmd_draw(PCIQXLDevice *qxl, QXLDrawable *draw)
-+{
-+    fprintf(stderr, ": surface_id %d type %s effect %s",
-+            draw->surface_id,
-+            qxl_name(qxl_draw_type, draw->type),
-+            qxl_name(qxl_draw_effect, draw->effect));
-+}
-+
-+static void qxl_log_cmd_draw_compat(PCIQXLDevice *qxl, QXLCompatDrawable *draw)
-+{
-+    fprintf(stderr, ": type %s effect %s",
-+            qxl_name(qxl_draw_type, draw->type),
-+            qxl_name(qxl_draw_effect, draw->effect));
-+}
-+
-+static void qxl_log_cmd_surface(PCIQXLDevice *qxl, QXLSurfaceCmd *cmd)
-+{
-+    fprintf(stderr, ": %s id %d",
-+            qxl_name(qxl_surface_cmd, cmd->type),
-+            cmd->surface_id);
-+    if (cmd->type == QXL_SURFACE_CMD_CREATE) {
-+        fprintf(stderr, " size %dx%d stride %d format %s (count %d, max %d)",
-+                cmd->u.surface_create.width,
-+                cmd->u.surface_create.height,
-+                cmd->u.surface_create.stride,
-+                qxl_name(spice_surface_fmt, cmd->u.surface_create.format),
-+                qxl->guest_surfaces.count, qxl->guest_surfaces.max);
-+    }
-+    if (cmd->type == QXL_SURFACE_CMD_DESTROY) {
-+        fprintf(stderr, " (count %d)", qxl->guest_surfaces.count);
-+    }
-+}
-+
-+void qxl_log_cmd_cursor(PCIQXLDevice *qxl, QXLCursorCmd *cmd, int group_id)
-+{
-+    QXLCursor *cursor;
-+
-+    fprintf(stderr, ": %s",
-+            qxl_name(qxl_cursor_cmd, cmd->type));
-+    switch (cmd->type) {
-+    case QXL_CURSOR_SET:
-+        fprintf(stderr, " +%d+%d visible %s, shape @ 0x%" PRIx64,
-+                cmd->u.set.position.x,
-+                cmd->u.set.position.y,
-+                cmd->u.set.visible ? "yes" : "no",
-+                cmd->u.set.shape);
-+        cursor = qxl_phys2virt(qxl, cmd->u.set.shape, group_id);
-+        fprintf(stderr, " type %s size %dx%d hot-spot +%d+%d"
-+                " unique 0x%" PRIx64 " data-size %d",
-+                qxl_name(spice_cursor_type, cursor->header.type),
-+                cursor->header.width, cursor->header.height,
-+                cursor->header.hot_spot_x, cursor->header.hot_spot_y,
-+                cursor->header.unique, cursor->data_size);
-+        break;
-+    case QXL_CURSOR_MOVE:
-+        fprintf(stderr, " +%d+%d", cmd->u.position.x, cmd->u.position.y);
-+        break;
-+    }
-+}
-+
-+void qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext)
-+{
-+    bool compat = ext->flags & QXL_COMMAND_FLAG_COMPAT;
-+    void *data;
-+
-+    if (!qxl->cmdlog) {
-+        return;
-+    }
-+    fprintf(stderr, "qxl-%d/%s:", qxl->id, ring);
-+    fprintf(stderr, " cmd @ 0x%" PRIx64 " %s%s", ext->cmd.data,
-+            qxl_name(qxl_type, ext->cmd.type),
-+            compat ? "(compat)" : "");
-+
-+    data = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
-+    switch (ext->cmd.type) {
-+    case QXL_CMD_DRAW:
-+        if (!compat) {
-+            qxl_log_cmd_draw(qxl, data);
-+        } else {
-+            qxl_log_cmd_draw_compat(qxl, data);
-+        }
-+        break;
-+    case QXL_CMD_SURFACE:
-+        qxl_log_cmd_surface(qxl, data);
-+        break;
-+    case QXL_CMD_CURSOR:
-+        qxl_log_cmd_cursor(qxl, data, ext->group_id);
-+        break;
-+    }
-+    fprintf(stderr, "\n");
-+}
-diff --git a/hw/qxl-render.c b/hw/qxl-render.c
-new file mode 100644
-index 0000000..d9ebca4
---- /dev/null
-+++ b/hw/qxl-render.c
-@@ -0,0 +1,207 @@
-+/*
-+ * qxl local rendering (aka display on sdl/vnc)
-+ */
-+#include <stdio.h>
-+#include <stdbool.h>
-+#include <stdint.h>
-+#include <string.h>
-+
-+#include "qxl.h"
-+
-+static void qxl_flip(PCIQXLDevice *qxl, QXLRect *rect)
-+{
-+    uint8_t *src = qxl->guest_primary.data;
-+    uint8_t *dst = qxl->guest_primary.flipped;
-+    int len, i;
-+
-+    src += (qxl->guest_primary.surface.height - rect->top - 1) *
-+        qxl->guest_primary.stride;
-+    dst += rect->top  * qxl->guest_primary.stride;
-+    src += rect->left * qxl->guest_primary.bytes_pp;
-+    dst += rect->left * qxl->guest_primary.bytes_pp;
-+    len  = (rect->right - rect->left) * qxl->guest_primary.bytes_pp;
-+
-+    for (i = rect->top; i < rect->bottom; i++) {
-+        memcpy(dst, src, len);
-+        dst += qxl->guest_primary.stride;
-+        src -= qxl->guest_primary.stride;
-+    }
-+}
-+
-+void qxl_render_resize(PCIQXLDevice *qxl)
-+{
-+    QXLSurfaceCreate *sc = &qxl->guest_primary.surface;
-+
-+    qxl->guest_primary.stride = sc->stride;
-+    qxl->guest_primary.resized++;
-+    switch (sc->format) {
-+    case SPICE_SURFACE_FMT_16_555:
-+        qxl->guest_primary.bytes_pp = 2;
-+        qxl->guest_primary.bits_pp = 15;
-+        break;
-+    case SPICE_SURFACE_FMT_16_565:
-+        qxl->guest_primary.bytes_pp = 2;
-+        qxl->guest_primary.bits_pp = 16;
-+        break;
-+    case SPICE_SURFACE_FMT_32_xRGB:
-+    case SPICE_SURFACE_FMT_32_ARGB:
-+        qxl->guest_primary.bytes_pp = 4;
-+        qxl->guest_primary.bits_pp = 32;
-+        break;
-+    default:
-+        fprintf(stderr, "%s: unhandled format: %x\n", __FUNCTION__,
-+                qxl->guest_primary.surface.format);
-+        qxl->guest_primary.bytes_pp = 4;
-+        qxl->guest_primary.bits_pp = 32;
-+        break;
-+    }
-+}
-+
-+void qxl_render_update(PCIQXLDevice *qxl)
-+{
-+    VGACommonState *vga = &qxl->vga;
-+    QXLRect dirty[32], update;
-+    void *ptr;
-+    int i;
-+
-+    if (qxl->guest_primary.resized) {
-+        qxl->guest_primary.resized = 0;
-+
-+        if (qxl->guest_primary.flipped) {
-+            qemu_free(qxl->guest_primary.flipped);
-+            qxl->guest_primary.flipped = NULL;
-+        }
-+        qemu_free_displaysurface(vga->ds);
-+
-+        qxl->guest_primary.data = qemu_get_ram_ptr(qxl->vga.vram_offset);
-+        if (qxl->guest_primary.stride < 0) {
-+            /* spice surface is upside down -> need extra buffer to flip */
-+            qxl->guest_primary.stride = -qxl->guest_primary.stride;
-+            qxl->guest_primary.flipped = qemu_malloc(qxl->guest_primary.surface.width *
-+                                                     qxl->guest_primary.stride);
-+            ptr = qxl->guest_primary.flipped;
-+        } else {
-+            ptr = qxl->guest_primary.data;
-+        }
-+        fprintf(stderr, "%s: %dx%d, stride %d, bpp %d, depth %d, flip %s\n",
-+                __FUNCTION__,
-+                qxl->guest_primary.surface.width,
-+                qxl->guest_primary.surface.height,
-+                qxl->guest_primary.stride,
-+                qxl->guest_primary.bytes_pp,
-+                qxl->guest_primary.bits_pp,
-+                qxl->guest_primary.flipped ? "yes" : "no");
-+        vga->ds->surface =
-+            qemu_create_displaysurface_from(qxl->guest_primary.surface.width,
-+                                            qxl->guest_primary.surface.height,
-+                                            qxl->guest_primary.bits_pp,
-+                                            qxl->guest_primary.stride,
-+                                            ptr);
-+        dpy_resize(vga->ds);
-+    }
-+
-+    if (!qxl->guest_primary.commands)
-+        return;
-+    qxl->guest_primary.commands = 0;
-+
-+    update.left   = 0;
-+    update.right  = qxl->guest_primary.surface.width;
-+    update.top    = 0;
-+    update.bottom = qxl->guest_primary.surface.height;
-+
-+    memset(dirty, 0, sizeof(dirty));
-+    qxl->ssd.worker->update_area(qxl->ssd.worker, 0, &update,
-+                                 dirty, ARRAY_SIZE(dirty), 1);
-+
-+    for (i = 0; i < ARRAY_SIZE(dirty); i++) {
-+        if (qemu_spice_rect_is_empty(dirty+i))
-+            break;
-+        if (qxl->guest_primary.flipped) {
-+            qxl_flip(qxl, dirty+i);
-+        }
-+        dpy_update(vga->ds,
-+                   dirty[i].left, dirty[i].top,
-+                   dirty[i].right - dirty[i].left,
-+                   dirty[i].bottom - dirty[i].top);
-+    }
-+}
-+
-+static QEMUCursor *qxl_cursor(PCIQXLDevice *qxl, QXLCursor *cursor)
-+{
-+    QEMUCursor *c;
-+    uint8_t *image, *mask;
-+    int size;
-+
-+    c = cursor_alloc(cursor->header.width, cursor->header.height);
-+    c->hot_x = cursor->header.hot_spot_x;
-+    c->hot_y = cursor->header.hot_spot_y;
-+    switch (cursor->header.type) {
-+    case SPICE_CURSOR_TYPE_ALPHA:
-+        size = cursor->header.width * cursor->header.height * sizeof(uint32_t);
-+        memcpy(c->data, cursor->chunk.data, size);
-+        if (qxl->debug > 1)
-+            cursor_print_ascii_art(c, "qxl/alpha");
-+        break;
-+    case SPICE_CURSOR_TYPE_MONO:
-+        mask  = cursor->chunk.data;
-+        image = mask + cursor_get_mono_bpl(c) * c->width;
-+        cursor_set_mono(c, 0xffffff, 0x000000, image, 1, mask);
-+        if (qxl->debug > 1)
-+            cursor_print_ascii_art(c, "qxl/mono");
-+        break;
-+    default:
-+        fprintf(stderr, "%s: not implemented: type %d\n",
-+                __FUNCTION__, cursor->header.type);
-+        goto fail;
-+    }
-+    return c;
-+
-+fail:
-+    cursor_put(c);
-+    return NULL;
-+}
-+
-+
-+void qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext)
-+{
-+    QXLCursorCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
-+    QXLCursor *cursor;
-+    QEMUCursor *c;
-+    int x = -1, y = -1;
-+
-+    if (!qxl->ssd.ds->mouse_set ||
-+        !qxl->ssd.ds->cursor_define)
-+        return;
-+
-+#if 1
-+    if (cmd->type != QXL_CURSOR_MOVE) {
-+        fprintf(stderr, "%s", __FUNCTION__);
-+        qxl_log_cmd_cursor(qxl, cmd, ext->group_id);
-+        fprintf(stderr, "\n");
-+    }
-+#endif
-+    switch (cmd->type) {
-+    case QXL_CURSOR_SET:
-+        x = cmd->u.set.position.x;
-+        y = cmd->u.set.position.y;
-+        cursor = qxl_phys2virt(qxl, cmd->u.set.shape, ext->group_id);
-+        if (cursor->chunk.data_size != cursor->data_size) {
-+            fprintf(stderr, "%s: multiple chunks\n", __FUNCTION__);
-+            return;
-+        }
-+        c = qxl_cursor(qxl, cursor);
-+        if (c == NULL) {
-+            c = cursor_builtin_left_ptr();
-+        }
-+        qxl->ssd.ds->cursor_define(c);
-+        cursor_put(c);
-+        break;
-+    case QXL_CURSOR_MOVE:
-+        x = cmd->u.position.x;
-+        y = cmd->u.position.y;
-+        break;
-+    }
-+    if (x != -1 && y != -1) {
-+        qxl->ssd.ds->mouse_set(x, y, 1);
-+    }
-+}
-diff --git a/hw/qxl.c b/hw/qxl.c
-new file mode 100644
-index 0000000..475360c
---- /dev/null
-+++ b/hw/qxl.c
-@@ -0,0 +1,1411 @@
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <stdbool.h>
-+#include <stdint.h>
-+#include <string.h>
-+#include <pthread.h>
-+
-+#include "qemu-common.h"
-+#include "qemu-timer.h"
-+#include "qemu-queue.h"
-+#include "monitor.h"
-+#include "sysemu.h"
-+
-+#include "qxl.h"
-+
-+#undef SPICE_RING_PROD_ITEM
-+#define SPICE_RING_PROD_ITEM(r, ret) {                                  \
-+        typeof(r) start = r;                                            \
-+        typeof(r) end = r + 1;                                          \
-+        uint32_t prod = (r)->prod & SPICE_RING_INDEX_MASK(r);           \
-+        typeof(&(r)->items[prod]) m_item = &(r)->items[prod];           \
-+        if (!((uint8_t*)m_item >= (uint8_t*)(start) && (uint8_t*)(m_item + 1) <= (uint8_t*)(end))) { \
-+            abort();                                                    \
-+        }                                                               \
-+        ret = &m_item->el;                                              \
-+    }
-+
-+#undef SPICE_RING_CONS_ITEM
-+#define SPICE_RING_CONS_ITEM(r, ret) {                                  \
-+        typeof(r) start = r;                                            \
-+        typeof(r) end = r + 1;                                          \
-+        uint32_t cons = (r)->cons & SPICE_RING_INDEX_MASK(r);           \
-+        typeof(&(r)->items[cons]) m_item = &(r)->items[cons];           \
-+        if (!((uint8_t*)m_item >= (uint8_t*)(start) && (uint8_t*)(m_item + 1) <= (uint8_t*)(end))) { \
-+            abort();                                                    \
-+        }                                                               \
-+        ret = &m_item->el;                                              \
-+    }
-+
-+#undef ALIGN
-+#define ALIGN(a, b) (((a) + ((b) - 1)) & ~((b) - 1))
-+
-+#define PIXEL_SIZE 0.2936875 //1280x1024 is 14.8" x 11.9" 
-+
-+#define QXL_MODE(_x, _y, _b, _o)                  \
-+    {   .x_res = _x,                              \
-+        .y_res = _y,                              \
-+        .bits  = _b,                              \
-+        .stride = (_x) * (_b) / 8,                \
-+        .x_mili = PIXEL_SIZE * (_x),              \
-+        .y_mili = PIXEL_SIZE * (_y),              \
-+        .orientation = _o,                        \
-+    }
-+
-+#define QXL_MODE_16_32(x_res, y_res, orientation) \
-+    QXL_MODE(x_res, y_res, 16, orientation),      \
-+    QXL_MODE(x_res, y_res, 32, orientation)
-+
-+#define QXL_MODE_EX(x_res, y_res)                 \
-+    QXL_MODE_16_32(x_res, y_res, 0),              \
-+    QXL_MODE_16_32(y_res, x_res, 1),              \
-+    QXL_MODE_16_32(x_res, y_res, 2),              \
-+    QXL_MODE_16_32(y_res, x_res, 3)
-+
-+static QXLMode qxl_modes[] = {
-+    QXL_MODE_EX(640, 480),
-+    QXL_MODE_EX(800, 600),
-+    QXL_MODE_EX(832, 624),
-+    QXL_MODE_EX(1024, 768),
-+    QXL_MODE_EX(1152, 864),
-+    QXL_MODE_EX(1152, 870),
-+    QXL_MODE_EX(1280, 720),
-+    QXL_MODE_EX(1280, 768),
-+    QXL_MODE_EX(1280, 800),
-+    QXL_MODE_EX(1280, 960),
-+    QXL_MODE_EX(1280, 1024),
-+    QXL_MODE_EX(1360, 768),
-+    QXL_MODE_EX(1366, 768),
-+    QXL_MODE_EX(1400, 1050),
-+    QXL_MODE_EX(1440, 900),
-+    QXL_MODE_EX(1600, 900),
-+    QXL_MODE_EX(1600, 1200),
-+    QXL_MODE_EX(1680, 1050),
-+    QXL_MODE_EX(1920, 1080),
-+#ifdef QXL_HIRES_MODES
-+    QXL_MODE_EX(1920, 1200),
-+    QXL_MODE_EX(1920, 1440),
-+    QXL_MODE_EX(2048, 1536),
-+    QXL_MODE_EX(2560, 1600),
-+    QXL_MODE_EX(2560, 2048),
-+    QXL_MODE_EX(2800, 2100),
-+    QXL_MODE_EX(3200, 2400),
-+#endif
-+};
-+
-+static int device_id = 0;
-+static PCIQXLDevice *qxl0;
-+
-+static void qxl_send_events(PCIQXLDevice *d, uint32_t events);
-+static void qxl_destroy_primary(PCIQXLDevice *d);
-+static void qxl_reset_memslots(PCIQXLDevice *d);
-+static void qxl_reset_surfaces(PCIQXLDevice *d);
-+static void qxl_ring_set_dirty(PCIQXLDevice *qxl);
-+
-+static inline uint32_t msb_mask(uint32_t val)
-+{
-+    uint32_t mask;
-+
-+    do {
-+        mask = ~(val - 1) & val;
-+        val &= ~mask;
-+    } while (mask < val);
-+
-+    return mask;
-+}
-+
-+static ram_addr_t qxl_rom_size(void)
-+{
-+    uint32_t rom_size = sizeof(QXLRom) + sizeof(QXLModes) + sizeof(qxl_modes);
-+    rom_size = MAX(rom_size, TARGET_PAGE_SIZE);
-+    rom_size = msb_mask(rom_size * 2 - 1);
-+    return rom_size;
-+}
-+
-+static void init_qxl_rom(PCIQXLDevice *d)
-+{
-+    QXLRom *rom = qemu_get_ram_ptr(d->rom_offset);
-+    QXLModes *modes = (QXLModes *)(rom + 1);
-+    uint32_t ram_header_size;
-+    uint32_t surface0_area_size;
-+    uint32_t num_pages;
-+    uint32_t fb, maxfb = 0;
-+    int i;
-+
-+    memset(rom, 0, d->rom_size);
-+
-+    rom->magic         = cpu_to_le32(QXL_ROM_MAGIC);
-+    rom->id            = cpu_to_le32(d->id);
-+    rom->modes_offset  = cpu_to_le32(sizeof(QXLRom));
-+
-+    rom->slot_gen_bits = MEMSLOT_GENERATION_BITS;
-+    rom->slot_id_bits  = MEMSLOT_SLOT_BITS;
-+    rom->slots_start   = 1;
-+    rom->slots_end     = NUM_MEMSLOTS - 1;
-+    rom->n_surfaces    = cpu_to_le32(NUM_SURFACES);
-+
-+    modes->n_modes     = cpu_to_le32(ARRAY_SIZE(qxl_modes));
-+    for (i = 0; i < modes->n_modes; i++) {
-+        fb = qxl_modes[i].y_res * qxl_modes[i].stride;
-+        if (maxfb < fb)
-+            maxfb = fb;
-+        modes->modes[i].id          = cpu_to_le32(i);
-+        modes->modes[i].x_res       = cpu_to_le32(qxl_modes[i].x_res);
-+        modes->modes[i].y_res       = cpu_to_le32(qxl_modes[i].y_res);
-+        modes->modes[i].bits        = cpu_to_le32(qxl_modes[i].bits);
-+        modes->modes[i].stride      = cpu_to_le32(qxl_modes[i].stride);
-+        modes->modes[i].x_mili      = cpu_to_le32(qxl_modes[i].x_mili);
-+        modes->modes[i].y_mili      = cpu_to_le32(qxl_modes[i].y_mili);
-+        modes->modes[i].orientation = cpu_to_le32(qxl_modes[i].orientation);
-+    }
-+    if (maxfb < VGA_RAM_SIZE && d->id == 0)
-+        maxfb = VGA_RAM_SIZE;
-+
-+    ram_header_size    = ALIGN(sizeof(QXLRam), 4096);
-+    surface0_area_size = ALIGN(maxfb, 4096);
-+    num_pages          = d->vga.vram_size;
-+    num_pages         -= ram_header_size;
-+    num_pages         -= surface0_area_size;
-+    num_pages          = num_pages / TARGET_PAGE_SIZE;
-+
-+    rom->draw_area_offset   = cpu_to_le32(0);
-+    rom->surface0_area_size = cpu_to_le32(surface0_area_size);
-+    rom->pages_offset       = cpu_to_le32(surface0_area_size);
-+    rom->num_pages          = cpu_to_le32(num_pages);
-+    rom->ram_header_offset  = cpu_to_le32(d->vga.vram_size - ram_header_size);
-+
-+    d->shadow_rom = *rom;
-+    d->rom        = rom;
-+    d->modes      = modes;
-+}
-+
-+static void init_qxl_ram(PCIQXLDevice *d)
-+{
-+    uint8_t *buf;
-+    uint64_t *item;
-+
-+    buf = d->vga.vram_ptr;
-+    d->ram = (QXLRam *)(buf + le32_to_cpu(d->shadow_rom.ram_header_offset));
-+    d->ram->magic       = cpu_to_le32(QXL_RAM_MAGIC);
-+    d->ram->int_pending = cpu_to_le32(0);
-+    d->ram->int_mask    = cpu_to_le32(0);
-+    SPICE_RING_INIT(&d->ram->cmd_ring);
-+    SPICE_RING_INIT(&d->ram->cursor_ring);
-+    SPICE_RING_INIT(&d->ram->release_ring);
-+    SPICE_RING_PROD_ITEM(&d->ram->release_ring, item);
-+    *item = 0;
-+    qxl_ring_set_dirty(d);
-+}
-+
-+static void qxl_set_dirty(ram_addr_t addr, ram_addr_t end)
-+{
-+    while (addr < end) {
-+        cpu_physical_memory_set_dirty(addr);
-+        addr += TARGET_PAGE_SIZE;
-+    }
-+}
-+
-+static void qxl_rom_set_dirty(PCIQXLDevice *qxl)
-+{
-+    ram_addr_t addr = qxl->rom_offset;
-+    qxl_set_dirty(addr, addr + qxl->rom_size);
-+}
-+
-+static void qxl_ram_set_dirty(PCIQXLDevice *qxl, void *ptr)
-+{
-+    ram_addr_t addr = qxl->vga.vram_offset;
-+    void *base = qxl->vga.vram_ptr;
-+    intptr_t offset;
-+
-+    offset = ptr - base;
-+    offset &= ~(TARGET_PAGE_SIZE-1);
-+    assert(offset < qxl->vga.vram_size);
-+    qxl_set_dirty(addr + offset, addr + offset + TARGET_PAGE_SIZE);
-+}
-+
-+static void qxl_ring_set_dirty(PCIQXLDevice *qxl)
-+{
-+    ram_addr_t addr = qxl->vga.vram_offset + qxl->shadow_rom.ram_header_offset;
-+    ram_addr_t end  = qxl->vga.vram_offset + qxl->vga.vram_size;
-+    qxl_set_dirty(addr, end);
-+}
-+
-+/*
-+ * keep track of some command state, for savevm/loadvm.
-+ */
-+static void qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext)
-+{
-+    switch (le32_to_cpu(ext->cmd.type)) {
-+    case QXL_CMD_SURFACE:
-+    {
-+        QXLSurfaceCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
-+        uint32_t id = le32_to_cpu(cmd->surface_id);
-+        PANIC_ON(id >= NUM_SURFACES);
-+        if (cmd->type == QXL_SURFACE_CMD_CREATE) {
-+            qxl->guest_surfaces.cmds[id] = ext->cmd.data;
-+            qxl->guest_surfaces.count++;
-+            if (qxl->guest_surfaces.max < qxl->guest_surfaces.count)
-+                qxl->guest_surfaces.max = qxl->guest_surfaces.count;
-+        }
-+        if (cmd->type == QXL_SURFACE_CMD_DESTROY) {
-+            qxl->guest_surfaces.cmds[id] = 0;
-+            qxl->guest_surfaces.count--;
-+        }
-+        break;
-+    }
-+    case QXL_CMD_CURSOR:
-+    {
-+        QXLCursorCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
-+        if (cmd->type == QXL_CURSOR_SET) {
-+            qxl->guest_cursor = ext->cmd.data;
-+        }
-+        break;
-+    }
-+    }
-+}
-+
-+/* spice display interface callbacks */
-+
-+static void interface_attach_worker(QXLInstance *sin, QXLWorker *qxl_worker)
-+{
-+    PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
-+
-+    dprintf(qxl, 1, "%s:\n", __FUNCTION__);
-+    qxl->ssd.worker = qxl_worker;
-+}
-+
-+static void interface_set_compression_level(QXLInstance *sin, int level)
-+{
-+    PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
-+
-+    dprintf(qxl, 1, "%s: %d\n", __FUNCTION__, level);
-+    qxl->shadow_rom.compression_level = cpu_to_le32(level);
-+    qxl->rom->compression_level = cpu_to_le32(level);
-+    qxl_rom_set_dirty(qxl);
-+}
-+
-+static void interface_set_mm_time(QXLInstance *sin, uint32_t mm_time)
-+{
-+    PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
-+
-+    qxl->shadow_rom.mm_clock = cpu_to_le32(mm_time);
-+    qxl->rom->mm_clock = cpu_to_le32(mm_time);
-+    qxl_rom_set_dirty(qxl);
-+}
-+
-+static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info)
-+{
-+    PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
-+
-+    dprintf(qxl, 1, "%s:\n", __FUNCTION__);
-+    info->memslot_gen_bits = MEMSLOT_GENERATION_BITS;
-+    info->memslot_id_bits = MEMSLOT_SLOT_BITS;
-+    info->num_memslots = NUM_MEMSLOTS;
-+    info->num_memslots_groups = NUM_MEMSLOTS_GROUPS;
-+    info->internal_groupslot_id = 0;
-+    info->qxl_ram_size = le32_to_cpu(qxl->shadow_rom.num_pages) << TARGET_PAGE_BITS;
-+    info->n_surfaces = NUM_SURFACES;
-+}
-+
-+static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
-+{
-+    PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
-+    SimpleSpiceUpdate *update;
-+    QXLCommandRing *ring;
-+    QXLCommand *cmd;
-+    int notify;
-+
-+    switch (qxl->mode) {
-+    case QXL_MODE_VGA:
-+        dprintf(qxl, 2, "%s: vga\n", __FUNCTION__);
-+        update = qemu_spice_create_update(&qxl->ssd);
-+        if (update == NULL) {
-+            return false;
-+        }
-+        *ext = update->ext;
-+        qxl_log_command(qxl, "vga", ext);
-+        return true;
-+    case QXL_MODE_COMPAT:
-+    case QXL_MODE_NATIVE:
-+    case QXL_MODE_UNDEFINED:
-+        dprintf(qxl, 2, "%s: %s\n", __FUNCTION__,
-+                qxl->cmdflags ? "compat" : "native");
-+        ring = &qxl->ram->cmd_ring;
-+        if (SPICE_RING_IS_EMPTY(ring)) {
-+            return false;
-+        }
-+        SPICE_RING_CONS_ITEM(ring, cmd);
-+        ext->cmd      = *cmd;
-+        ext->group_id = MEMSLOT_GROUP_GUEST;
-+        ext->flags    = qxl->cmdflags;
-+        SPICE_RING_POP(ring, notify);
-+        qxl_ring_set_dirty(qxl);
-+        if (notify) {
-+            qxl_send_events(qxl, QXL_INTERRUPT_DISPLAY);
-+        }
-+        qxl->guest_primary.commands++;
-+        qxl_track_command(qxl, ext);
-+        qxl_log_command(qxl, "cmd", ext);
-+        return true;
-+    default:
-+        return false;
-+    }
-+}
-+
-+static int interface_req_cmd_notification(QXLInstance *sin)
-+{
-+    PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
-+    int wait = 1;
-+
-+    switch (qxl->mode) {
-+    case QXL_MODE_COMPAT:
-+    case QXL_MODE_NATIVE:
-+    case QXL_MODE_UNDEFINED:
-+        SPICE_RING_CONS_WAIT(&qxl->ram->cmd_ring, wait);
-+        qxl_ring_set_dirty(qxl);
-+        break;
-+    default:
-+        /* nothing */
-+        break;
-+    }
-+    return wait;
-+}
-+
-+static inline void qxl_push_free_res(PCIQXLDevice *d)
-+{
-+    QXLReleaseRing *ring = &d->ram->release_ring;
-+    uint64_t *item;
-+
-+#define QXL_FREE_BUNCH_SIZE 10
-+
-+    if (SPICE_RING_IS_EMPTY(ring) || (d->num_free_res == QXL_FREE_BUNCH_SIZE &&
-+                                      ring->prod - ring->cons + 1 != ring->num_items)) {
-+        int notify;
-+
-+        SPICE_RING_PUSH(ring, notify);
-+        if (notify) {
-+            qxl_send_events(d, QXL_INTERRUPT_DISPLAY);
-+        }
-+        SPICE_RING_PROD_ITEM(ring, item);
-+        *item = 0;
-+        d->num_free_res = 0;
-+        d->last_release = NULL;
-+        qxl_ring_set_dirty(d);
-+    }
-+}
-+
-+static void interface_release_resource(QXLInstance *sin,
-+                                       struct QXLReleaseInfoExt ext)
-+{
-+    PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
-+    QXLReleaseRing *ring;
-+    uint64_t *item, id;
-+
-+    if (ext.group_id == MEMSLOT_GROUP_HOST) {
-+        /* host group -> vga mode update request */
-+        qemu_spice_destroy_update(&qxl->ssd, (void*)ext.info->id);
-+        return;
-+    }
-+
-+    /*
-+     * ext->info points into guest-visible memory
-+     * pci bar 0, $command.release_info
-+     */
-+    ring = &qxl->ram->release_ring;
-+    SPICE_RING_PROD_ITEM(ring, item);
-+    if (*item == 0) {
-+        /* stick head into the ring */
-+        id = ext.info->id;
-+        ext.info->next = 0;
-+        qxl_ram_set_dirty(qxl, &ext.info->next);
-+        *item = id;
-+        qxl_ring_set_dirty(qxl);
-+    } else {
-+        /* append item to the list */
-+        qxl->last_release->next = ext.info->id;
-+        qxl_ram_set_dirty(qxl, &qxl->last_release->next);
-+        ext.info->next = 0;
-+        qxl_ram_set_dirty(qxl, &ext.info->next);
-+    }
-+    qxl->last_release = ext.info;
-+    qxl->num_free_res++;
-+    qxl_push_free_res(qxl);
-+}
-+
-+static int interface_get_cursor_command(QXLInstance *sin, struct QXLCommandExt *ext)
-+{
-+    PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
-+    QXLCursorRing *ring;
-+    QXLCommand *cmd;
-+    int notify;
-+
-+    switch (qxl->mode) {
-+    case QXL_MODE_COMPAT:
-+    case QXL_MODE_NATIVE:
-+    case QXL_MODE_UNDEFINED:
-+        ring = &qxl->ram->cursor_ring;
-+        if (SPICE_RING_IS_EMPTY(ring)) {
-+            return false;
-+        }
-+        SPICE_RING_CONS_ITEM(ring, cmd);
-+        ext->cmd      = *cmd;
-+        ext->group_id = MEMSLOT_GROUP_GUEST;
-+        ext->flags    = qxl->cmdflags;
-+        SPICE_RING_POP(ring, notify);
-+        qxl_ring_set_dirty(qxl);
-+        if (notify) {
-+            qxl_send_events(qxl, QXL_INTERRUPT_CURSOR);
-+        }
-+        qxl->guest_primary.commands++;
-+        qxl_track_command(qxl, ext);
-+        qxl_log_command(qxl, "csr", ext);
-+        if (qxl->id == 0) {
-+            qxl_render_cursor(qxl, ext);
-+        }
-+        return true;
-+    default:
-+        return false;
-+    }
-+}
-+
-+static int interface_req_cursor_notification(QXLInstance *sin)
-+{
-+    PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
-+    int wait = 1;
-+
-+    switch (qxl->mode) {
-+    case QXL_MODE_COMPAT:
-+    case QXL_MODE_NATIVE:
-+    case QXL_MODE_UNDEFINED:
-+        SPICE_RING_CONS_WAIT(&qxl->ram->cursor_ring, wait);
-+        qxl_ring_set_dirty(qxl);
-+        break;
-+    default:
-+        /* nothing */
-+        break;
-+    }
-+    return wait;
-+}
-+
-+static void interface_notify_update(QXLInstance *sin, uint32_t update_id)
-+{
-+    fprintf(stderr, "%s: abort()\n", __FUNCTION__);
-+    abort();
-+}
-+
-+static int interface_flush_resources(QXLInstance *sin)
-+{
-+    PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
-+    int ret;
-+
-+    ret = qxl->num_free_res;
-+    if (ret) {
-+        qxl_push_free_res(qxl);
-+    }
-+    return ret;
-+}
-+
-+static const QXLInterface qxl_interface = {
-+    .base.type               = SPICE_INTERFACE_QXL,
-+    .base.description        = "qxl gpu",
-+    .base.major_version      = SPICE_INTERFACE_QXL_MAJOR,
-+    .base.minor_version      = SPICE_INTERFACE_QXL_MINOR,
-+
-+    .pci_vendor              = REDHAT_PCI_VENDOR_ID,
-+    .pci_id                  = QXL_DEVICE_ID,
-+    .pci_revision            = QXL_REVISION,
-+
-+    .attache_worker          = interface_attach_worker,
-+    .set_compression_level   = interface_set_compression_level,
-+    .set_mm_time             = interface_set_mm_time,
-+
-+    .get_init_info           = interface_get_init_info,
-+    .get_command             = interface_get_command,
-+    .req_cmd_notification    = interface_req_cmd_notification,
-+    .release_resource        = interface_release_resource,
-+    .get_cursor_command      = interface_get_cursor_command,
-+    .req_cursor_notification = interface_req_cursor_notification,
-+    .notify_update           = interface_notify_update,
-+    .flush_resources         = interface_flush_resources,
-+};
-+
-+static void qxl_enter_vga_mode(PCIQXLDevice *d)
-+{
-+    if (d->mode == QXL_MODE_VGA) {
-+        return;
-+    }
-+    dprintf(d, 1, "%s\n", __FUNCTION__);
-+    qemu_spice_create_host_primary(&d->ssd);
-+    d->mode = QXL_MODE_VGA;
-+    memset(&d->ssd.dirty, 0, sizeof(d->ssd.dirty));
-+}
-+
-+static void qxl_exit_vga_mode(PCIQXLDevice *d)
-+{
-+    if (d->mode != QXL_MODE_VGA) {
-+        return;
-+    }
-+    dprintf(d, 1, "%s\n", __FUNCTION__);
-+    qxl_destroy_primary(d);
-+}
-+
-+static void qxl_set_irq(PCIQXLDevice *d)
-+{
-+    uint32_t pending = le32_to_cpu(d->ram->int_pending);
-+    uint32_t mask    = le32_to_cpu(d->ram->int_mask);
-+    int level = !!(pending & mask);
-+    qemu_set_irq(d->pci.irq[0], level);
-+    qxl_ring_set_dirty(d);
-+}
-+
-+static void qxl_write_config(PCIDevice *d, uint32_t address,
-+                             uint32_t val, int len)
-+{
-+    PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, d);
-+    VGACommonState *vga = &qxl->vga;
-+
-+    if (qxl->id == 0) {
-+        vga_dirty_log_stop(vga);
-+    }
-+    pci_default_write_config(d, address, val, len);
-+    if (qxl->id == 0) {
-+        if (vga->map_addr && qxl->pci.io_regions[0].addr == -1)
-+            vga->map_addr = 0;
-+        vga_dirty_log_start(vga);
-+    }
-+}
-+
-+static void qxl_check_state(PCIQXLDevice *d)
-+{
-+    QXLRam *ram = d->ram;
-+
-+    assert(SPICE_RING_IS_EMPTY(&ram->cmd_ring));
-+    assert(SPICE_RING_IS_EMPTY(&ram->cursor_ring));
-+}
-+
-+static void qxl_reset_state(PCIQXLDevice *d)
-+{
-+    QXLRam *ram = d->ram;
-+    QXLRom *rom = d->rom;
-+
-+    assert(SPICE_RING_IS_EMPTY(&ram->cmd_ring));
-+    assert(SPICE_RING_IS_EMPTY(&ram->cursor_ring));
-+    d->shadow_rom.update_id = cpu_to_le32(0);
-+    *rom = d->shadow_rom;
-+    qxl_rom_set_dirty(d);
-+    init_qxl_ram(d);
-+    d->num_free_res = 0;
-+    d->last_release = NULL;
-+    memset(&d->ssd.dirty, 0, sizeof(d->ssd.dirty));
-+}
-+
-+static void qxl_soft_reset(PCIQXLDevice *d)
-+{
-+    dprintf(d, 1, "%s:\n", __FUNCTION__);
-+    qxl_check_state(d);
-+
-+    if (d->id == 0) {
-+        qxl_enter_vga_mode(d);
-+    } else {
-+        d->mode = QXL_MODE_UNDEFINED;
-+    }
-+}
-+
-+static void qxl_hard_reset(PCIQXLDevice *d, int loadvm)
-+{
-+    dprintf(d, 1, "%s: start%s\n", __FUNCTION__,
-+            loadvm ? " (loadvm)" : "");
-+
-+    d->ssd.worker->reset_cursor(d->ssd.worker);
-+    d->ssd.worker->reset_image_cache(d->ssd.worker);
-+    qxl_reset_surfaces(d);
-+    qxl_reset_memslots(d);
-+
-+    /* pre loadvm reset must not touch QXLRam.  This lives in
-+     * device memory, is migrated together with RAM and thus
-+     * already loaded at this point */
-+    if (!loadvm) {
-+        qxl_reset_state(d);
-+    }
-+    qemu_spice_create_host_memslot(&d->ssd);
-+    qxl_soft_reset(d);
-+
-+    dprintf(d, 1, "%s: done\n", __FUNCTION__);
-+}
-+
-+static void qxl_reset_handler(DeviceState *dev)
-+{
-+    PCIQXLDevice *d = DO_UPCAST(PCIQXLDevice, pci.qdev, dev);
-+    qxl_hard_reset(d, 0);
-+}
-+
-+static void qxl_vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-+{
-+    VGACommonState *vga = opaque;
-+    PCIQXLDevice *qxl = container_of(vga, PCIQXLDevice, vga);
-+
-+    if (qxl->mode != QXL_MODE_VGA) {
-+        dprintf(qxl, 1, "%s\n", __FUNCTION__);
-+        qxl_destroy_primary(qxl);
-+        qxl_soft_reset(qxl);
-+    }
-+    vga_ioport_write(opaque, addr, val);
-+}
-+
-+static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta)
-+{
-+    static const int regions[] = {
-+        QXL_RAM_RANGE_INDEX,
-+        QXL_VRAM_RANGE_INDEX,
-+    };
-+    uint64_t guest_start;
-+    uint64_t guest_end;
-+    int pci_region;
-+    pcibus_t pci_start;
-+    pcibus_t pci_end;
-+    intptr_t virt_start;
-+    QXLDevMemSlot memslot;
-+    int i;
-+
-+    guest_start = le64_to_cpu(d->guest_slots[slot_id].slot.mem_start);
-+    guest_end   = le64_to_cpu(d->guest_slots[slot_id].slot.mem_end);
-+
-+    dprintf(d, 1, "%s: slot %d: guest phys 0x%" PRIx64 " - 0x%" PRIx64 "\n",
-+            __FUNCTION__, slot_id,
-+            guest_start, guest_end);
-+
-+    PANIC_ON(slot_id >= NUM_MEMSLOTS);
-+    PANIC_ON(guest_start > guest_end);
-+
-+    for (i = 0; i < ARRAY_SIZE(regions); i++) {
-+        pci_region = regions[i];
-+        pci_start = d->pci.io_regions[pci_region].addr;
-+        pci_end = pci_start + d->pci.io_regions[pci_region].size;
-+        /* mapped? */
-+        if (pci_start == -1) {
-+            continue;
-+        }
-+        /* start address in range ? */
-+        if (guest_start < pci_start || guest_start > pci_end) {
-+            continue;
-+        }
-+        /* end address in range ? */
-+        if (guest_end > pci_end) {
-+            continue;
-+        }
-+        /* passed */
-+        break;
-+    }
-+    PANIC_ON(i == ARRAY_SIZE(regions)); /* finished loop without match */
-+
-+    switch (pci_region) {
-+    case QXL_RAM_RANGE_INDEX:
-+        virt_start = (intptr_t)qemu_get_ram_ptr(d->vga.vram_offset);
-+        break;
-+    case QXL_VRAM_RANGE_INDEX:
-+        virt_start = (intptr_t)qemu_get_ram_ptr(d->vram_offset);
-+        break;
-+    default:
-+        /* should not happen */
-+        abort();
-+    }
-+
-+    memslot.slot_id = slot_id;
-+    memslot.slot_group_id = MEMSLOT_GROUP_GUEST; /* guest group */
-+    memslot.virt_start = virt_start + (guest_start - pci_start);
-+    memslot.virt_end   = virt_start + (guest_end   - pci_start);
-+    memslot.addr_delta = memslot.virt_start - delta;
-+    memslot.generation = d->rom->slot_generation = 0; // FIXME d->generation++;
-+    qxl_rom_set_dirty(d);
-+
-+    dprintf(d, 1, "%s: slot %d: host virt 0x%" PRIx64 " - 0x%" PRIx64 "\n",
-+            __FUNCTION__, memslot.slot_id,
-+            memslot.virt_start, memslot.virt_end);
-+
-+    d->ssd.worker->add_memslot(d->ssd.worker, &memslot);
-+    d->guest_slots[slot_id].ptr = (void*)memslot.virt_start;
-+    d->guest_slots[slot_id].size = memslot.virt_end - memslot.virt_start;
-+    d->guest_slots[slot_id].delta = delta;
-+    d->guest_slots[slot_id].active = 1;
-+}
-+
-+static void qxl_del_memslot(PCIQXLDevice *d, uint32_t slot_id)
-+{
-+    dprintf(d, 1, "%s: slot %d\n", __FUNCTION__, slot_id);
-+    d->ssd.worker->del_memslot(d->ssd.worker, MEMSLOT_GROUP_HOST, slot_id);
-+    d->guest_slots[slot_id].active = 0;
-+}
-+
-+static void qxl_reset_memslots(PCIQXLDevice *d)
-+{
-+    dprintf(d, 1, "%s:\n", __FUNCTION__);
-+    d->ssd.worker->reset_memslots(d->ssd.worker);
-+    memset(&d->guest_slots, 0, sizeof(d->guest_slots));
-+}
-+
-+static void qxl_reset_surfaces(PCIQXLDevice *d)
-+{
-+    dprintf(d, 1, "%s:\n", __FUNCTION__);
-+    d->mode = QXL_MODE_UNDEFINED;
-+    d->ssd.worker->destroy_surfaces(d->ssd.worker);
-+    memset(&d->guest_surfaces.cmds, 0, sizeof(d->guest_surfaces.cmds));
-+}
-+
-+void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id)
-+{
-+    uint64_t phys   = le64_to_cpu(pqxl);
-+    uint32_t slot   = (phys >> (64 -  8)) & 0xff;
-+    uint64_t offset = phys & 0xffffffffffff;
-+
-+    switch (group_id) {
-+    case MEMSLOT_GROUP_HOST:
-+        return (void*)offset;
-+    case MEMSLOT_GROUP_GUEST:
-+        PANIC_ON(slot > NUM_MEMSLOTS);
-+        PANIC_ON(!qxl->guest_slots[slot].active);
-+        PANIC_ON(offset < qxl->guest_slots[slot].delta);
-+        offset -= qxl->guest_slots[slot].delta;
-+        PANIC_ON(offset > qxl->guest_slots[slot].size)
-+        return qxl->guest_slots[slot].ptr + offset;
-+    default:
-+        PANIC_ON(1);
-+    }
-+}
-+
-+static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm)
-+{
-+    QXLDevSurfaceCreate surface;
-+    QXLSurfaceCreate *sc = &qxl->guest_primary.surface;
-+
-+    assert(qxl->mode != QXL_MODE_NATIVE);
-+    qxl_exit_vga_mode(qxl);
-+
-+    dprintf(qxl, 1, "%s: %dx%d\n", __FUNCTION__,
-+            le32_to_cpu(sc->width), le32_to_cpu(sc->height));
-+
-+    surface.format     = le32_to_cpu(sc->format);
-+    surface.height     = le32_to_cpu(sc->height);
-+    surface.mem        = le64_to_cpu(sc->mem);
-+    surface.position   = le32_to_cpu(sc->position);
-+    surface.stride     = le32_to_cpu(sc->stride);
-+    surface.width      = le32_to_cpu(sc->width);
-+    surface.type       = le32_to_cpu(sc->type);
-+    surface.flags      = le32_to_cpu(sc->flags);
-+
-+    surface.mouse_mode = true;
-+    surface.group_id   = MEMSLOT_GROUP_GUEST;
-+    if (loadvm) {
-+        surface.flags |= QXL_SURF_FLAG_KEEP_DATA;
-+    }
-+
-+    qxl->mode = QXL_MODE_NATIVE;
-+    qxl->cmdflags = 0;
-+    qxl->ssd.worker->create_primary_surface(qxl->ssd.worker, 0, &surface);
-+
-+    /* for local rendering */
-+    qxl_render_resize(qxl);
-+}
-+
-+static void qxl_destroy_primary(PCIQXLDevice *d)
-+{
-+    if (d->mode == QXL_MODE_UNDEFINED) {
-+        return;
-+    }
-+
-+    dprintf(d, 1, "%s\n", __FUNCTION__);
-+
-+    d->mode = QXL_MODE_UNDEFINED;
-+    d->ssd.worker->destroy_primary_surface(d->ssd.worker, 0);
-+}
-+
-+static void qxl_set_mode(PCIQXLDevice *d, int modenr)
-+{
-+    pcibus_t start = d->pci.io_regions[QXL_RAM_RANGE_INDEX].addr;
-+    pcibus_t end   = d->pci.io_regions[QXL_RAM_RANGE_INDEX].size + start;
-+    QXLMode *mode = d->modes->modes + modenr;
-+    uint64_t devmem = d->pci.io_regions[QXL_RAM_RANGE_INDEX].addr;
-+    QXLMemSlot slot = {
-+        .mem_start = start,
-+        .mem_end = end
-+    };
-+    QXLSurfaceCreate surface = {
-+        .width      = mode->x_res,
-+        .height     = mode->y_res,
-+        .stride     = -mode->x_res * 4,
-+        .format     = SPICE_SURFACE_FMT_32_xRGB,
-+        .mouse_mode = true,
-+        .mem        = devmem,
-+    };
-+
-+    dprintf(d, 1, "%s: mode %d  [ %d x %d @ %d bpp devmem 0x%lx ]\n", __FUNCTION__,
-+            modenr, mode->x_res, mode->y_res, mode->bits, devmem);
-+    qxl_hard_reset(d, 0);
-+
-+    d->guest_slots[0].slot = slot;
-+    qxl_add_memslot(d, 0, devmem);
-+
-+    d->guest_primary.surface = surface;
-+    qxl_create_guest_primary(d, 0);
-+
-+    d->mode = QXL_MODE_COMPAT;
-+    d->cmdflags = QXL_COMMAND_FLAG_COMPAT;
-+    d->shadow_rom.mode = cpu_to_le32(modenr);
-+    d->rom->mode = cpu_to_le32(modenr);
-+    qxl_rom_set_dirty(d);
-+}
-+
-+static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
-+{
-+    PCIQXLDevice *d = opaque;
-+    uint32_t io_port = addr - d->io_base;
-+
-+    switch (io_port) {
-+    case QXL_IO_RESET:
-+    case QXL_IO_SET_MODE:
-+    case QXL_IO_MEMSLOT_ADD:
-+    case QXL_IO_MEMSLOT_DEL:
-+    case QXL_IO_CREATE_PRIMARY:
-+        break;
-+    default:
-+        if (d->mode == QXL_MODE_NATIVE || d->mode == QXL_MODE_COMPAT)
-+            break;
-+        dprintf(d, 1, "%s: unexpected port 0x%x in vga mode\n", __FUNCTION__, io_port);
-+        return;
-+    }
-+
-+    switch (io_port) {
-+    case QXL_IO_UPDATE_AREA:
-+    {
-+        QXLRect update = d->ram->update_area;
-+        d->ssd.worker->update_area(d->ssd.worker, d->ram->update_surface,
-+                                   &update, NULL, 0, 0);
-+        break;
-+    }
-+    case QXL_IO_NOTIFY_CMD:
-+        d->ssd.worker->wakeup(d->ssd.worker);
-+        break;
-+    case QXL_IO_NOTIFY_CURSOR:
-+        d->ssd.worker->wakeup(d->ssd.worker);
-+        break;
-+    case QXL_IO_UPDATE_IRQ:
-+        qxl_set_irq(d);
-+        break;
-+    case QXL_IO_NOTIFY_OOM:
-+        if (!SPICE_RING_IS_EMPTY(&d->ram->release_ring)) {
-+            break;
-+        }
-+        pthread_yield();
-+        if (!SPICE_RING_IS_EMPTY(&d->ram->release_ring)) {
-+            break;
-+        }
-+        d->ssd.worker->oom(d->ssd.worker);
-+        break;
-+    case QXL_IO_SET_MODE:
-+        dprintf(d, 1, "QXL_SET_MODE %d\n", val);
-+        qxl_set_mode(d, val);
-+        break;
-+    case QXL_IO_LOG:
-+        dprintf(d, 1, "log %s", d->ram->log_buf);
-+        break;
-+    case QXL_IO_RESET:
-+        dprintf(d, 1, "QXL_IO_RESET\n");
-+        qxl_hard_reset(d, 0);
-+        break;
-+    case QXL_IO_MEMSLOT_ADD:
-+        PANIC_ON(val >= NUM_MEMSLOTS);
-+        PANIC_ON(d->guest_slots[val].active);
-+        d->guest_slots[val].slot = d->ram->mem_slot;
-+        qxl_add_memslot(d, val, 0);
-+        break;
-+    case QXL_IO_MEMSLOT_DEL:
-+        qxl_del_memslot(d, val);
-+        break;
-+    case QXL_IO_CREATE_PRIMARY:
-+        PANIC_ON(val != 0);
-+        dprintf(d, 1, "QXL_IO_CREATE_PRIMARY\n");
-+        d->guest_primary.surface = d->ram->create_surface;
-+        qxl_create_guest_primary(d, 0);
-+        break;
-+    case QXL_IO_DESTROY_PRIMARY:
-+        PANIC_ON(val != 0);
-+        dprintf(d, 1, "QXL_IO_DESTROY_PRIMARY\n");
-+        qxl_destroy_primary(d);
-+        break;
-+    case QXL_IO_DESTROY_SURFACE_WAIT:
-+        d->ssd.worker->destroy_surface_wait(d->ssd.worker, val);
-+        break;
-+    default:
-+        fprintf(stderr, "%s: ioport=0x%x, abort()\n", __FUNCTION__, io_port);
-+        abort();
-+    }
-+}
-+
-+static uint32_t ioport_read(void *opaque, uint32_t addr)
-+{
-+    PCIQXLDevice *d = opaque;
-+
-+    dprintf(d, 1, "%s: unexpected\n", __FUNCTION__);
-+    return 0xff;
-+}
-+
-+static void qxl_map(PCIDevice *pci, int region_num,
-+                    pcibus_t addr, pcibus_t size, int type)
-+{
-+    static const char *names[] = {
-+        [ QXL_IO_RANGE_INDEX ]   = "ioports",
-+        [ QXL_RAM_RANGE_INDEX ]  = "devram",
-+        [ QXL_ROM_RANGE_INDEX ]  = "rom",
-+        [ QXL_VRAM_RANGE_INDEX ] = "vram",
-+    };
-+    PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, pci);
-+
-+    dprintf(qxl, 1, "%s: bar %d [%s] addr 0x%lx size 0x%lx\n", __FUNCTION__,
-+            region_num, names[region_num], addr, size);
-+
-+    switch (region_num) {
-+    case QXL_IO_RANGE_INDEX:
-+        register_ioport_write(addr, size, 1, ioport_write, pci);
-+        register_ioport_read(addr, size, 1, ioport_read, pci);
-+        qxl->io_base = addr;
-+        break;
-+    case QXL_RAM_RANGE_INDEX:
-+        cpu_register_physical_memory(addr, size, qxl->vga.vram_offset | IO_MEM_RAM);
-+        qxl->vga.map_addr = addr;
-+        qxl->vga.map_end = addr + size;
-+        if (qxl->id == 0) {
-+            vga_dirty_log_start(&qxl->vga);
-+        }
-+        break;
-+    case QXL_ROM_RANGE_INDEX:
-+        cpu_register_physical_memory(addr, size, qxl->rom_offset | IO_MEM_ROM);
-+        break;
-+    case QXL_VRAM_RANGE_INDEX:
-+        cpu_register_physical_memory(addr, size, qxl->vram_offset | IO_MEM_RAM);
-+        break;
-+    }
-+}
-+
-+static void pipe_read(void *opaque)
-+{
-+    PCIQXLDevice *d = opaque;
-+    char dummy;
-+    int len;
-+
-+    do {
-+        len = read(d->pipe[0], &dummy, sizeof(dummy));
-+    } while (len == sizeof(dummy));
-+    qxl_set_irq(d);
-+}
-+
-+static void qxl_send_events(PCIQXLDevice *d, uint32_t events)
-+{
-+    uint32_t old_pending;
-+    uint32_t le_events = cpu_to_le32(events);
-+
-+    assert(d->ssd.running);
-+    old_pending = __sync_fetch_and_or(&d->ram->int_pending, le_events);
-+    if ((old_pending & le_events) == le_events) {
-+        return;
-+    }
-+    if (pthread_self() == d->main) {
-+        qxl_set_irq(d);
-+    } else {
-+        if (write(d->pipe[1], d, 1) != 1) {
-+            dprintf(d, 1, "%s: write to pipe failed\n", __FUNCTION__);
-+        }
-+    }
-+}
-+
-+static void init_pipe_signaling(PCIQXLDevice *d)
-+{
-+   if (pipe(d->pipe) < 0) {
-+       dprintf(d, 1, "%s: pipe creation failed\n", __FUNCTION__);
-+       return;
-+   }
-+#ifdef CONFIG_IOTHREAD
-+   fcntl(d->pipe[0], F_SETFL, O_NONBLOCK);
-+#else
-+   fcntl(d->pipe[0], F_SETFL, O_NONBLOCK /* | O_ASYNC */);
-+#endif
-+   fcntl(d->pipe[1], F_SETFL, O_NONBLOCK);
-+   fcntl(d->pipe[0], F_SETOWN, getpid());
-+
-+   d->main = pthread_self();
-+   qemu_set_fd_handler(d->pipe[0], pipe_read, NULL, d);
-+}
-+
-+/* graphics console */
-+
-+static void qxl_hw_update(void *opaque)
-+{
-+    PCIQXLDevice *qxl = opaque;
-+    VGACommonState *vga = &qxl->vga;
-+
-+    switch (qxl->mode) {
-+    case QXL_MODE_VGA:
-+        vga->update(vga);
-+        break;
-+    case QXL_MODE_NATIVE:
-+        qxl_render_update(qxl);
-+        break;
-+    default:
-+        break;
-+    }
-+}
-+
-+static void qxl_hw_invalidate(void *opaque)
-+{
-+    PCIQXLDevice *qxl = opaque;
-+    VGACommonState *vga = &qxl->vga;
-+
-+    vga->invalidate(vga);
-+}
-+
-+static void qxl_hw_screen_dump(void *opaque, const char *filename)
-+{
-+    PCIQXLDevice *qxl = opaque;
-+    VGACommonState *vga = &qxl->vga;
-+
-+    if (qxl->mode == QXL_MODE_VGA) {
-+        vga->screen_dump(vga, filename);
-+        return;
-+    }
-+}
-+
-+static void qxl_hw_text_update(void *opaque, console_ch_t *chardata)
-+{
-+    PCIQXLDevice *qxl = opaque;
-+    VGACommonState *vga = &qxl->vga;
-+
-+    if (qxl->mode == QXL_MODE_VGA) {
-+        vga->text_update(vga, chardata);
-+        return;
-+    }
-+}
-+
-+static void qxl_vm_change_state_handler(void *opaque, int running, int reason)
-+{
-+    PCIQXLDevice *qxl = opaque;
-+    qemu_spice_vm_change_state_handler(&qxl->ssd, running, reason);
-+}
-+
-+/* display change listener */
-+
-+static void display_update(struct DisplayState *ds, int x, int y, int w, int h)
-+{
-+    if (qxl0->mode == QXL_MODE_VGA) {
-+        qemu_spice_display_update(&qxl0->ssd, x, y, w, h);
-+    }
-+}
-+
-+static void display_resize(struct DisplayState *ds)
-+{
-+    if (qxl0->mode == QXL_MODE_VGA) {
-+        qemu_spice_display_resize(&qxl0->ssd);
-+    }
-+}
-+
-+static void display_refresh(struct DisplayState *ds)
-+{
-+    if (qxl0->mode == QXL_MODE_VGA) {
-+        qemu_spice_display_refresh(&qxl0->ssd);
-+    }
-+}
-+
-+static DisplayChangeListener display_listener = {
-+    .dpy_update  = display_update,
-+    .dpy_resize  = display_resize,
-+    .dpy_refresh = display_refresh,
-+};
-+
-+static int qxl_init(PCIDevice *dev)
-+{
-+    PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, dev);
-+    VGACommonState *vga = &qxl->vga;
-+    uint8_t* config = qxl->pci.config;
-+    ram_addr_t ram_size = msb_mask(qxl->vga.vram_size * 2 - 1);
-+    uint32_t pci_device_id;
-+    uint32_t pci_device_rev;
-+
-+    if (device_id == 0 && dev->qdev.hotplugged) {
-+        device_id++;
-+    }
-+
-+    qxl->id = device_id;
-+    qxl->mode = QXL_MODE_UNDEFINED;
-+    qxl->generation = 1;
-+
-+    switch (qxl->revision) {
-+    case 1: /* qxl-1 */
-+        pci_device_id  = 0x0100;
-+        pci_device_rev = 1;
-+        break;
-+    case 2: /* qxl-2 */
-+        pci_device_id  = 0x0100;
-+        pci_device_rev = 2;
-+        break;
-+    default: /* unstable */
-+        pci_device_id  = 0x01ff;
-+        pci_device_rev = 1;
-+        break;
-+    }
-+
-+    if (!qxl->id) {
-+        if (ram_size < 32 * 1024 * 1024)
-+            ram_size = 32 * 1024 * 1024;
-+        vga_common_init(vga, ram_size);
-+        vga_init(vga);
-+        register_ioport_write(0x3c0, 16, 1, qxl_vga_ioport_write, vga);
-+        register_ioport_write(0x3b4,  2, 1, qxl_vga_ioport_write, vga);
-+        register_ioport_write(0x3d4,  2, 1, qxl_vga_ioport_write, vga);
-+        register_ioport_write(0x3ba,  1, 1, qxl_vga_ioport_write, vga);
-+        register_ioport_write(0x3da,  1, 1, qxl_vga_ioport_write, vga);
-+
-+        vga->ds = graphic_console_init(qxl_hw_update, qxl_hw_invalidate,
-+                                       qxl_hw_screen_dump, qxl_hw_text_update, qxl);
-+        qxl->ssd.ds = vga->ds;
-+        qxl->ssd.bufsize = (16 * 1024 * 1024);
-+        qxl->ssd.buf = qemu_malloc(qxl->ssd.bufsize);
-+        pthread_mutex_init(&qxl->ssd.lock, NULL);
-+
-+        qxl0 = qxl;
-+        register_displaychangelistener(vga->ds, &display_listener);
-+
-+        if (qxl->pci.romfile == NULL) {
-+            if (pci_device_id == 0x01ff) {
-+                qxl->pci.romfile = qemu_strdup("vgabios-qxldev.bin");
-+            } else {
-+                qxl->pci.romfile = qemu_strdup("vgabios-qxl.bin");
-+            }
-+        }
-+        pci_config_set_class(config, PCI_CLASS_DISPLAY_VGA);
-+    } else {
-+        if (ram_size < 16 * 1024 * 1024)
-+            ram_size = 16 * 1024 * 1024;
-+        qxl->vga.vram_size = ram_size;
-+        qxl->vga.vram_offset = qemu_ram_alloc(&qxl->pci.qdev, "bar0", qxl->vga.vram_size);
-+        qxl->vga.vram_ptr = qemu_get_ram_ptr(qxl->vga.vram_offset);
-+
-+        pci_config_set_class(config, PCI_CLASS_DISPLAY_OTHER);
-+    }
-+
-+    pci_config_set_vendor_id(config, REDHAT_PCI_VENDOR_ID);
-+    pci_config_set_device_id(config, pci_device_id);
-+    pci_set_byte(&config[PCI_REVISION_ID], pci_device_rev);
-+    pci_set_byte(&config[PCI_INTERRUPT_PIN], 1);
-+
-+    qxl->rom_size = qxl_rom_size();
-+    qxl->rom_offset = qemu_ram_alloc(&qxl->pci.qdev, "bar2", qxl->rom_size);
-+    init_qxl_rom(qxl);
-+    init_qxl_ram(qxl);
-+
-+    if (qxl->vram_size < 16 * 1024 * 1024)
-+        qxl->vram_size = 16 * 1024 * 1024;
-+    qxl->vram_size = msb_mask(qxl->vram_size * 2 - 1);
-+    qxl->vram_offset = qemu_ram_alloc(&qxl->pci.qdev, "bar1", qxl->vram_size);
-+
-+    pci_register_bar(&qxl->pci, QXL_IO_RANGE_INDEX,
-+                     msb_mask(QXL_IO_RANGE_SIZE * 2 - 1),
-+                     PCI_BASE_ADDRESS_SPACE_IO, qxl_map);
-+
-+    pci_register_bar(&qxl->pci, QXL_ROM_RANGE_INDEX,
-+                     qxl->rom_size, PCI_BASE_ADDRESS_SPACE_MEMORY,
-+                     qxl_map);
-+
-+    pci_register_bar(&qxl->pci, QXL_RAM_RANGE_INDEX,
-+                     qxl->vga.vram_size, PCI_BASE_ADDRESS_SPACE_MEMORY,
-+                     qxl_map);
-+
-+    pci_register_bar(&qxl->pci, QXL_VRAM_RANGE_INDEX, qxl->vram_size,
-+                     PCI_BASE_ADDRESS_SPACE_MEMORY, qxl_map);
-+
-+    qxl->ssd.qxl.base.sif = &qxl_interface.base;
-+    qxl->ssd.qxl.id = qxl->id;
-+    spice_server_add_interface(spice_server, &qxl->ssd.qxl.base);
-+    qemu_add_vm_change_state_handler(qxl_vm_change_state_handler, qxl);
-+
-+    init_pipe_signaling(qxl);
-+    qxl_reset_state(qxl);
-+
-+    device_id++;
-+    return 0;
-+}
-+
-+static void qxl_pre_save(void *opaque)
-+{
-+    PCIQXLDevice* d = opaque;
-+    uint8_t *ram_start = d->vga.vram_ptr;
-+
-+    dprintf(d, 1, "%s:\n", __FUNCTION__);
-+#if 1 /* wanna zap this */
-+    if (d->last_release == NULL) {
-+        d->last_release_offset = 0;
-+    } else {
-+        d->last_release_offset = (uint8_t *)d->last_release - ram_start;
-+    }
-+    assert(d->last_release_offset < d->vga.vram_size);
-+#endif
-+}
-+
-+static int qxl_pre_load(void *opaque)
-+{
-+    PCIQXLDevice* d = opaque;
-+
-+    dprintf(d, 1, "%s: start\n", __FUNCTION__);
-+    qxl_hard_reset(d, 1);
-+    qxl_exit_vga_mode(d);
-+    dprintf(d, 1, "%s: done\n", __FUNCTION__);
-+    return 0;
-+}
-+
-+static int qxl_post_load(void *opaque, int version)
-+{
-+    PCIQXLDevice* d = opaque;
-+    uint8_t *ram_start = d->vga.vram_ptr;
-+    QXLCommandExt *cmds;
-+    int in, out, i, newmode;
-+
-+    dprintf(d, 1, "%s: start\n", __FUNCTION__);
-+    newmode = d->mode;
-+    d->mode = QXL_MODE_UNDEFINED;
-+    switch (newmode) {
-+    case QXL_MODE_UNDEFINED:
-+        break;
-+    case QXL_MODE_VGA:
-+        qxl_enter_vga_mode(d);
-+        break;
-+    case QXL_MODE_NATIVE:
-+        for (i = 0; i < NUM_MEMSLOTS; i++) {
-+            if (!d->guest_slots[i].active)
-+                continue;
-+            qxl_add_memslot(d, i, 0);
-+        }
-+        qxl_create_guest_primary(d, 1);
-+
-+        /* replay surface-create and cursor-set commands */
-+        cmds = qemu_mallocz(sizeof(QXLCommandExt) * (NUM_SURFACES + 1));
-+        for (in = 0, out = 0; in < NUM_SURFACES; in++) {
-+            if (d->guest_surfaces.cmds[in] == 0)
-+                continue;
-+            cmds[out].cmd.data = d->guest_surfaces.cmds[in];
-+            cmds[out].cmd.type = QXL_CMD_SURFACE;
-+            cmds[out].group_id = MEMSLOT_GROUP_GUEST;
-+            out++;
-+        }
-+        cmds[out].cmd.data = d->guest_cursor;
-+        cmds[out].cmd.type = QXL_CMD_CURSOR;
-+        cmds[out].group_id = MEMSLOT_GROUP_GUEST;
-+        out++;
-+        d->ssd.worker->loadvm_commands(d->ssd.worker, cmds, out);
-+        qemu_free(cmds);
-+
-+        break;
-+    case QXL_MODE_COMPAT:
-+        qxl_set_mode(d, d->shadow_rom.mode);
-+        break;
-+    }
-+    dprintf(d, 1, "%s: done\n", __FUNCTION__);
-+
-+#if 1 /* wanna zap this */
-+    if (d->last_release_offset >= d->vga.vram_size) {
-+        dprintf(d, 1, "%s: invalid last_release_offset %u, ram_size %u\n",
-+                __FUNCTION__, d->last_release_offset, d->vga.vram_size);
-+        exit(-1);
-+    }
-+
-+    if (d->last_release_offset == 0) {
-+        d->last_release = NULL;
-+    } else {
-+        d->last_release = (QXLReleaseInfo *)(ram_start + d->last_release_offset);
-+    }
-+#endif
-+
-+    return 0;
-+}
-+
-+#define QXL_VER 1
-+
-+static VMStateDescription qxl_memslot = {
-+    .name               = "qxl-memslot",
-+    .version_id         = QXL_VER,
-+    .minimum_version_id = QXL_VER,
-+    .fields = (VMStateField[]) {
-+        VMSTATE_UINT64(slot.mem_start, struct guest_slots),
-+        VMSTATE_UINT64(slot.mem_end,   struct guest_slots),
-+        VMSTATE_UINT32(active,         struct guest_slots),
-+        VMSTATE_END_OF_LIST()
-+    }
-+};
-+
-+static VMStateDescription qxl_surface = {
-+    .name               = "qxl-surface",
-+    .version_id         = QXL_VER,
-+    .minimum_version_id = QXL_VER,
-+    .fields = (VMStateField[]) {
-+        VMSTATE_UINT32(width,      QXLSurfaceCreate),
-+        VMSTATE_UINT32(height,     QXLSurfaceCreate),
-+        VMSTATE_INT32(stride,      QXLSurfaceCreate),
-+        VMSTATE_UINT32(format,     QXLSurfaceCreate),
-+        VMSTATE_UINT32(position,   QXLSurfaceCreate),
-+        VMSTATE_UINT32(mouse_mode, QXLSurfaceCreate),
-+        VMSTATE_UINT32(flags,      QXLSurfaceCreate),
-+        VMSTATE_UINT32(type,       QXLSurfaceCreate),
-+        VMSTATE_UINT64(mem,        QXLSurfaceCreate),
-+        VMSTATE_END_OF_LIST()
-+    }
-+};
-+
-+static VMStateDescription qxl_vmstate = {
-+    .name               = "qxl",
-+    .version_id         = QXL_VER,
-+    .minimum_version_id = QXL_VER,
-+    .pre_save           = qxl_pre_save,
-+    .pre_load           = qxl_pre_load,
-+    .post_load          = qxl_post_load,
-+    .fields = (VMStateField []) {
-+        VMSTATE_PCI_DEVICE(pci, PCIQXLDevice),
-+        VMSTATE_STRUCT(vga, PCIQXLDevice, QXL_VER, vmstate_vga_common, VGACommonState),
-+        VMSTATE_UINT32(shadow_rom.mode, PCIQXLDevice),
-+#if 1 /* wanna zap this */
-+        VMSTATE_UINT32(num_free_res, PCIQXLDevice),
-+        VMSTATE_UINT32(last_release_offset, PCIQXLDevice),
-+#endif
-+        VMSTATE_UINT32(mode, PCIQXLDevice),
-+        VMSTATE_UINT32(ssd.unique, PCIQXLDevice),
-+#if 1 /* new stuff */
-+        VMSTATE_STRUCT_ARRAY(guest_slots, PCIQXLDevice, NUM_MEMSLOTS, QXL_VER,
-+                             qxl_memslot, struct guest_slots),
-+        VMSTATE_STRUCT(guest_primary.surface, PCIQXLDevice, QXL_VER,
-+                       qxl_surface, QXLSurfaceCreate),
-+        VMSTATE_ARRAY(guest_surfaces.cmds, PCIQXLDevice, NUM_SURFACES, QXL_VER,
-+                      vmstate_info_uint64, uint64_t),
-+        VMSTATE_UINT64(guest_cursor, PCIQXLDevice),
-+#endif
-+        VMSTATE_END_OF_LIST()
-+    }
-+};
-+
-+static PCIDeviceInfo qxl_info = {
-+    .qdev.name    = "qxl",
-+    .qdev.desc    = "Spice QXL GPU",
-+    .qdev.size    = sizeof(PCIQXLDevice),
-+    .qdev.reset   = qxl_reset_handler,
-+    .qdev.vmsd    = &qxl_vmstate,
-+    .init         = qxl_init,
-+    .config_write = qxl_write_config,
-+    .qdev.props = (Property[]) {
-+        DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size, 64 * 1024 * 1024),
-+        DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram_size, 64 * 1024 * 1024),
-+        DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision, 3),
-+        DEFINE_PROP_UINT32("debug", PCIQXLDevice, debug, 0),
-+        DEFINE_PROP_UINT32("cmdlog", PCIQXLDevice, cmdlog, 0),
-+        DEFINE_PROP_END_OF_LIST(),
-+    }
-+};
-+
-+static void qxl_register(void)
-+{
-+    pci_qdev_register(&qxl_info);
-+}
-+
-+device_init(qxl_register);
-diff --git a/hw/qxl.h b/hw/qxl.h
-new file mode 100644
-index 0000000..1216405
---- /dev/null
-+++ b/hw/qxl.h
-@@ -0,0 +1,102 @@
-+#include "console.h"
-+#include "hw.h"
-+#include "pci.h"
-+#include "vga_int.h"
-+
-+#include "qemu-spice.h"
-+#include "spice-display.h"
-+
-+enum qxl_mode {
-+    QXL_MODE_UNDEFINED,
-+    QXL_MODE_VGA,
-+    QXL_MODE_COMPAT, /* spice 0.4.x */
-+    QXL_MODE_NATIVE,
-+};
-+
-+typedef struct PCIQXLDevice {
-+    PCIDevice          pci;
-+    SimpleSpiceDisplay ssd;
-+    int                id;
-+    uint32_t           debug;
-+    uint32_t           cmdlog;
-+    enum qxl_mode      mode;
-+    uint32_t           cmdflags;
-+    int                generation;
-+    uint32_t           revision;
-+
-+    struct guest_slots {
-+        QXLMemSlot     slot;
-+        void           *ptr;
-+        uint64_t       size;
-+        uint64_t       delta;
-+        uint32_t       active;
-+    } guest_slots[NUM_MEMSLOTS];
-+
-+    struct guest_primary {
-+        QXLSurfaceCreate surface;
-+        uint32_t       commands;
-+        uint32_t       resized;
-+        int32_t        stride;
-+        uint32_t       bits_pp;
-+        uint32_t       bytes_pp;
-+        uint8_t        *data, *flipped;
-+    } guest_primary;
-+
-+    struct surfaces {
-+        QXLPHYSICAL    cmds[NUM_SURFACES];
-+        uint32_t       count;
-+        uint32_t       max;
-+    } guest_surfaces;
-+    QXLPHYSICAL        guest_cursor;
-+
-+    /* thread signaling */
-+    pthread_t          main;
-+    int                pipe[2];
-+
-+    /* ram pci bar */
-+    QXLRam             *ram;
-+    VGACommonState     vga;
-+    uint32_t           num_free_res;
-+    QXLReleaseInfo     *last_release;
-+    uint32_t           last_release_offset;
-+
-+    /* rom pci bar */
-+    QXLRom             shadow_rom;
-+    QXLRom             *rom;
-+    QXLModes           *modes;
-+    uint32_t           rom_size;
-+    uint64_t           rom_offset;
-+
-+    /* vram pci bar */
-+    uint32_t           vram_size;
-+    uint64_t           vram_offset;
-+
-+    /* io bar */
-+    uint32_t           io_base;
-+
-+} PCIQXLDevice;
-+
-+#define PANIC_ON(x) if ((x)) {                         \
-+    printf("%s: PANIC %s failed\n", __FUNCTION__, #x); \
-+    exit(-1);                                          \
-+}
-+
-+#define dprintf(_qxl, _level, _fmt, ...)                                \
-+    do {                                                                \
-+        if (_qxl->debug >= _level) {                                    \
-+            fprintf(stderr, "qxl-%d: ", _qxl->id);                      \
-+            fprintf(stderr, _fmt, ## __VA_ARGS__);                      \
-+        }                                                               \
-+    } while (0)
-+
-+/* qxl.c */
-+void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id);
-+
-+/* qxl-logger.c */
-+void qxl_log_cmd_cursor(PCIQXLDevice *qxl, QXLCursorCmd *cmd, int group_id);
-+void qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext);
-+
-+/* qxl-render.c */
-+void qxl_render_resize(PCIQXLDevice *qxl);
-+void qxl_render_update(PCIQXLDevice *qxl);
-+void qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext);
-diff --git a/hw/vga_int.h b/hw/vga_int.h
-index 70e0f19..4a82683 100644
---- a/hw/vga_int.h
-+++ b/hw/vga_int.h
-@@ -106,7 +106,7 @@ typedef void (* vga_update_retrace_info_fn)(struct VGACommonState *s);
- typedef struct VGACommonState {
-     uint8_t *vram_ptr;
-     ram_addr_t vram_offset;
--    unsigned int vram_size;
-+    uint32_t vram_size;
-     uint32_t lfb_addr;
-     uint32_t lfb_end;
-     uint32_t map_addr;
-diff --git a/sysemu.h b/sysemu.h
-index bf1d68a..ea3634d 100644
---- a/sysemu.h
-+++ b/sysemu.h
-@@ -103,7 +103,7 @@ extern int autostart;
- extern int bios_size;
-
- typedef enum {
--    VGA_NONE, VGA_STD, VGA_CIRRUS, VGA_VMWARE, VGA_XENFB
-+    VGA_NONE, VGA_STD, VGA_CIRRUS, VGA_VMWARE, VGA_XENFB, VGA_QXL,
- } VGAInterfaceType;
-
- extern int vga_interface_type;
-@@ -111,6 +111,7 @@ extern int vga_interface_type;
- #define std_vga_enabled (vga_interface_type == VGA_STD)
- #define xenfb_enabled (vga_interface_type == VGA_XENFB)
- #define vmsvga_enabled (vga_interface_type == VGA_VMWARE)
-+#define qxl_enabled (vga_interface_type == VGA_QXL)
-
- extern int graphic_width;
- extern int graphic_height;
-diff --git a/vl.c b/vl.c
-index 2ccebc8..eb630bd 100644
---- a/vl.c
-+++ b/vl.c
-@@ -1459,6 +1459,8 @@ static void select_vgahw (const char *p)
-         vga_interface_type = VGA_VMWARE;
-     } else if (strstart(p, "xenfb", &opts)) {
-         vga_interface_type = VGA_XENFB;
-+    } else if (strstart(p, "qxl", &opts)) {
-+        vga_interface_type = VGA_QXL;
-     } else if (!strstart(p, "none", &opts)) {
-     invalid_vga:
-         fprintf(stderr, "Unknown vga type: %s\n", p);
-@@ -3034,7 +3036,7 @@ int main(int argc, char **argv, char **envp)
-         break;
-     }
- #ifdef CONFIG_SPICE
--    if (using_spice) {
-+    if (using_spice && !qxl_enabled) {
-         qemu_spice_display_init(ds);
-     }
- #endif
--- 
-1.7.2.3
-
diff --git a/0015-spice-add-audio.patch b/0015-spice-add-audio.patch
deleted file mode 100644
index 6725ffe..0000000
--- a/0015-spice-add-audio.patch
+++ /dev/null
@@ -1,405 +0,0 @@
-From f3e02bc08c4521dc53d858174612341462d588ce Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Tue, 13 Apr 2010 10:34:46 +0200
-Subject: [PATCH 15/39] spice: add audio
-
-Add support for the spice audio interface.
-
-The driver is first in the driver list, but can_be_default is set only
-in case spice is active.  So if you are using spice the spice audio
-driver is the default one, otherwise whatever comes first after spice in
-the list.  Overriding the default using QEMU_AUDIO_DRV works in any
-case.
----
- Makefile.objs      |    1 +
- audio/audio.c      |    3 +
- audio/audio_int.h  |    1 +
- audio/spiceaudio.c |  312 ++++++++++++++++++++++++++++++++++++++++++++++++++++
- qemu-spice.h       |    1 +
- spice.c            |    1 +
- 6 files changed, 319 insertions(+), 0 deletions(-)
- create mode 100644 audio/spiceaudio.c
-
-diff --git a/Makefile.objs b/Makefile.objs
-index d05643f..9a6b0f3 100644
---- a/Makefile.objs
-+++ b/Makefile.objs
-@@ -94,6 +94,7 @@ common-obj-$(CONFIG_SPICE) += spice.o spice-input.o spice-display.o
- audio-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
- audio-obj-$(CONFIG_SDL) += sdlaudio.o
- audio-obj-$(CONFIG_OSS) += ossaudio.o
-+audio-obj-$(CONFIG_SPICE) += spiceaudio.o
- audio-obj-$(CONFIG_COREAUDIO) += coreaudio.o
- audio-obj-$(CONFIG_ALSA) += alsaaudio.o
- audio-obj-$(CONFIG_DSOUND) += dsoundaudio.o
-diff --git a/audio/audio.c b/audio/audio.c
-index ad51077..ade342e 100644
---- a/audio/audio.c
-+++ b/audio/audio.c
-@@ -44,6 +44,9 @@
-     that we generate the list.
- */
- static struct audio_driver *drvtab[] = {
-+#ifdef CONFIG_SPICE
-+    &spice_audio_driver,
-+#endif
-     CONFIG_AUDIO_DRIVERS
-     &no_audio_driver,
-     &wav_audio_driver
-diff --git a/audio/audio_int.h b/audio/audio_int.h
-index 06e313f..d1f6c2d 100644
---- a/audio/audio_int.h
-+++ b/audio/audio_int.h
-@@ -209,6 +209,7 @@ extern struct audio_driver coreaudio_audio_driver;
- extern struct audio_driver dsound_audio_driver;
- extern struct audio_driver esd_audio_driver;
- extern struct audio_driver pa_audio_driver;
-+extern struct audio_driver spice_audio_driver;
- extern struct audio_driver winwave_audio_driver;
- extern struct mixeng_volume nominal_volume;
-
-diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c
-new file mode 100644
-index 0000000..8ae7499
---- /dev/null
-+++ b/audio/spiceaudio.c
-@@ -0,0 +1,312 @@
-+#include "hw/hw.h"
-+#include "qemu-timer.h"
-+#include "qemu-spice.h"
-+
-+#define AUDIO_CAP "spice"
-+#include "audio.h"
-+#include "audio_int.h"
-+
-+#define LINE_IN_SAMPLES 1024
-+#define LINE_OUT_SAMPLES 1024
-+
-+typedef struct SpiceVoiceOut {
-+    HWVoiceOut            hw;
-+    SpicePlaybackInstance sin;
-+    int64_t               prev_ticks;
-+    int                   active;
-+    uint32_t              *frame;
-+    uint32_t              *fpos;
-+    uint32_t              fsize;
-+} SpiceVoiceOut;
-+
-+typedef struct SpiceVoiceIn {
-+    HWVoiceIn             hw;
-+    SpiceRecordInstance   sin;
-+    int64_t               prev_ticks;
-+    int                   active;
-+    uint32_t              samples[LINE_IN_SAMPLES];
-+} SpiceVoiceIn;
-+
-+static const SpicePlaybackInterface playback_sif = {
-+    .base.type          = SPICE_INTERFACE_PLAYBACK,
-+    .base.description   = "playback",
-+    .base.major_version = SPICE_INTERFACE_PLAYBACK_MAJOR,
-+    .base.minor_version = SPICE_INTERFACE_PLAYBACK_MINOR,
-+};
-+
-+static const SpiceRecordInterface record_sif = {
-+    .base.type          = SPICE_INTERFACE_RECORD,
-+    .base.description   = "record",
-+    .base.major_version = SPICE_INTERFACE_RECORD_MAJOR,
-+    .base.minor_version = SPICE_INTERFACE_RECORD_MINOR,
-+};
-+
-+static void *spice_audio_init(void)
-+{
-+    if (!using_spice) {
-+        return NULL;
-+    }
-+    return &spice_audio_init;
-+}
-+
-+static void spice_audio_fini(void *opaque)
-+{
-+    /* nothing */
-+}
-+
-+static int calculate_samples(struct audio_pcm_info *info, int64_t *old_ticks)
-+{
-+    int64_t now;
-+    int64_t ticks;
-+    int64_t bytes;
-+    int samples;
-+
-+    now = qemu_get_clock (vm_clock);
-+    ticks = now - *old_ticks;
-+    *old_ticks = now;
-+    bytes = muldiv64 (ticks, info->bytes_per_second, get_ticks_per_sec ());
-+    bytes = audio_MIN (bytes, INT_MAX);
-+    samples = bytes >> info->shift;
-+    return samples;
-+}
-+
-+/* playback */
-+
-+static int line_out_init(HWVoiceOut *hw, struct audsettings *as)
-+{
-+    SpiceVoiceOut *out = container_of(hw, SpiceVoiceOut, hw);
-+    struct audsettings settings;
-+
-+    settings.freq       = SPICE_INTERFACE_PLAYBACK_FREQ;
-+    settings.nchannels  = SPICE_INTERFACE_PLAYBACK_CHAN;
-+    settings.fmt        = AUD_FMT_S16;
-+    settings.endianness = AUDIO_HOST_ENDIANNESS;
-+
-+    audio_pcm_init_info(&hw->info, &settings);
-+    hw->samples = LINE_OUT_SAMPLES;
-+    out->active = 0;
-+
-+    out->sin.base.sif = &playback_sif.base;
-+    spice_server_add_interface(spice_server, &out->sin.base);
-+    return 0;
-+}
-+
-+static void line_out_fini(HWVoiceOut *hw)
-+{
-+    SpiceVoiceOut *out = container_of(hw, SpiceVoiceOut, hw);
-+
-+    spice_server_remove_interface(&out->sin.base);
-+}
-+
-+static int line_out_run(HWVoiceOut *hw, int live)
-+{
-+    SpiceVoiceOut *out = container_of(hw, SpiceVoiceOut, hw);
-+    int rpos, decr;
-+    int samples;
-+
-+    if (!live) {
-+        return 0;
-+    }
-+
-+    decr = calculate_samples(&hw->info, &out->prev_ticks);
-+    decr = audio_MIN(live, decr);
-+
-+    samples = decr;
-+    rpos = hw->rpos;
-+    while (samples) {
-+        int left_till_end_samples = hw->samples - rpos;
-+        int len = audio_MIN(samples, left_till_end_samples);
-+
-+        if (!out->frame) {
-+            spice_server_playback_get_buffer(&out->sin, &out->frame, &out->fsize);
-+            out->fpos = out->frame;
-+        }
-+        if (out->frame) {
-+            len = audio_MIN(len, out->fsize);
-+            hw->clip(out->fpos, hw->mix_buf + rpos, len);
-+            out->fsize -= len;
-+            out->fpos  += len;
-+            if (out->fsize == 0) {
-+                spice_server_playback_put_samples(&out->sin, out->frame);
-+                out->frame = out->fpos = NULL;
-+            }
-+        }
-+        rpos = (rpos + len) % hw->samples;
-+        samples -= len;
-+    }
-+    hw->rpos = rpos;
-+    return decr;
-+}
-+
-+static int line_out_write(SWVoiceOut *sw, void *buf, int len)
-+{
-+    return audio_pcm_sw_write(sw, buf, len);
-+}
-+
-+static int line_out_ctl(HWVoiceOut *hw, int cmd, ...)
-+{
-+    SpiceVoiceOut *out = container_of(hw, SpiceVoiceOut, hw);
-+
-+    switch (cmd) {
-+    case VOICE_ENABLE:
-+        if (out->active) {
-+            break;
-+        }
-+        out->active = 1;
-+        out->prev_ticks = qemu_get_clock (vm_clock);
-+        spice_server_playback_start(&out->sin);
-+        break;
-+    case VOICE_DISABLE:
-+        if (!out->active) {
-+            break;
-+        }
-+        out->active = 0;
-+        if (out->frame) {
-+            memset(out->fpos, 0, out->fsize << 2);
-+            spice_server_playback_put_samples(&out->sin, out->frame);
-+            out->frame = out->fpos = NULL;
-+        }
-+        spice_server_playback_stop(&out->sin);
-+        break;
-+    }
-+    return 0;
-+}
-+
-+/* record */
-+
-+static int line_in_init(HWVoiceIn *hw, struct audsettings *as)
-+{
-+    SpiceVoiceIn *in = container_of(hw, SpiceVoiceIn, hw);
-+    struct audsettings settings;
-+
-+    settings.freq       = SPICE_INTERFACE_RECORD_FREQ;
-+    settings.nchannels  = SPICE_INTERFACE_RECORD_CHAN;
-+    settings.fmt        = AUD_FMT_S16;
-+    settings.endianness = AUDIO_HOST_ENDIANNESS;
-+
-+    audio_pcm_init_info(&hw->info, &settings);
-+    hw->samples = LINE_IN_SAMPLES;
-+    in->active = 0;
-+
-+    in->sin.base.sif = &record_sif.base;
-+    spice_server_add_interface(spice_server, &in->sin.base);
-+    return 0;
-+}
-+
-+static void line_in_fini(HWVoiceIn *hw)
-+{
-+    SpiceVoiceIn *in = container_of(hw, SpiceVoiceIn, hw);
-+
-+    spice_server_remove_interface(&in->sin.base);
-+}
-+
-+static int line_in_run(HWVoiceIn *hw)
-+{
-+    SpiceVoiceIn *in = container_of(hw, SpiceVoiceIn, hw);
-+    int num_samples;
-+    int ready;
-+    int len[2];
-+    uint64_t delta_samp;
-+    uint32_t *samples;
-+
-+    if (!(num_samples = hw->samples - audio_pcm_hw_get_live_in(hw))) {
-+        return 0;
-+    }
-+
-+    delta_samp = calculate_samples(&hw->info, &in->prev_ticks);
-+    num_samples = audio_MIN(num_samples, delta_samp);
-+
-+    ready = spice_server_record_get_samples(&in->sin, in->samples, num_samples);
-+    samples = in->samples;
-+    if (ready == 0) {
-+        static uint32_t silence[LINE_IN_SAMPLES];
-+        samples = silence;
-+        ready = LINE_IN_SAMPLES;
-+    }
-+
-+    num_samples = audio_MIN(ready, num_samples);
-+
-+    if (hw->wpos + num_samples > hw->samples) {
-+        len[0] = hw->samples - hw->wpos;
-+        len[1] = num_samples - len[0];
-+    } else {
-+        len[0] = num_samples;
-+        len[1] = 0;
-+    }
-+
-+    hw->conv(hw->conv_buf + hw->wpos, samples, len[0], &nominal_volume);
-+
-+    if (len[1]) {
-+        hw->conv(hw->conv_buf, samples + len[0], len[1],
-+                 &nominal_volume);
-+    }
-+
-+    hw->wpos = (hw->wpos + num_samples) % hw->samples;
-+
-+    return num_samples;
-+}
-+
-+static int line_in_read(SWVoiceIn *sw, void *buf, int size)
-+{
-+    return audio_pcm_sw_read(sw, buf, size);
-+}
-+
-+static int line_in_ctl(HWVoiceIn *hw, int cmd, ...)
-+{
-+    SpiceVoiceIn *in = container_of(hw, SpiceVoiceIn, hw);
-+
-+    switch (cmd) {
-+    case VOICE_ENABLE:
-+        if (in->active) {
-+            break;
-+        }
-+        in->active = 1;
-+        in->prev_ticks = qemu_get_clock (vm_clock);
-+        spice_server_record_start(&in->sin);
-+        break;
-+    case VOICE_DISABLE:
-+        if (!in->active) {
-+            break;
-+        }
-+        in->active = 0;
-+        spice_server_record_stop(&in->sin);
-+        break;
-+    }
-+    return 0;
-+}
-+
-+static struct audio_option audio_options[] = {
-+    { /* end of list */ },
-+};
-+
-+static struct audio_pcm_ops audio_callbacks = {
-+    .init_out = line_out_init,
-+    .fini_out = line_out_fini,
-+    .run_out  = line_out_run,
-+    .write    = line_out_write,
-+    .ctl_out  = line_out_ctl,
-+
-+    .init_in  = line_in_init,
-+    .fini_in  = line_in_fini,
-+    .run_in   = line_in_run,
-+    .read     = line_in_read,
-+    .ctl_in   = line_in_ctl,
-+};
-+
-+struct audio_driver spice_audio_driver = {
-+    .name           = "spice",
-+    .descr          = "spice audio driver",
-+    .options        = audio_options,
-+    .init           = spice_audio_init,
-+    .fini           = spice_audio_fini,
-+    .pcm_ops        = &audio_callbacks,
-+    .max_voices_out = 1,
-+    .max_voices_in  = 1,
-+    .voice_size_out = sizeof(SpiceVoiceOut),
-+    .voice_size_in  = sizeof(SpiceVoiceIn),
-+};
-+
-+void qemu_spice_audio_init(void)
-+{
-+    spice_audio_driver.can_be_default = 1;
-+}
-diff --git a/qemu-spice.h b/qemu-spice.h
-index f061004..6f19ba7 100644
---- a/qemu-spice.h
-+++ b/qemu-spice.h
-@@ -13,6 +13,7 @@ extern int using_spice;
-
- void qemu_spice_init(void);
- void qemu_spice_input_init(void);
-+void qemu_spice_audio_init(void);
- void qemu_spice_display_init(DisplayState *ds);
-
- #else  /* CONFIG_SPICE */
-diff --git a/spice.c b/spice.c
-index 3fe76cd..fc76ef7 100644
---- a/spice.c
-+++ b/spice.c
-@@ -204,6 +204,7 @@ void qemu_spice_init(void)
-     using_spice = 1;
-
-     qemu_spice_input_init();
-+    qemu_spice_audio_init();
-
-     qemu_free(x509_key_file);
-     qemu_free(x509_cert_file);
--- 
-1.7.2.3
-
diff --git a/0016-spice-add-virtio-serial-based-vdi-port-backend.patch b/0016-spice-add-virtio-serial-based-vdi-port-backend.patch
deleted file mode 100644
index 91528c9..0000000
--- a/0016-spice-add-virtio-serial-based-vdi-port-backend.patch
+++ /dev/null
@@ -1,238 +0,0 @@
-From ebf4cebd082442ed2bc11475fde301c18648298d Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Tue, 20 Apr 2010 13:33:54 +0200
-Subject: [PATCH 16/39] spice: add virtio-serial based vdi port backend.
-
-Adds the spicevmc device.  This is a communication channel between the
-spice client and the guest.  It is used to send display information and
-mouse events from the spice clients to the guest.
----
- Makefile.target |    1 +
- hw/spice-vmc.c  |  203 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 204 insertions(+), 0 deletions(-)
- create mode 100644 hw/spice-vmc.c
-
-diff --git a/Makefile.target b/Makefile.target
-index 4da33b5..90544c5 100644
---- a/Makefile.target
-+++ b/Makefile.target
-@@ -217,6 +217,7 @@ obj-i386-y += pc_piix.o
- obj-i386-y += testdev.o
- obj-i386-y += acpi.o acpi_piix4.o
- obj-i386-$(CONFIG_SPICE) += qxl.o qxl-logger.o qxl-render.o
-+obj-i386-$(CONFIG_SPICE) += spice-vmc.o
-
- obj-i386-y += pcspk.o i8254.o
- obj-i386-$(CONFIG_KVM_PIT) += i8254-kvm.o
-diff --git a/hw/spice-vmc.c b/hw/spice-vmc.c
-new file mode 100644
-index 0000000..3f6a2bb
---- /dev/null
-+++ b/hw/spice-vmc.c
-@@ -0,0 +1,203 @@
-+/*
-+
-+ Spice Virtual Machine Channel (VMC).
-+
-+ A virtio-serial port used for spice to guest communication, over
-+ which spice client and a daemon in the guest operating system
-+ communicate.
-+
-+ Replaces the old vdi_port PCI device.
-+
-+*/
-+
-+#include <stdio.h>
-+#include <stdbool.h>
-+#include <spice.h>
-+#include <spice-experimental.h>
-+
-+#include "virtio-serial.h"
-+#include "qemu-spice.h"
-+
-+#define VMC_GUEST_DEVICE_NAME "com.redhat.spice.0"
-+#define VMC_DEVICE_NAME       "spicevmc"
-+
-+#define dprintf(_svc, _level, _fmt, ...)                                \
-+    do {                                                                \
-+        if (_svc->debug >= _level) {                                    \
-+            fprintf(stderr, "svc: " _fmt, ## __VA_ARGS__);              \
-+        }                                                               \
-+    } while (0)
-+
-+typedef struct SpiceVirtualChannel {
-+    VirtIOSerialPort      port;
-+    VMChangeStateEntry    *vmstate;
-+    SpiceVDIPortInstance  sin;
-+    bool                  active;
-+    uint8_t               *buffer;
-+    uint8_t               *datapos;
-+    ssize_t               bufsize, datalen;
-+    uint32_t              debug;
-+} SpiceVirtualChannel;
-+
-+static int vmc_write(SpiceVDIPortInstance *sin, const uint8_t *buf, int len)
-+{
-+    SpiceVirtualChannel *svc = container_of(sin, SpiceVirtualChannel, sin);
-+    ssize_t out;
-+
-+    out = virtio_serial_write(&svc->port, buf, len);
-+    dprintf(svc, 2, "%s: %lu/%d\n", __func__, out, len);
-+    return out;
-+}
-+
-+static int vmc_read(SpiceVDIPortInstance *sin, uint8_t *buf, int len)
-+{
-+    SpiceVirtualChannel *svc = container_of(sin, SpiceVirtualChannel, sin);
-+    int bytes = MIN(len, svc->datalen);
-+
-+    dprintf(svc, 2, "%s: %d/%zd\n", __func__, bytes, svc->datalen);
-+    if (bytes) {
-+        memcpy(buf, svc->datapos, bytes);
-+        svc->datapos += bytes;
-+        svc->datalen -= bytes;
-+        if (0 == svc->datalen) {
-+            virtio_serial_throttle_port(&svc->port, false);
-+        }
-+    }
-+    return bytes;
-+}
-+
-+static SpiceVDIPortInterface vmc_interface = {
-+    .base.type          = SPICE_INTERFACE_VDI_PORT,
-+    .base.description   = "spice virtual channel vdi port",
-+    .base.major_version = SPICE_INTERFACE_VDI_PORT_MAJOR,
-+    .base.minor_version = SPICE_INTERFACE_VDI_PORT_MINOR,
-+    .write              = vmc_write,
-+    .read               = vmc_read,
-+};
-+
-+static void vmc_register_interface(SpiceVirtualChannel *svc)
-+{
-+    if (svc->active) {
-+        return;
-+    }
-+    dprintf(svc, 1, "%s\n", __func__);
-+    svc->sin.base.sif = &vmc_interface.base;
-+    spice_server_add_interface(spice_server, &svc->sin.base);
-+    svc->active = true;
-+}
-+
-+static void vmc_unregister_interface(SpiceVirtualChannel *svc)
-+{
-+    if (!svc->active) {
-+        return;
-+    }
-+    dprintf(svc, 1, "%s\n", __func__);
-+    spice_server_remove_interface(&svc->sin.base);
-+    svc->active = false;
-+}
-+
-+
-+static void vmc_change_state_handler(void *opaque, int running, int reason)
-+{
-+    SpiceVirtualChannel *svc = opaque;
-+
-+    if (running && svc->active) {
-+        spice_server_vdi_port_wakeup(&svc->sin);
-+    }
-+}
-+
-+/*
-+ * virtio-serial callbacks
-+ */
-+
-+static void vmc_guest_open(VirtIOSerialPort *port)
-+{
-+    SpiceVirtualChannel *svc = DO_UPCAST(SpiceVirtualChannel, port, port);
-+
-+    dprintf(svc, 1, "%s\n", __func__);
-+    vmc_register_interface(svc);
-+}
-+
-+static void vmc_guest_close(VirtIOSerialPort *port)
-+{
-+    SpiceVirtualChannel *svc = DO_UPCAST(SpiceVirtualChannel, port, port);
-+
-+    dprintf(svc, 1, "%s\n", __func__);
-+    vmc_unregister_interface(svc);
-+}
-+
-+static void vmc_guest_ready(VirtIOSerialPort *port)
-+{
-+    SpiceVirtualChannel *svc = DO_UPCAST(SpiceVirtualChannel, port, port);
-+
-+    dprintf(svc, 1, "%s\n", __func__);
-+    if (svc->active)
-+        spice_server_vdi_port_wakeup(&svc->sin);
-+}
-+
-+static void vmc_have_data(VirtIOSerialPort *port, const uint8_t *buf, size_t len)
-+{
-+    SpiceVirtualChannel *svc = DO_UPCAST(SpiceVirtualChannel, port, port);
-+
-+    dprintf(svc, 2, "%s: %zd\n", __func__, len);
-+    assert(svc->datapos == 0);
-+    if (svc->bufsize < len) {
-+        svc->bufsize = len;
-+        svc->buffer = qemu_realloc(svc->buffer, svc->bufsize);
-+    }
-+    memcpy(svc->buffer, buf, len);
-+    svc->datapos = svc->buffer;
-+    svc->datalen = len;
-+    virtio_serial_throttle_port(&svc->port, true);
-+    spice_server_vdi_port_wakeup(&svc->sin);
-+}
-+
-+static int vmc_initfn(VirtIOSerialDevice *dev)
-+{
-+    VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev);
-+    SpiceVirtualChannel *svc = DO_UPCAST(SpiceVirtualChannel, port, port);
-+
-+    if (!using_spice)
-+        return -1;
-+
-+    dprintf(svc, 1, "%s\n", __func__);
-+    port->name = qemu_strdup(VMC_GUEST_DEVICE_NAME);
-+    svc->vmstate = qemu_add_vm_change_state_handler(
-+        vmc_change_state_handler, svc);
-+    virtio_serial_open(port);
-+    return 0;
-+}
-+
-+static int vmc_exitfn(VirtIOSerialDevice *dev)
-+{
-+    VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev);
-+    SpiceVirtualChannel *svc = DO_UPCAST(SpiceVirtualChannel, port, port);
-+
-+    dprintf(svc, 1, "%s\n", __func__);
-+    vmc_unregister_interface(svc);
-+    qemu_del_vm_change_state_handler(svc->vmstate);
-+    virtio_serial_close(port);
-+    return 0;
-+}
-+
-+static VirtIOSerialPortInfo vmc_info = {
-+    .qdev.name     = VMC_DEVICE_NAME,
-+    .qdev.size     = sizeof(SpiceVirtualChannel),
-+    .init          = vmc_initfn,
-+    .exit          = vmc_exitfn,
-+    .guest_open    = vmc_guest_open,
-+    .guest_close   = vmc_guest_close,
-+    .guest_ready   = vmc_guest_ready,
-+    .have_data     = vmc_have_data,
-+    .qdev.props = (Property[]) {
-+        DEFINE_PROP_UINT32("nr", SpiceVirtualChannel, port.id, VIRTIO_CONSOLE_BAD_ID),
-+        DEFINE_PROP_UINT32("debug", SpiceVirtualChannel, debug, 1),
-+        DEFINE_PROP_END_OF_LIST(),
-+    }
-+};
-+
-+static void vmc_register(void)
-+{
-+    virtio_serial_port_qdev_register(&vmc_info);
-+}
-+device_init(vmc_register)
--- 
-1.7.2.3
-
diff --git a/0017-spice-add-pci-vdi-port-backend-obsolete.patch b/0017-spice-add-pci-vdi-port-backend-obsolete.patch
deleted file mode 100644
index 6505bb7..0000000
--- a/0017-spice-add-pci-vdi-port-backend-obsolete.patch
+++ /dev/null
@@ -1,592 +0,0 @@
-From ee782dec6adaced9c5bb99d02253505fb635fa12 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Fri, 12 Mar 2010 16:26:18 +0100
-Subject: [PATCH 17/39] spice: add pci vdi port backend (obsolete).
-
-This is *not* intended to be merged upstream.  It is just here
-because the virtio-serial windows guest drivers are not ready,
-so you can't go with the new spice-vmc yet.
----
- Makefile.target |    2 +-
- hw/spice-vdi.c  |  556 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 557 insertions(+), 1 deletions(-)
- create mode 100644 hw/spice-vdi.c
-
-diff --git a/Makefile.target b/Makefile.target
-index 90544c5..025bdb8 100644
---- a/Makefile.target
-+++ b/Makefile.target
-@@ -217,7 +217,7 @@ obj-i386-y += pc_piix.o
- obj-i386-y += testdev.o
- obj-i386-y += acpi.o acpi_piix4.o
- obj-i386-$(CONFIG_SPICE) += qxl.o qxl-logger.o qxl-render.o
--obj-i386-$(CONFIG_SPICE) += spice-vmc.o
-+obj-i386-$(CONFIG_SPICE) += spice-vmc.o spice-vdi.o
-
- obj-i386-y += pcspk.o i8254.o
- obj-i386-$(CONFIG_KVM_PIT) += i8254-kvm.o
-diff --git a/hw/spice-vdi.c b/hw/spice-vdi.c
-new file mode 100644
-index 0000000..23cbbe1
---- /dev/null
-+++ b/hw/spice-vdi.c
-@@ -0,0 +1,556 @@
-+#include <pthread.h>
-+#include <signal.h>
-+
-+#include "qemu-common.h"
-+#include "qemu-spice.h"
-+#include "hw/hw.h"
-+#include "hw/pc.h"
-+#include "hw/pci.h"
-+#include "console.h"
-+#include "hw/vga_int.h"
-+#include "qemu-timer.h"
-+#include "sysemu.h"
-+#include "console.h"
-+#include "pci.h"
-+#include "hw.h"
-+#include "cpu-common.h"
-+
-+#include <spice.h>
-+#include <spice-experimental.h>
-+#include <spice/ipc_ring.h>
-+#include <spice/barrier.h>
-+
-+#undef SPICE_RING_PROD_ITEM
-+#define SPICE_RING_PROD_ITEM(r, ret) {                                  \
-+        typeof(r) start = r;                                            \
-+        typeof(r) end = r + 1;                                          \
-+        uint32_t prod = (r)->prod & SPICE_RING_INDEX_MASK(r);           \
-+        typeof(&(r)->items[prod]) m_item = &(r)->items[prod];           \
-+        if (!((uint8_t*)m_item >= (uint8_t*)(start) && (uint8_t*)(m_item + 1) <= (uint8_t*)(end))) { \
-+            abort();                                                    \
-+        }                                                               \
-+        ret = &m_item->el;                                              \
-+    }
-+
-+#undef SPICE_RING_CONS_ITEM
-+#define SPICE_RING_CONS_ITEM(r, ret) {                                  \
-+        typeof(r) start = r;                                            \
-+        typeof(r) end = r + 1;                                          \
-+        uint32_t cons = (r)->cons & SPICE_RING_INDEX_MASK(r);           \
-+        typeof(&(r)->items[cons]) m_item = &(r)->items[cons];           \
-+        if (!((uint8_t*)m_item >= (uint8_t*)(start) && (uint8_t*)(m_item + 1) <= (uint8_t*)(end))) { \
-+            abort();                                                    \
-+        }                                                               \
-+        ret = &m_item->el;                                              \
-+    }
-+
-+
-+#undef ALIGN
-+#define ALIGN(a, b) (((a) + ((b) - 1)) & ~((b) - 1))
-+
-+#define REDHAT_PCI_VENDOR_ID 0x1b36
-+#define VDI_PORT_DEVICE_ID 0x0105
-+#define VDI_PORT_REVISION 0x01
-+
-+#define VDI_PORT_INTERRUPT (1 << 0)
-+
-+#define VDI_PORT_MAGIC (*(uint32_t*)"VDIP")
-+
-+#define VDI_PORT_DEV_NAME "vdi_port"
-+#define VDI_PORT_SAVE_VERSION 20
-+
-+#include <spice/start-packed.h>
-+
-+typedef struct SPICE_ATTR_PACKED VDIPortPacket {
-+    uint32_t gen;
-+    uint32_t size;
-+    uint8_t data[512 - 2 * sizeof(uint32_t)];
-+} VDIPortPacket;
-+
-+SPICE_RING_DECLARE(VDIPortRing, VDIPortPacket, 32);
-+
-+enum {
-+    VDI_PORT_IO_RANGE_INDEX,
-+    VDI_PORT_RAM_RANGE_INDEX,
-+};
-+
-+enum {
-+    VDI_PORT_IO_CONNECTION,
-+    VDI_PORT_IO_NOTIFY = 4,
-+    VDI_PORT_IO_UPDATE_IRQ = 8,
-+
-+    VDI_PORT_IO_RANGE_SIZE = 12
-+};
-+
-+typedef struct SPICE_ATTR_PACKED VDIPortRam {
-+    uint32_t magic;
-+    uint32_t generation;
-+    uint32_t int_pending;
-+    uint32_t int_mask;
-+    VDIPortRing input;
-+    VDIPortRing output;
-+    uint32_t reserv[32];
-+} VDIPortRam;
-+
-+#include <spice/end-packed.h>
-+
-+typedef struct PCIVDIPortDevice {
-+    PCIDevice pci_dev;
-+    uint32_t io_base;
-+    uint64_t ram_offset;
-+    uint32_t ram_size;
-+    VDIPortRam *ram;
-+    uint32_t connected;
-+    int running;
-+    int new_gen_on_resume;
-+    int active_interface;
-+    SpiceVDIPortInstance sin;
-+    int plug_read_pos;
-+} PCIVDIPortDevice;
-+
-+static int debug = 1;
-+
-+static inline uint32_t msb_mask(uint32_t val)
-+{
-+    uint32_t mask;
-+
-+    do {
-+        mask = ~(val - 1) & val;
-+        val &= ~mask;
-+    } while (mask < val);
-+
-+    return mask;
-+}
-+
-+static inline void atomic_or(uint32_t *var, uint32_t add)
-+{
-+   __asm__ __volatile__ ("lock; orl %1, %0" : "+m" (*var) : "r" (add) : "memory");
-+}
-+
-+static inline uint32_t atomic_exchange(uint32_t val, uint32_t *ptr)
-+{
-+   __asm__ __volatile__("xchgl %0, %1" : "+q"(val), "+m" (*ptr) : : "memory");
-+   return val;
-+}
-+
-+static void set_dirty(void *base, ram_addr_t offset, void *start, uint32_t length)
-+{
-+    assert(start >= base);
-+
-+    ram_addr_t addr =  (ram_addr_t)((uint8_t*)start - (uint8_t*)base) + offset;
-+    ram_addr_t end =  ALIGN(addr + length, TARGET_PAGE_SIZE);
-+
-+    do {
-+        cpu_physical_memory_set_dirty(addr);
-+        addr += TARGET_PAGE_SIZE;
-+    } while ( addr < end );
-+}
-+
-+static inline void vdi_port_set_dirty(PCIVDIPortDevice *d, void *start, uint32_t length)
-+{
-+    set_dirty(d->ram, d->ram_offset, start, length);
-+}
-+
-+static void vdi_port_new_gen(PCIVDIPortDevice *d)
-+{
-+    d->ram->generation = (d->ram->generation + 1 == 0) ? 1 : d->ram->generation + 1;
-+    vdi_port_set_dirty(d, &d->ram->generation, sizeof(d->ram->generation));
-+}
-+
-+static int vdi_port_irq_level(PCIVDIPortDevice *d)
-+{
-+    return !!(d->ram->int_pending & d->ram->int_mask);
-+}
-+
-+static void vdi_port_notify_guest(PCIVDIPortDevice *d)
-+{
-+    uint32_t events = VDI_PORT_INTERRUPT;
-+    uint32_t old_pending;
-+
-+    if (!d->connected) {
-+        return;
-+    }
-+    old_pending = __sync_fetch_and_or(&d->ram->int_pending, events);
-+    if ((old_pending & events) == events) {
-+        return;
-+    }
-+    qemu_set_irq(d->pci_dev.irq[0], vdi_port_irq_level(d));
-+    vdi_port_set_dirty(d, &d->ram->int_pending, sizeof(d->ram->int_pending));
-+}
-+
-+static int vdi_port_interface_write(SpiceVDIPortInstance *sin,
-+                                    const uint8_t *buf, int len)
-+{
-+    PCIVDIPortDevice *d = container_of(sin, PCIVDIPortDevice, sin);
-+    VDIPortRing *ring = &d->ram->output;
-+    int do_notify = false;
-+    int actual_write = 0;
-+    int l = len;
-+
-+    if (!d->running) {
-+        return 0;
-+    }
-+
-+    while (len) {
-+        VDIPortPacket *packet;
-+        int notify;
-+        int wait;
-+
-+        SPICE_RING_PROD_WAIT(ring, wait);
-+        if (wait) {
-+            break;
-+        }
-+
-+        SPICE_RING_PROD_ITEM(ring, packet);
-+        packet->gen = d->ram->generation;
-+        packet->size = MIN(len, sizeof(packet->data));
-+        memcpy(packet->data, buf, packet->size);
-+        vdi_port_set_dirty(d, packet, sizeof(*packet) - (sizeof(packet->data) - packet->size));
-+
-+        SPICE_RING_PUSH(ring, notify);
-+        do_notify = do_notify || notify;
-+        len -= packet->size;
-+        buf += packet->size;
-+        actual_write += packet->size;
-+    }
-+    vdi_port_set_dirty(d, ring, sizeof(*ring) - sizeof(ring->items));
-+
-+    if (do_notify) {
-+        vdi_port_notify_guest(d);
-+    }
-+    if (debug > 1) {
-+        fprintf(stderr, "%s: %d/%d\n", __FUNCTION__, actual_write, l);
-+    }
-+    return actual_write;
-+}
-+
-+static int vdi_port_interface_read(SpiceVDIPortInstance *sin,
-+                                   uint8_t *buf, int len)
-+{
-+    PCIVDIPortDevice *d = container_of(sin, PCIVDIPortDevice, sin);
-+    VDIPortRing *ring = &d->ram->input;
-+    uint32_t gen = d->ram->generation;
-+    VDIPortPacket *packet;
-+    int do_notify = false;
-+    int actual_read = 0;
-+    int l = len;
-+
-+    if (!d->running) {
-+        return 0;
-+    }
-+
-+    while (!SPICE_RING_IS_EMPTY(ring)) {
-+        int notify;
-+
-+        SPICE_RING_CONS_ITEM(ring, packet);
-+        if (packet->gen == gen) {
-+            break;
-+        }
-+        SPICE_RING_POP(ring, notify);
-+        do_notify = do_notify || notify;
-+    }
-+    while (len) {
-+        VDIPortPacket *packet;
-+        int wait;
-+        int now;
-+
-+        SPICE_RING_CONS_WAIT(ring, wait);
-+
-+        if (wait) {
-+            break;
-+        }
-+
-+        SPICE_RING_CONS_ITEM(ring, packet);
-+        if (packet->size > sizeof(packet->data)) {
-+            vdi_port_set_dirty(d, ring, sizeof(*ring) - sizeof(ring->items));
-+            printf("%s: bad packet size\n", __FUNCTION__);
-+            return 0;
-+        }
-+        now = MIN(len, packet->size - d->plug_read_pos);
-+        memcpy(buf, packet->data + d->plug_read_pos, now);
-+        len -= now;
-+        buf += now;
-+        actual_read +=  now;
-+        if ((d->plug_read_pos += now) == packet->size) {
-+            int notify;
-+
-+            d->plug_read_pos = 0;
-+            SPICE_RING_POP(ring, notify);
-+            do_notify = do_notify || notify;
-+        }
-+    }
-+    vdi_port_set_dirty(d, ring, sizeof(*ring) - sizeof(ring->items));
-+
-+    if (do_notify) {
-+        vdi_port_notify_guest(d);
-+    }
-+    if (debug > 1) {
-+        fprintf(stderr, "%s: %d/%d\n", __FUNCTION__, actual_read, l);
-+    }
-+    return actual_read;
-+}
-+
-+static SpiceVDIPortInterface vdi_port_interface = {
-+    .base.type          = SPICE_INTERFACE_VDI_PORT,
-+    .base.description   = "vdi port",
-+    .base.major_version = SPICE_INTERFACE_VDI_PORT_MAJOR,
-+    .base.minor_version = SPICE_INTERFACE_VDI_PORT_MINOR,
-+
-+    .write              = vdi_port_interface_write,
-+    .read               = vdi_port_interface_read,
-+};
-+
-+static void vdi_port_register_interface(PCIVDIPortDevice *d)
-+{
-+    if (d->active_interface ) {
-+        return;
-+    }
-+
-+    if (debug) {
-+        fprintf(stderr, "%s\n", __FUNCTION__);
-+    }
-+    d->sin.base.sif = &vdi_port_interface.base;
-+    spice_server_add_interface(spice_server, &d->sin.base);
-+    d->active_interface = true;
-+}
-+
-+static void vdi_port_unregister_interface(PCIVDIPortDevice *d)
-+{
-+    if (!d->active_interface ) {
-+        return;
-+    }
-+    if (debug) {
-+        fprintf(stderr, "%s\n", __FUNCTION__);
-+    }
-+    spice_server_remove_interface(&d->sin.base);
-+    d->active_interface = false;
-+}
-+
-+static uint32_t vdi_port_dev_connect(PCIVDIPortDevice *d)
-+{
-+    if (d->connected) {
-+        if (debug) {
-+            fprintf(stderr, "%s: already connected\n", __FUNCTION__);
-+        }
-+        return 0;
-+    }
-+    vdi_port_new_gen(d);
-+    d->connected = true;
-+    vdi_port_register_interface(d);
-+    return d->ram->generation;
-+}
-+
-+static void vdi_port_dev_disconnect(PCIVDIPortDevice *d)
-+{
-+    if (!d->connected) {
-+        if (debug) {
-+            fprintf(stderr, "%s: not connected\n", __FUNCTION__);
-+        }
-+        return;
-+    }
-+    d->connected = false;
-+    vdi_port_unregister_interface(d);
-+}
-+
-+static void vdi_port_dev_notify(PCIVDIPortDevice *d)
-+{
-+    spice_server_vdi_port_wakeup(&d->sin);
-+}
-+
-+static void vdi_port_write_dword(void *opaque, uint32_t addr, uint32_t val)
-+{
-+    PCIVDIPortDevice *d = opaque;
-+    uint32_t io_port = addr - d->io_base;
-+
-+    if (debug > 1) {
-+        fprintf(stderr, "%s: addr 0x%x val 0x%x\n", __FUNCTION__, addr, val);
-+    }
-+    switch (io_port) {
-+    case VDI_PORT_IO_NOTIFY:
-+        if (!d->connected) {
-+            fprintf(stderr, "%s: not connected\n", __FUNCTION__);
-+            return;
-+        }
-+        vdi_port_dev_notify(d);
-+        break;
-+    case VDI_PORT_IO_UPDATE_IRQ:
-+        qemu_set_irq(d->pci_dev.irq[0], vdi_port_irq_level(d));
-+        break;
-+    case VDI_PORT_IO_CONNECTION:
-+        vdi_port_dev_disconnect(d);
-+        break;
-+    default:
-+        if (debug) {
-+            fprintf(stderr, "%s: unexpected addr 0x%x val 0x%x\n",
-+                    __FUNCTION__, addr, val);
-+        }
-+    };
-+}
-+
-+static uint32_t vdi_port_read_dword(void *opaque, uint32_t addr)
-+{
-+    PCIVDIPortDevice *d = opaque;
-+    uint32_t io_port = addr - d->io_base;
-+
-+    if (debug > 1) {
-+        fprintf(stderr, "%s: addr 0x%x\n", __FUNCTION__, addr);
-+    }
-+    if (io_port == VDI_PORT_IO_CONNECTION) {
-+        return vdi_port_dev_connect(d);
-+    } else {
-+        fprintf(stderr, "%s: unexpected addr 0x%x\n", __FUNCTION__, addr);
-+    }
-+    return 0xffffffff;
-+}
-+
-+static void vdi_port_io_map(PCIDevice *pci_dev, int region_num,
-+                            pcibus_t addr, pcibus_t size, int type)
-+{
-+    PCIVDIPortDevice *d = DO_UPCAST(PCIVDIPortDevice, pci_dev, pci_dev);
-+
-+    if (debug) {
-+        fprintf(stderr, "%s: base 0x%lx size 0x%lx\n", __FUNCTION__, addr, size);
-+    }
-+    d->io_base = addr;
-+    register_ioport_write(addr, size, 4, vdi_port_write_dword, pci_dev);
-+    register_ioport_read(addr, size, 4, vdi_port_read_dword, pci_dev);
-+}
-+
-+static void vdi_port_ram_map(PCIDevice *pci_dev, int region_num,
-+                             pcibus_t addr, pcibus_t size, int type)
-+{
-+    PCIVDIPortDevice *d = DO_UPCAST(PCIVDIPortDevice, pci_dev, pci_dev);
-+
-+    if (debug) {
-+        fprintf(stderr, "%s: addr 0x%lx size 0x%lx\n", __FUNCTION__, addr, size);
-+    }
-+
-+    assert((addr & (size - 1)) == 0);
-+    assert(size ==  d->ram_size);
-+
-+    cpu_register_physical_memory(addr, size, d->ram_offset | IO_MEM_RAM);
-+}
-+
-+static void vdi_port_reset(PCIVDIPortDevice *d)
-+{
-+    memset(d->ram, 0, sizeof(*d->ram));
-+    SPICE_RING_INIT(&d->ram->input);
-+    SPICE_RING_INIT(&d->ram->output);
-+    d->ram->magic = VDI_PORT_MAGIC;
-+    d->ram->generation = 0;
-+    d->ram->int_pending = 0;
-+    d->ram->int_mask = 0;
-+    d->connected = false;
-+    d->plug_read_pos = 0;
-+    vdi_port_set_dirty(d, d->ram, sizeof(*d->ram));
-+}
-+
-+static void vdi_port_reset_handler(DeviceState *dev)
-+{
-+    PCIVDIPortDevice *d = DO_UPCAST(PCIVDIPortDevice, pci_dev.qdev, dev);
-+
-+    if (d->connected) {
-+        vdi_port_dev_disconnect(d);
-+    }
-+
-+    vdi_port_reset(d);
-+    qemu_set_irq(d->pci_dev.irq[0], vdi_port_irq_level(d));
-+}
-+
-+static int vdi_port_pre_load(void* opaque)
-+{
-+    PCIVDIPortDevice* d = opaque;
-+
-+    vdi_port_unregister_interface(d);
-+    return 0;
-+}
-+
-+static int vdi_port_post_load(void* opaque,int version_id)
-+{
-+    PCIVDIPortDevice* d = opaque;
-+
-+    if (d->connected) {
-+        vdi_port_register_interface(d);
-+    }
-+    return 0;
-+}
-+
-+static void vdi_port_vm_change_state_handler(void *opaque, int running, int reason)
-+{
-+    PCIVDIPortDevice* d = opaque;
-+
-+    if (running) {
-+        d->running = true;
-+        if (d->new_gen_on_resume) {
-+            d->new_gen_on_resume = false;
-+            vdi_port_new_gen(d);
-+            vdi_port_notify_guest(d);
-+        }
-+        qemu_set_irq(d->pci_dev.irq[0], vdi_port_irq_level(d));
-+        vdi_port_dev_notify(d);
-+    } else {
-+        d->running = false;
-+    }
-+}
-+
-+static int vdi_port_init(PCIDevice *dev)
-+{
-+    PCIVDIPortDevice *vdi = (PCIVDIPortDevice *)dev;
-+    uint8_t* config = vdi->pci_dev.config;
-+    uint32_t ram_size = msb_mask(sizeof(VDIPortRam) * 2 - 1);
-+
-+    vdi->ram_offset = qemu_ram_alloc(&vdi->pci_dev.qdev, "bar1", ram_size);
-+    vdi->ram = qemu_get_ram_ptr(vdi->ram_offset);
-+    vdi_port_reset(vdi);
-+    vdi->ram_size = ram_size;
-+    vdi->new_gen_on_resume = false;
-+    vdi->running = false;
-+
-+    pci_config_set_vendor_id(config, REDHAT_PCI_VENDOR_ID);
-+    pci_config_set_device_id(config, VDI_PORT_DEVICE_ID);
-+    pci_config_set_class(config, PCI_CLASS_COMMUNICATION_OTHER);
-+    pci_set_byte(&config[PCI_REVISION_ID], VDI_PORT_REVISION);
-+    pci_set_byte(&config[PCI_INTERRUPT_PIN], 1);
-+
-+    pci_register_bar(dev, VDI_PORT_IO_RANGE_INDEX,
-+                     msb_mask(VDI_PORT_IO_RANGE_SIZE * 2 - 1),
-+                     PCI_BASE_ADDRESS_SPACE_IO, vdi_port_io_map);
-+
-+    pci_register_bar(dev, VDI_PORT_RAM_RANGE_INDEX,
-+                     vdi->ram_size , PCI_BASE_ADDRESS_SPACE_MEMORY,
-+                     vdi_port_ram_map);
-+
-+    qemu_add_vm_change_state_handler(vdi_port_vm_change_state_handler, vdi);
-+
-+    return 0;
-+}
-+
-+static VMStateDescription vdi_port_vmstate = {
-+    .name = VDI_PORT_DEV_NAME,
-+    .version_id = VDI_PORT_SAVE_VERSION,
-+    .minimum_version_id = VDI_PORT_SAVE_VERSION,
-+    .pre_load = vdi_port_pre_load,
-+    .post_load = vdi_port_post_load,
-+    .fields = (VMStateField []) {
-+        VMSTATE_PCI_DEVICE(pci_dev, PCIVDIPortDevice),
-+        VMSTATE_UINT32(connected, PCIVDIPortDevice),
-+        VMSTATE_END_OF_LIST()
-+    }
-+};
-+
-+static PCIDeviceInfo vdi_port_info = {
-+    .qdev.name = VDI_PORT_DEV_NAME,
-+    .qdev.desc = "spice virtual desktop port (obsolete)",
-+    .qdev.size = sizeof(PCIVDIPortDevice),
-+    .qdev.vmsd = &vdi_port_vmstate,
-+    .qdev.reset = vdi_port_reset_handler,
-+
-+    .init = vdi_port_init,
-+};
-+
-+static void vdi_port_register(void)
-+{
-+    pci_qdev_register(&vdi_port_info);
-+}
-+
-+device_init(vdi_port_register);
--- 
-1.7.2.3
-
diff --git a/0018-use-memalign-instead-of-posix_memalign.patch b/0018-use-memalign-instead-of-posix_memalign.patch
deleted file mode 100644
index d7264c4..0000000
--- a/0018-use-memalign-instead-of-posix_memalign.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 898303cfd535d76ce971f3ac1310696937fbd286 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Mon, 14 Jun 2010 09:53:48 +0200
-Subject: [PATCH 18/39] use memalign instead of posix_memalign
-
----
- osdep.c |    5 +++++
- 1 files changed, 5 insertions(+), 0 deletions(-)
-
-diff --git a/osdep.c b/osdep.c
-index 2375a69..ed2fd40 100644
---- a/osdep.c
-+++ b/osdep.c
-@@ -100,7 +100,12 @@ void *qemu_memalign(size_t alignment, size_t size)
- #if defined(_POSIX_C_SOURCE) && !defined(__sun__)
-     int ret;
-     void *ptr;
-+#if 0
-     ret = posix_memalign(&ptr, alignment, size);
-+#else
-+    ptr = memalign(alignment, size);
-+    ret = (ptr == NULL) ? -1 : 0;
-+#endif
-     if (ret != 0) {
-         fprintf(stderr, "Failed to allocate %zu B: %s\n",
-                 size, strerror(ret));
--- 
-1.7.2.3
-
diff --git a/0019-spice-live-migration-wip.patch b/0019-spice-live-migration-wip.patch
deleted file mode 100644
index 4e6ef6b..0000000
--- a/0019-spice-live-migration-wip.patch
+++ /dev/null
@@ -1,179 +0,0 @@
-From 80b1dac2be1487d31e6766abe2359fcff1bf0481 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Fri, 23 Apr 2010 13:28:21 +0200
-Subject: [PATCH 19/39] spice: live migration (wip).
-
-Handle spice client migration, i.e. inform a spice client connected
-about the new host and connection parameters, so it can move over the
-connection automatically.
----
- monitor.c       |    1 +
- qemu-monitor.hx |   11 +++++++
- qemu-spice.h    |    2 +
- spice.c         |   87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
- 4 files changed, 101 insertions(+), 0 deletions(-)
-
-diff --git a/monitor.c b/monitor.c
-index e51df62..6674a8c 100644
---- a/monitor.c
-+++ b/monitor.c
-@@ -57,6 +57,7 @@
- #include "osdep.h"
- #include "exec-all.h"
- #include "qemu-kvm.h"
-+#include "qemu-spice.h"
-
- //#define DEBUG
- //#define DEBUG_COMPLETION
-diff --git a/qemu-monitor.hx b/qemu-monitor.hx
-index da7b796..c2570d9 100644
---- a/qemu-monitor.hx
-+++ b/qemu-monitor.hx
-@@ -2510,6 +2510,17 @@ ETEXI
-
- HXCOMM DO NOT add new commands after 'info', move your addition before it!
-
-+#if defined(CONFIG_SPICE)
-+    {
-+        .name       = "spice_migrate_info",
-+        .args_type  = "hostname:s,port:i?,tls-port:i?,cert-subject:s?",
-+        .params     = "hostname port tls-port cert-subject",
-+        .help       = "send migration info to spice client",
-+	.user_print = monitor_user_noop,
-+        .mhandler.cmd_new = mon_spice_migrate,
-+    },
-+#endif
-+
- STEXI
- @end table
- ETEXI
-diff --git a/qemu-spice.h b/qemu-spice.h
-index 6f19ba7..3c8e959 100644
---- a/qemu-spice.h
-+++ b/qemu-spice.h
-@@ -16,6 +16,8 @@ void qemu_spice_input_init(void);
- void qemu_spice_audio_init(void);
- void qemu_spice_display_init(DisplayState *ds);
-
-+int mon_spice_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data);
-+
- #else  /* CONFIG_SPICE */
-
- #define using_spice 0
-diff --git a/spice.c b/spice.c
-index fc76ef7..1109b4f 100644
---- a/spice.c
-+++ b/spice.c
-@@ -11,6 +11,7 @@
- #include "qemu-queue.h"
- #include "qemu-x509.h"
- #include "monitor.h"
-+#include "hw/hw.h"
-
- /* core bits */
-
-@@ -122,8 +123,90 @@ static SpiceCoreInterface core_interface = {
-     .watch_remove       = watch_remove,
- };
-
-+/* handle client migration */
-+
-+static int spice_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
-+{
-+    static int last_stage;
-+    static int migrate_client, client_connected;
-+    int ret = 1;
-+
-+    if (last_stage != stage) {
-+        last_stage = stage;
-+        fprintf(stderr, "%s: stage %d\n", __FUNCTION__, stage);
-+    } else {
-+        fprintf(stderr, ".");
-+    }
-+
-+    switch (stage) {
-+    case 1:
-+        migrate_client = 1;
-+        client_connected = 0;
-+        fprintf(stderr, "%s: start client migration\n", __FUNCTION__);
-+        if (spice_server_migrate_start(spice_server) != 0) {
-+            fprintf(stderr, "%s: fail -> no client migration\n", __FUNCTION__);
-+            migrate_client = 0;
-+        }
-+        break;
-+    case 2:
-+        if (!migrate_client)
-+            break;
-+        switch (spice_server_migrate_client_state(spice_server)) {
-+        case SPICE_MIGRATE_CLIENT_NONE:
-+            fprintf(stderr, "%s: no client connected\n", __FUNCTION__);
-+            migrate_client = 0;
-+            break;
-+        case SPICE_MIGRATE_CLIENT_WAITING:
-+            ret = 0;
-+            break;
-+        case SPICE_MIGRATE_CLIENT_READY:
-+            if (!client_connected) {
-+                fprintf(stderr, "%s: client connected to target\n", __FUNCTION__);
-+                client_connected = 1;
-+            }
-+            break;
-+        }
-+        break;
-+    case 3:
-+        if (migrate_client && client_connected) {
-+            fprintf(stderr, "%s: finish client migration\n", __FUNCTION__);
-+            spice_server_migrate_end(spice_server, 1);
-+        }
-+        break;
-+    }
-+    return ret;
-+}
-+
-+static void spice_save(QEMUFile *f, void *opaque)
-+{
-+    fprintf(stderr, "%s:\n", __FUNCTION__);
-+}
-+
-+static int spice_load(QEMUFile *f, void *opaque, int version_id)
-+{
-+    fprintf(stderr, "%s:\n", __FUNCTION__);
-+    return 0;
-+}
-+
- /* functions for the rest of qemu */
-
-+int mon_spice_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data)
-+{
-+    const char *hostname = qdict_get_str(qdict, "hostname");
-+    const char *subject  = qdict_get_try_str(qdict, "cert-subject");
-+    int port             = qdict_get_try_int(qdict, "port", -1);
-+    int tls_port         = qdict_get_try_int(qdict, "tls-port", -1);
-+
-+    if (!spice_server) {
-+        qerror_report(QERR_DEVICE_NOT_ACTIVE, "spice");
-+        return -1;
-+    }
-+
-+    /* TODO: Convert to QError */
-+    return spice_server_migrate_info(spice_server, hostname,
-+                                     port, tls_port, subject);
-+}
-+
- void qemu_spice_init(void)
- {
-     QemuOpts *opts = QTAILQ_FIRST(&qemu_spice_opts.head);
-@@ -206,6 +289,10 @@ void qemu_spice_init(void)
-     qemu_spice_input_init();
-     qemu_spice_audio_init();
-
-+    register_savevm_live(NULL, "spice", -1, 1, NULL,
-+                         spice_live, spice_save, spice_load,
-+                         spice_server);
-+
-     qemu_free(x509_key_file);
-     qemu_free(x509_cert_file);
-     qemu_free(x509_cacert_file);
--- 
-1.7.2.3
-
diff --git a/0020-spice-display-draw.h-is-internal-now.patch b/0020-spice-display-draw.h-is-internal-now.patch
deleted file mode 100644
index e734447..0000000
--- a/0020-spice-display-draw.h-is-internal-now.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From 7241cc479a0f4a148ae60336add6d7be80da9ff0 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Thu, 8 Jul 2010 14:11:18 +0200
-Subject: [PATCH 20/39] spice-display: draw.h is internal now
-
----
- spice-display.h |    2 +-
- 1 files changed, 1 insertions(+), 1 deletions(-)
-
-diff --git a/spice-display.h b/spice-display.h
-index 70a7be4..b55e7ea 100644
---- a/spice-display.h
-+++ b/spice-display.h
-@@ -1,5 +1,5 @@
- #include <spice/ipc_ring.h>
--#include <spice/draw.h>
-+#include <spice/enums.h>
- #include <spice/qxl_dev.h>
-
- #include "pflib.h"
--- 
-1.7.2.3
-
diff --git a/0021-spice-display-disable-debug.patch b/0021-spice-display-disable-debug.patch
deleted file mode 100644
index bdaee85..0000000
--- a/0021-spice-display-disable-debug.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From c269c8b87769b25c9d69d40944de0e883458af86 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Thu, 8 Jul 2010 14:31:10 +0200
-Subject: [PATCH 21/39] spice-display: disable debug
-
----
- spice-display.c |    2 +-
- 1 files changed, 1 insertions(+), 1 deletions(-)
-
-diff --git a/spice-display.c b/spice-display.c
-index a749e64..2291cc7 100644
---- a/spice-display.c
-+++ b/spice-display.c
-@@ -15,7 +15,7 @@
-
- #include "spice-display.h"
-
--static int debug = 1;
-+static int debug = 0;
-
- int qemu_spice_rect_is_empty(const QXLRect* r)
- {
--- 
-1.7.2.3
-
diff --git a/0022-spice-display-pci-rev-fixups.patch b/0022-spice-display-pci-rev-fixups.patch
deleted file mode 100644
index 87534af..0000000
--- a/0022-spice-display-pci-rev-fixups.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 2912f038b4bfddd4c3dacb3b0102e45553859632 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Thu, 8 Jul 2010 16:29:15 +0200
-Subject: [PATCH 22/39] spice-display: pci rev fixups
-
----
- spice-display.c |    4 ----
- 1 files changed, 0 insertions(+), 4 deletions(-)
-
-diff --git a/spice-display.c b/spice-display.c
-index 2291cc7..87a71cd 100644
---- a/spice-display.c
-+++ b/spice-display.c
-@@ -334,10 +334,6 @@ static const QXLInterface dpy_interface = {
-     .base.major_version      = SPICE_INTERFACE_QXL_MAJOR,
-     .base.minor_version      = SPICE_INTERFACE_QXL_MINOR,
-
--    .pci_vendor              = REDHAT_PCI_VENDOR_ID,
--    .pci_id                  = QXL_DEVICE_ID,
--    .pci_revision            = QXL_REVISION,
--
-     .attache_worker          = interface_attach_worker,
-     .set_compression_level   = interface_set_compression_level,
-     .set_mm_time             = interface_set_mm_time,
--- 
-1.7.2.3
-
diff --git a/0023-qxl-pci-rev-fixups.patch b/0023-qxl-pci-rev-fixups.patch
deleted file mode 100644
index 5a9fc24..0000000
--- a/0023-qxl-pci-rev-fixups.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From 727553e1a33dccab2b27ee5e184e003440765289 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Thu, 8 Jul 2010 16:29:27 +0200
-Subject: [PATCH 23/39] qxl: pci rev fixups
-
----
- hw/qxl.c |   20 ++++++++------------
- 1 files changed, 8 insertions(+), 12 deletions(-)
-
-diff --git a/hw/qxl.c b/hw/qxl.c
-index 475360c..2a0ea4e 100644
---- a/hw/qxl.c
-+++ b/hw/qxl.c
-@@ -511,10 +511,6 @@ static const QXLInterface qxl_interface = {
-     .base.major_version      = SPICE_INTERFACE_QXL_MAJOR,
-     .base.minor_version      = SPICE_INTERFACE_QXL_MINOR,
-
--    .pci_vendor              = REDHAT_PCI_VENDOR_ID,
--    .pci_id                  = QXL_DEVICE_ID,
--    .pci_revision            = QXL_REVISION,
--
-     .attache_worker          = interface_attach_worker,
-     .set_compression_level   = interface_set_compression_level,
-     .set_mm_time             = interface_set_mm_time,
-@@ -1136,16 +1132,16 @@ static int qxl_init(PCIDevice *dev)
-     qxl->generation = 1;
-
-     switch (qxl->revision) {
--    case 1: /* qxl-1 */
--        pci_device_id  = 0x0100;
--        pci_device_rev = 1;
-+    case 1: /* spice 0.4 -- qxl-1 */
-+        pci_device_id  = QXL_DEVICE_ID_STABLE;
-+        pci_device_rev = QXL_REVISION_STABLE_V04;
-         break;
--    case 2: /* qxl-2 */
--        pci_device_id  = 0x0100;
--        pci_device_rev = 2;
-+    case 2: /* spice 0.6 -- qxl-2 */
-+        pci_device_id  = QXL_DEVICE_ID_STABLE;
-+        pci_device_rev = QXL_REVISION_STABLE_V06;
-         break;
--    default: /* unstable */
--        pci_device_id  = 0x01ff;
-+    default: /* experimental */
-+        pci_device_id  = QXL_DEVICE_ID_DEVEL;
-         pci_device_rev = 1;
-         break;
-     }
--- 
-1.7.2.3
-
diff --git a/0024-qxl-support-QXL_IO_DESTROY_ALL_SURFACES.patch b/0024-qxl-support-QXL_IO_DESTROY_ALL_SURFACES.patch
deleted file mode 100644
index 07882f3..0000000
--- a/0024-qxl-support-QXL_IO_DESTROY_ALL_SURFACES.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From c9f9044475d392e55de4dd6e343477ce1a57eabc Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Thu, 8 Jul 2010 17:51:09 +0200
-Subject: [PATCH 24/39] qxl: support QXL_IO_DESTROY_ALL_SURFACES
-
----
- hw/qxl.c |    3 +++
- 1 files changed, 3 insertions(+), 0 deletions(-)
-
-diff --git a/hw/qxl.c b/hw/qxl.c
-index 2a0ea4e..7bd4467 100644
---- a/hw/qxl.c
-+++ b/hw/qxl.c
-@@ -930,6 +930,9 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
-     case QXL_IO_DESTROY_SURFACE_WAIT:
-         d->ssd.worker->destroy_surface_wait(d->ssd.worker, val);
-         break;
-+    case QXL_IO_DESTROY_ALL_SURFACES:
-+        d->ssd.worker->destroy_surfaces(d->ssd.worker);
-+        break;
-     default:
-         fprintf(stderr, "%s: ioport=0x%x, abort()\n", __FUNCTION__, io_port);
-         abort();
--- 
-1.7.2.3
-
diff --git a/0025-spice-vmc-two-bugfixes-in-vmc_read.patch b/0025-spice-vmc-two-bugfixes-in-vmc_read.patch
deleted file mode 100644
index 3b4178b..0000000
--- a/0025-spice-vmc-two-bugfixes-in-vmc_read.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From c8fa37e075cf59e8b21af9211f6a6348c92ed098 Mon Sep 17 00:00:00 2001
-From: Alon Levy <alevy@redhat.com>
-Date: Mon, 12 Jul 2010 22:48:59 +0300
-Subject: [PATCH 25/39] spice-vmc: two bugfixes in vmc_read
-
- * throttling with no discard means possible recursion, make
-  vmc_read handle that.
- * zero datapos when data is done (from rhel6 version)
----
- hw/spice-vmc.c |   13 ++++++++-----
- 1 files changed, 8 insertions(+), 5 deletions(-)
-
-diff --git a/hw/spice-vmc.c b/hw/spice-vmc.c
-index 3f6a2bb..06e30e6 100644
---- a/hw/spice-vmc.c
-+++ b/hw/spice-vmc.c
-@@ -45,7 +45,7 @@ static int vmc_write(SpiceVDIPortInstance *sin, const uint8_t *buf, int len)
-     ssize_t out;
-
-     out = virtio_serial_write(&svc->port, buf, len);
--    dprintf(svc, 2, "%s: %lu/%d\n", __func__, out, len);
-+    dprintf(svc, 3, "%s: %lu/%d\n", __func__, out, len);
-     return out;
- }
-
-@@ -54,13 +54,16 @@ static int vmc_read(SpiceVDIPortInstance *sin, uint8_t *buf, int len)
-     SpiceVirtualChannel *svc = container_of(sin, SpiceVirtualChannel, sin);
-     int bytes = MIN(len, svc->datalen);
-
--    dprintf(svc, 2, "%s: %d/%zd\n", __func__, bytes, svc->datalen);
--    if (bytes) {
-+    dprintf(svc, 2, "%s: %p %d/%d/%zd\n", __func__, svc->datapos, len, bytes, svc->datalen);
-+    if (bytes > 0) {
-         memcpy(buf, svc->datapos, bytes);
-         svc->datapos += bytes;
-         svc->datalen -= bytes;
--        if (0 == svc->datalen) {
-+        assert(svc->datalen >= 0);
-+        if (svc->datalen == 0) {
-+            svc->datapos = 0;
-             virtio_serial_throttle_port(&svc->port, false);
-+            // ^^^ !!! may call vmc_have_data, so don't touch svc after it!
-         }
-     }
-     return bytes;
-@@ -140,7 +143,7 @@ static void vmc_have_data(VirtIOSerialPort *port, const uint8_t *buf, size_t len
-     SpiceVirtualChannel *svc = DO_UPCAST(SpiceVirtualChannel, port, port);
-
-     dprintf(svc, 2, "%s: %zd\n", __func__, len);
--    assert(svc->datapos == 0);
-+    assert(svc->datalen == 0);
-     if (svc->bufsize < len) {
-         svc->bufsize = len;
-         svc->buffer = qemu_realloc(svc->buffer, svc->bufsize);
--- 
-1.7.2.3
-
diff --git a/0026-spice-enabling-disabling-jpeg-and-zlib-over-glz-via-.patch b/0026-spice-enabling-disabling-jpeg-and-zlib-over-glz-via-.patch
deleted file mode 100644
index 0af9bae..0000000
--- a/0026-spice-enabling-disabling-jpeg-and-zlib-over-glz-via-.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From 0045574847883167f5c2b569811e049616ee611d Mon Sep 17 00:00:00 2001
-From: Yonit Halperin <yhalperi@redhat.com>
-Date: Wed, 14 Jul 2010 13:26:34 +0300
-Subject: [PATCH 26/39] spice: enabling/disabling jpeg and zlib-over-glz via spice command line args
-
----
- qemu-config.c |    6 ++++++
- spice.c       |   29 +++++++++++++++++++++++++++++
- 2 files changed, 35 insertions(+), 0 deletions(-)
-
-diff --git a/qemu-config.c b/qemu-config.c
-index 74bfc62..3e4fcf9 100644
---- a/qemu-config.c
-+++ b/qemu-config.c
-@@ -384,6 +384,12 @@ QemuOptsList qemu_spice_opts = {
-         },{
-             .name = "tls-ciphers",
-             .type = QEMU_OPT_STRING,
-+        },{
-+            .name = "jpeg",
-+            .type = QEMU_OPT_STRING,
-+        },{
-+            .name = "zlib-glz",
-+            .type = QEMU_OPT_STRING,
-         },
-         { /* end if list */ }
-     },
-diff --git a/spice.c b/spice.c
-index 1109b4f..201e53c 100644
---- a/spice.c
-+++ b/spice.c
-@@ -207,6 +207,23 @@ int mon_spice_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data)
-                                      port, tls_port, subject);
- }
-
-+static inline spice_wan_compression_t get_wan_compression_value(const char *str)
-+{
-+    if (!strcmp(str, "wan")) {
-+        return SPICE_WAN_COMPRESSION_AUTO;
-+    }
-+
-+    if (!strcmp(str, "never")) {
-+        return SPICE_WAN_COMPRESSION_NEVER;
-+    }
-+
-+    if (!strcmp(str, "always")) {
-+        return SPICE_WAN_COMPRESSION_ALWAYS;
-+    }
-+
-+    return SPICE_WAN_COMPRESSION_INVALID;
-+}
-+
- void qemu_spice_init(void)
- {
-     QemuOpts *opts = QTAILQ_FIRST(&qemu_spice_opts.head);
-@@ -218,6 +235,7 @@ void qemu_spice_init(void)
-         *x509_cert_file = NULL,
-         *x509_cacert_file = NULL;
-     int port, tls_port, len;
-+    const char *jpeg, *zlib_glz;
-
-     if (!opts)
-         return;
-@@ -283,6 +301,17 @@ void qemu_spice_init(void)
-     /* TODO: make configurable via cmdline */
-     spice_server_set_image_compression(spice_server, SPICE_IMAGE_COMPRESS_AUTO_GLZ);
-
-+    jpeg = qemu_opt_get(opts, "jpeg");
-+    zlib_glz = qemu_opt_get(opts, "zlib-glz");
-+
-+    if (jpeg) {
-+        spice_server_set_jpeg_compression(spice_server, get_wan_compression_value(jpeg));
-+    }
-+
-+    if (zlib_glz) {
-+        spice_server_set_zlib_glz_compression(spice_server, get_wan_compression_value(zlib_glz));
-+    }
-+
-     spice_server_init(spice_server, &core_interface);
-     using_spice = 1;
-
--- 
-1.7.2.3
-
diff --git a/0027-ifdef-new-config-options.patch b/0027-ifdef-new-config-options.patch
deleted file mode 100644
index 9b185eb..0000000
--- a/0027-ifdef-new-config-options.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From 9200133d24ee5b5dab71ce922882c3534d9e8a5a Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Thu, 15 Jul 2010 09:01:28 +0200
-Subject: [PATCH 27/39] ifdef new config options.
-
----
- spice.c |    6 +++++-
- 1 files changed, 5 insertions(+), 1 deletions(-)
-
-diff --git a/spice.c b/spice.c
-index 201e53c..76e6ac1 100644
---- a/spice.c
-+++ b/spice.c
-@@ -207,6 +207,7 @@ int mon_spice_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data)
-                                      port, tls_port, subject);
- }
-
-+#if defined(SPICE_SERVER_VERSION) && SPICE_SERVER_VERSION >= 0x000503
- static inline spice_wan_compression_t get_wan_compression_value(const char *str)
- {
-     if (!strcmp(str, "wan")) {
-@@ -223,6 +224,7 @@ static inline spice_wan_compression_t get_wan_compression_value(const char *str)
-
-     return SPICE_WAN_COMPRESSION_INVALID;
- }
-+#endif
-
- void qemu_spice_init(void)
- {
-@@ -235,7 +237,6 @@ void qemu_spice_init(void)
-         *x509_cert_file = NULL,
-         *x509_cacert_file = NULL;
-     int port, tls_port, len;
--    const char *jpeg, *zlib_glz;
-
-     if (!opts)
-         return;
-@@ -301,6 +302,8 @@ void qemu_spice_init(void)
-     /* TODO: make configurable via cmdline */
-     spice_server_set_image_compression(spice_server, SPICE_IMAGE_COMPRESS_AUTO_GLZ);
-
-+#if defined(SPICE_SERVER_VERSION) && SPICE_SERVER_VERSION >= 0x000503
-+    const char *jpeg, *zlib_glz;
-     jpeg = qemu_opt_get(opts, "jpeg");
-     zlib_glz = qemu_opt_get(opts, "zlib-glz");
-
-@@ -311,6 +314,7 @@ void qemu_spice_init(void)
-     if (zlib_glz) {
-         spice_server_set_zlib_glz_compression(spice_server, get_wan_compression_value(zlib_glz));
-     }
-+#endif
-
-     spice_server_init(spice_server, &core_interface);
-     using_spice = 1;
--- 
-1.7.2.3
-
diff --git a/0028-spice-vmc-add-counter-to-debug-statements.patch b/0028-spice-vmc-add-counter-to-debug-statements.patch
deleted file mode 100644
index 2a3b23c..0000000
--- a/0028-spice-vmc-add-counter-to-debug-statements.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 2165916a311108d39c7aa45e5189af26712234b8 Mon Sep 17 00:00:00 2001
-From: Alon Levy <alevy@redhat.com>
-Date: Wed, 14 Jul 2010 16:30:35 +0300
-Subject: [PATCH 28/39] spice-vmc: add counter to debug statements
-
----
- hw/spice-vmc.c |    3 ++-
- 1 files changed, 2 insertions(+), 1 deletions(-)
-
-diff --git a/hw/spice-vmc.c b/hw/spice-vmc.c
-index 06e30e6..041f243 100644
---- a/hw/spice-vmc.c
-+++ b/hw/spice-vmc.c
-@@ -23,8 +23,9 @@
-
- #define dprintf(_svc, _level, _fmt, ...)                                \
-     do {                                                                \
-+        static unsigned __dprintf_counter = 0;                          \
-         if (_svc->debug >= _level) {                                    \
--            fprintf(stderr, "svc: " _fmt, ## __VA_ARGS__);              \
-+            fprintf(stderr, "svc: %3d: " _fmt, ++__dprintf_counter, ## __VA_ARGS__);\
-         }                                                               \
-     } while (0)
-
--- 
-1.7.2.3
-
diff --git a/0029-spice-vmc-split-vmc_write-to-max-sized-virtio_serial.patch b/0029-spice-vmc-split-vmc_write-to-max-sized-virtio_serial.patch
deleted file mode 100644
index 0378f1c..0000000
--- a/0029-spice-vmc-split-vmc_write-to-max-sized-virtio_serial.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From f86c044ae075d142e658e866572eb0a37ecad2e1 Mon Sep 17 00:00:00 2001
-From: Alon Levy <alevy@redhat.com>
-Date: Thu, 22 Jul 2010 00:21:18 +0300
-Subject: [PATCH 29/39] spice-vmc: split vmc_write to max sized virtio_serial_write calls
-
-workaround for current windows driver limitation (RHBZ 617000)
----
- hw/spice-vmc.c |   21 ++++++++++++++++++---
- 1 files changed, 18 insertions(+), 3 deletions(-)
-
-diff --git a/hw/spice-vmc.c b/hw/spice-vmc.c
-index 041f243..b9d64a2 100644
---- a/hw/spice-vmc.c
-+++ b/hw/spice-vmc.c
-@@ -21,6 +21,8 @@
- #define VMC_GUEST_DEVICE_NAME "com.redhat.spice.0"
- #define VMC_DEVICE_NAME       "spicevmc"
-
-+#define VMC_MAX_HOST_WRITE    2048
-+
- #define dprintf(_svc, _level, _fmt, ...)                                \
-     do {                                                                \
-         static unsigned __dprintf_counter = 0;                          \
-@@ -43,10 +45,23 @@ typedef struct SpiceVirtualChannel {
- static int vmc_write(SpiceVDIPortInstance *sin, const uint8_t *buf, int len)
- {
-     SpiceVirtualChannel *svc = container_of(sin, SpiceVirtualChannel, sin);
--    ssize_t out;
-+    ssize_t out = 0;
-+    ssize_t last_out;
-+    uint8_t* p = (uint8_t*)buf;
-+
-+    while (len > 0) {
-+        last_out = virtio_serial_write(&svc->port, p,
-+                            MIN(len, VMC_MAX_HOST_WRITE));
-+        if (last_out > 0) {
-+            out += last_out;
-+            len -= last_out;
-+            p += last_out;
-+        } else {
-+            break;
-+        }
-+    }
-
--    out = virtio_serial_write(&svc->port, buf, len);
--    dprintf(svc, 3, "%s: %lu/%d\n", __func__, out, len);
-+    dprintf(svc, 3, "%s: %lu/%zd\n", __func__, out, len + out);
-     return out;
- }
-
--- 
-1.7.2.3
-
diff --git a/0030-qxl-add-800x480-resolution-to-qxl_modes-n900-native.patch b/0030-qxl-add-800x480-resolution-to-qxl_modes-n900-native.patch
deleted file mode 100644
index 4eb6f8c..0000000
--- a/0030-qxl-add-800x480-resolution-to-qxl_modes-n900-native.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From be78cc4a136f8ec63dc6d7efd8356625c639a877 Mon Sep 17 00:00:00 2001
-From: Alon Levy <alevy@redhat.com>
-Date: Tue, 3 Aug 2010 11:37:51 +0300
-Subject: [PATCH 30/39] qxl: add 800x480 resolution to qxl_modes (n900 native)
-
----
- hw/qxl.c |    1 +
- 1 files changed, 1 insertions(+), 0 deletions(-)
-
-diff --git a/hw/qxl.c b/hw/qxl.c
-index 7bd4467..86c0e03 100644
---- a/hw/qxl.c
-+++ b/hw/qxl.c
-@@ -64,6 +64,7 @@
-
- static QXLMode qxl_modes[] = {
-     QXL_MODE_EX(640, 480),
-+    QXL_MODE_EX(800, 480),
-     QXL_MODE_EX(800, 600),
-     QXL_MODE_EX(832, 624),
-     QXL_MODE_EX(1024, 768),
--- 
-1.7.2.3
-
diff --git a/0031-qxl-savevm-fixes.patch b/0031-qxl-savevm-fixes.patch
deleted file mode 100644
index 93054e8..0000000
--- a/0031-qxl-savevm-fixes.patch
+++ /dev/null
@@ -1,259 +0,0 @@
-From e55e5fd43113a5b266efa6d17e44f0e9231a98ed Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Wed, 25 Aug 2010 16:08:37 +0000
-Subject: [PATCH 31/39] qxl: savevm fixes
-
----
- hw/qxl.c |  125 +++++++++++++++++++++++++++++++++++++++++++++----------------
- hw/qxl.h |    6 +++
- 2 files changed, 98 insertions(+), 33 deletions(-)
-
-diff --git a/hw/qxl.c b/hw/qxl.c
-index 86c0e03..4a15200 100644
---- a/hw/qxl.c
-+++ b/hw/qxl.c
-@@ -1087,6 +1087,14 @@ static void qxl_vm_change_state_handler(void *opaque, int running, int reason)
- {
-     PCIQXLDevice *qxl = opaque;
-     qemu_spice_vm_change_state_handler(&qxl->ssd, running, reason);
-+
-+    if (!running && qxl->mode == QXL_MODE_NATIVE) {
-+        /* dirty all vram (which holds surfaces) to make sure it is saved */
-+        /* FIXME #1: should go out during "live" stage */
-+        /* FIXME #2: we only need to save the areas which are actually used */
-+        ram_addr_t addr = qxl->vram_offset;
-+        qxl_set_dirty(addr, addr + qxl->vram_size);
-+    }
- }
-
- /* display change listener */
-@@ -1134,6 +1142,8 @@ static int qxl_init(PCIDevice *dev)
-     qxl->id = device_id;
-     qxl->mode = QXL_MODE_UNDEFINED;
-     qxl->generation = 1;
-+    qxl->num_memslots = NUM_MEMSLOTS;
-+    qxl->num_surfaces = NUM_SURFACES;
-
-     switch (qxl->revision) {
-     case 1: /* spice 0.4 -- qxl-1 */
-@@ -1183,7 +1193,8 @@ static int qxl_init(PCIDevice *dev)
-         if (ram_size < 16 * 1024 * 1024)
-             ram_size = 16 * 1024 * 1024;
-         qxl->vga.vram_size = ram_size;
--        qxl->vga.vram_offset = qemu_ram_alloc(&qxl->pci.qdev, "bar0", qxl->vga.vram_size);
-+        qxl->vga.vram_offset = qemu_ram_alloc(&qxl->pci.qdev, "qxl.vgavram",
-+                                              qxl->vga.vram_size);
-         qxl->vga.vram_ptr = qemu_get_ram_ptr(qxl->vga.vram_offset);
-
-         pci_config_set_class(config, PCI_CLASS_DISPLAY_OTHER);
-@@ -1195,14 +1206,14 @@ static int qxl_init(PCIDevice *dev)
-     pci_set_byte(&config[PCI_INTERRUPT_PIN], 1);
-
-     qxl->rom_size = qxl_rom_size();
--    qxl->rom_offset = qemu_ram_alloc(&qxl->pci.qdev, "bar2", qxl->rom_size);
-+    qxl->rom_offset = qemu_ram_alloc(&qxl->pci.qdev, "qxl.vrom", qxl->rom_size);
-     init_qxl_rom(qxl);
-     init_qxl_ram(qxl);
-
-     if (qxl->vram_size < 16 * 1024 * 1024)
-         qxl->vram_size = 16 * 1024 * 1024;
-     qxl->vram_size = msb_mask(qxl->vram_size * 2 - 1);
--    qxl->vram_offset = qemu_ram_alloc(&qxl->pci.qdev, "bar1", qxl->vram_size);
-+    qxl->vram_offset = qemu_ram_alloc(&qxl->pci.qdev, "qxl.vram", qxl->vram_size);
-
-     pci_register_bar(&qxl->pci, QXL_IO_RANGE_INDEX,
-                      msb_mask(QXL_IO_RANGE_SIZE * 2 - 1),
-@@ -1237,14 +1248,12 @@ static void qxl_pre_save(void *opaque)
-     uint8_t *ram_start = d->vga.vram_ptr;
-
-     dprintf(d, 1, "%s:\n", __FUNCTION__);
--#if 1 /* wanna zap this */
-     if (d->last_release == NULL) {
-         d->last_release_offset = 0;
-     } else {
-         d->last_release_offset = (uint8_t *)d->last_release - ram_start;
-     }
-     assert(d->last_release_offset < d->vga.vram_size);
--#endif
- }
-
- static int qxl_pre_load(void *opaque)
-@@ -1306,29 +1315,55 @@ static int qxl_post_load(void *opaque, int version)
-     }
-     dprintf(d, 1, "%s: done\n", __FUNCTION__);
-
--#if 1 /* wanna zap this */
--    if (d->last_release_offset >= d->vga.vram_size) {
--        dprintf(d, 1, "%s: invalid last_release_offset %u, ram_size %u\n",
--                __FUNCTION__, d->last_release_offset, d->vga.vram_size);
--        exit(-1);
--    }
--
-+    assert(d->last_release_offset < d->vga.vram_size);
-     if (d->last_release_offset == 0) {
-         d->last_release = NULL;
-     } else {
-         d->last_release = (QXLReleaseInfo *)(ram_start + d->last_release_offset);
-     }
--#endif
-+
-+    /* spice 0.4 compatibility -- accept but ignore */
-+    free(d->worker_data);
-+    d->worker_data = NULL;
-+    d->worker_data_size = 0;
-
-     return 0;
- }
-
--#define QXL_VER 1
-+#define QXL_SAVE_VERSION 20
-+
-+static bool qxl_test_worker_data(void *opaque, int version_id)
-+{
-+    PCIQXLDevice* d = opaque;
-+
-+    if (d->revision != 1) {
-+        return false;
-+    }
-+    if (!d->worker_data_size) {
-+        return false;
-+    }
-+    if (!d->worker_data) {
-+        d->worker_data = qemu_malloc(d->worker_data_size);
-+    }
-+    return true;
-+}
-+
-+static bool qxl_test_spice04(void *opaque, int version_id)
-+{
-+    PCIQXLDevice* d = opaque;
-+    return d->revision == 1;
-+}
-+
-+static bool qxl_test_spice06(void *opaque)
-+{
-+    PCIQXLDevice* d = opaque;
-+    return d->revision > 1;
-+}
-
- static VMStateDescription qxl_memslot = {
-     .name               = "qxl-memslot",
--    .version_id         = QXL_VER,
--    .minimum_version_id = QXL_VER,
-+    .version_id         = QXL_SAVE_VERSION,
-+    .minimum_version_id = QXL_SAVE_VERSION,
-     .fields = (VMStateField[]) {
-         VMSTATE_UINT64(slot.mem_start, struct guest_slots),
-         VMSTATE_UINT64(slot.mem_end,   struct guest_slots),
-@@ -1339,8 +1374,8 @@ static VMStateDescription qxl_memslot = {
-
- static VMStateDescription qxl_surface = {
-     .name               = "qxl-surface",
--    .version_id         = QXL_VER,
--    .minimum_version_id = QXL_VER,
-+    .version_id         = QXL_SAVE_VERSION,
-+    .minimum_version_id = QXL_SAVE_VERSION,
-     .fields = (VMStateField[]) {
-         VMSTATE_UINT32(width,      QXLSurfaceCreate),
-         VMSTATE_UINT32(height,     QXLSurfaceCreate),
-@@ -1355,34 +1390,58 @@ static VMStateDescription qxl_surface = {
-     }
- };
-
-+static VMStateDescription qxl_vmstate_spice06 = {
-+    .name               = "qxl/spice06",
-+    .version_id         = QXL_SAVE_VERSION,
-+    .minimum_version_id = QXL_SAVE_VERSION,
-+    .fields = (VMStateField []) {
-+        VMSTATE_INT32_EQUAL(num_memslots, PCIQXLDevice),
-+        VMSTATE_STRUCT_ARRAY(guest_slots, PCIQXLDevice, NUM_MEMSLOTS, 0,
-+                             qxl_memslot, struct guest_slots),
-+        VMSTATE_STRUCT(guest_primary.surface, PCIQXLDevice, 0,
-+                       qxl_surface, QXLSurfaceCreate),
-+        VMSTATE_INT32_EQUAL(num_surfaces, PCIQXLDevice),
-+        VMSTATE_ARRAY(guest_surfaces.cmds, PCIQXLDevice, NUM_SURFACES, 0,
-+                      vmstate_info_uint64, uint64_t),
-+        VMSTATE_UINT64(guest_cursor, PCIQXLDevice),
-+        VMSTATE_END_OF_LIST()
-+    },
-+};
-+
- static VMStateDescription qxl_vmstate = {
-     .name               = "qxl",
--    .version_id         = QXL_VER,
--    .minimum_version_id = QXL_VER,
-+    .version_id         = QXL_SAVE_VERSION,
-+    .minimum_version_id = QXL_SAVE_VERSION,
-     .pre_save           = qxl_pre_save,
-     .pre_load           = qxl_pre_load,
-     .post_load          = qxl_post_load,
-     .fields = (VMStateField []) {
-         VMSTATE_PCI_DEVICE(pci, PCIQXLDevice),
--        VMSTATE_STRUCT(vga, PCIQXLDevice, QXL_VER, vmstate_vga_common, VGACommonState),
-+        VMSTATE_STRUCT(vga, PCIQXLDevice, 0, vmstate_vga_common, VGACommonState),
-         VMSTATE_UINT32(shadow_rom.mode, PCIQXLDevice),
--#if 1 /* wanna zap this */
-         VMSTATE_UINT32(num_free_res, PCIQXLDevice),
-         VMSTATE_UINT32(last_release_offset, PCIQXLDevice),
--#endif
-         VMSTATE_UINT32(mode, PCIQXLDevice),
-         VMSTATE_UINT32(ssd.unique, PCIQXLDevice),
--#if 1 /* new stuff */
--        VMSTATE_STRUCT_ARRAY(guest_slots, PCIQXLDevice, NUM_MEMSLOTS, QXL_VER,
--                             qxl_memslot, struct guest_slots),
--        VMSTATE_STRUCT(guest_primary.surface, PCIQXLDevice, QXL_VER,
--                       qxl_surface, QXLSurfaceCreate),
--        VMSTATE_ARRAY(guest_surfaces.cmds, PCIQXLDevice, NUM_SURFACES, QXL_VER,
--                      vmstate_info_uint64, uint64_t),
--        VMSTATE_UINT64(guest_cursor, PCIQXLDevice),
--#endif
-+
-+        /* spice 0.4 sends/expects them */
-+        VMSTATE_VBUFFER_UINT32(vga.vram_ptr, PCIQXLDevice, 0, qxl_test_spice04, 0,
-+                               vga.vram_size),
-+        VMSTATE_UINT32_TEST(worker_data_size, PCIQXLDevice, qxl_test_spice04),
-+        VMSTATE_VBUFFER_UINT32(worker_data, PCIQXLDevice, 0, qxl_test_worker_data, 0,
-+                               worker_data_size),
-+
-         VMSTATE_END_OF_LIST()
--    }
-+    },
-+    .subsections = (VMStateSubsection[]) {
-+        {
-+            /* additional spice 0.6 state */
-+            .vmsd   = &qxl_vmstate_spice06,
-+            .needed = qxl_test_spice06,
-+        },{
-+            /* end of list */
-+        },
-+    },
- };
-
- static PCIDeviceInfo qxl_info = {
-diff --git a/hw/qxl.h b/hw/qxl.h
-index 1216405..caf3684 100644
---- a/hw/qxl.h
-+++ b/hw/qxl.h
-@@ -24,6 +24,9 @@ typedef struct PCIQXLDevice {
-     int                generation;
-     uint32_t           revision;
-
-+    int32_t            num_memslots;
-+    int32_t            num_surfaces;
-+
-     struct guest_slots {
-         QXLMemSlot     slot;
-         void           *ptr;
-@@ -74,6 +77,9 @@ typedef struct PCIQXLDevice {
-     /* io bar */
-     uint32_t           io_base;
-
-+    /* spice 0.4 loadvm compatibility */
-+    void               *worker_data;
-+    uint32_t           worker_data_size;
- } PCIQXLDevice;
-
- #define PANIC_ON(x) if ((x)) {                         \
--- 
-1.7.2.3
-
diff --git a/0032-Revert-spice-vmc-split-vmc_write-to-max-sized-virtio.patch b/0032-Revert-spice-vmc-split-vmc_write-to-max-sized-virtio.patch
deleted file mode 100644
index 54b7715..0000000
--- a/0032-Revert-spice-vmc-split-vmc_write-to-max-sized-virtio.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From f48f184b9d22bbd2e34fb4f3a7a760f0e98fae64 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Wed, 8 Sep 2010 11:45:30 +0200
-Subject: [PATCH 32/39] Revert "spice-vmc: split vmc_write to max sized virtio_serial_write calls"
-
-This reverts commit 380b75548db5116e538dc646e84bceb1c4b0e61b.
----
- hw/spice-vmc.c |   21 +++------------------
- 1 files changed, 3 insertions(+), 18 deletions(-)
-
-diff --git a/hw/spice-vmc.c b/hw/spice-vmc.c
-index b9d64a2..041f243 100644
---- a/hw/spice-vmc.c
-+++ b/hw/spice-vmc.c
-@@ -21,8 +21,6 @@
- #define VMC_GUEST_DEVICE_NAME "com.redhat.spice.0"
- #define VMC_DEVICE_NAME       "spicevmc"
-
--#define VMC_MAX_HOST_WRITE    2048
--
- #define dprintf(_svc, _level, _fmt, ...)                                \
-     do {                                                                \
-         static unsigned __dprintf_counter = 0;                          \
-@@ -45,23 +43,10 @@ typedef struct SpiceVirtualChannel {
- static int vmc_write(SpiceVDIPortInstance *sin, const uint8_t *buf, int len)
- {
-     SpiceVirtualChannel *svc = container_of(sin, SpiceVirtualChannel, sin);
--    ssize_t out = 0;
--    ssize_t last_out;
--    uint8_t* p = (uint8_t*)buf;
--
--    while (len > 0) {
--        last_out = virtio_serial_write(&svc->port, p,
--                            MIN(len, VMC_MAX_HOST_WRITE));
--        if (last_out > 0) {
--            out += last_out;
--            len -= last_out;
--            p += last_out;
--        } else {
--            break;
--        }
--    }
-+    ssize_t out;
-
--    dprintf(svc, 3, "%s: %lu/%zd\n", __func__, out, len + out);
-+    out = virtio_serial_write(&svc->port, buf, len);
-+    dprintf(svc, 3, "%s: %lu/%d\n", __func__, out, len);
-     return out;
- }
-
--- 
-1.7.2.3
-
diff --git a/0033-Revert-spice-vmc-add-counter-to-debug-statements.patch b/0033-Revert-spice-vmc-add-counter-to-debug-statements.patch
deleted file mode 100644
index 6ff14e4..0000000
--- a/0033-Revert-spice-vmc-add-counter-to-debug-statements.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From a5d6e7e76bf5f5fb0e2c8232ddca2b850bfc1afa Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Wed, 8 Sep 2010 11:45:49 +0200
-Subject: [PATCH 33/39] Revert "spice-vmc: add counter to debug statements"
-
-This reverts commit f3ab5192a20ee9dc7776b13ec0ba75030bb52a20.
----
- hw/spice-vmc.c |    3 +--
- 1 files changed, 1 insertions(+), 2 deletions(-)
-
-diff --git a/hw/spice-vmc.c b/hw/spice-vmc.c
-index 041f243..06e30e6 100644
---- a/hw/spice-vmc.c
-+++ b/hw/spice-vmc.c
-@@ -23,9 +23,8 @@
-
- #define dprintf(_svc, _level, _fmt, ...)                                \
-     do {                                                                \
--        static unsigned __dprintf_counter = 0;                          \
-         if (_svc->debug >= _level) {                                    \
--            fprintf(stderr, "svc: %3d: " _fmt, ++__dprintf_counter, ## __VA_ARGS__);\
-+            fprintf(stderr, "svc: " _fmt, ## __VA_ARGS__);              \
-         }                                                               \
-     } while (0)
-
--- 
-1.7.2.3
-
diff --git a/0034-Revert-spice-vmc-two-bugfixes-in-vmc_read.patch b/0034-Revert-spice-vmc-two-bugfixes-in-vmc_read.patch
deleted file mode 100644
index ce11f48..0000000
--- a/0034-Revert-spice-vmc-two-bugfixes-in-vmc_read.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From 84115ef1adf343c34eebfb1045cbc5c72892e3b2 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Wed, 8 Sep 2010 11:46:18 +0200
-Subject: [PATCH 34/39] Revert "spice-vmc: two bugfixes in vmc_read"
-
-This reverts commit 71983a37e30c68beab5e9056a4600d2958f77a04.
----
- hw/spice-vmc.c |   13 +++++--------
- 1 files changed, 5 insertions(+), 8 deletions(-)
-
-diff --git a/hw/spice-vmc.c b/hw/spice-vmc.c
-index 06e30e6..3f6a2bb 100644
---- a/hw/spice-vmc.c
-+++ b/hw/spice-vmc.c
-@@ -45,7 +45,7 @@ static int vmc_write(SpiceVDIPortInstance *sin, const uint8_t *buf, int len)
-     ssize_t out;
-
-     out = virtio_serial_write(&svc->port, buf, len);
--    dprintf(svc, 3, "%s: %lu/%d\n", __func__, out, len);
-+    dprintf(svc, 2, "%s: %lu/%d\n", __func__, out, len);
-     return out;
- }
-
-@@ -54,16 +54,13 @@ static int vmc_read(SpiceVDIPortInstance *sin, uint8_t *buf, int len)
-     SpiceVirtualChannel *svc = container_of(sin, SpiceVirtualChannel, sin);
-     int bytes = MIN(len, svc->datalen);
-
--    dprintf(svc, 2, "%s: %p %d/%d/%zd\n", __func__, svc->datapos, len, bytes, svc->datalen);
--    if (bytes > 0) {
-+    dprintf(svc, 2, "%s: %d/%zd\n", __func__, bytes, svc->datalen);
-+    if (bytes) {
-         memcpy(buf, svc->datapos, bytes);
-         svc->datapos += bytes;
-         svc->datalen -= bytes;
--        assert(svc->datalen >= 0);
--        if (svc->datalen == 0) {
--            svc->datapos = 0;
-+        if (0 == svc->datalen) {
-             virtio_serial_throttle_port(&svc->port, false);
--            // ^^^ !!! may call vmc_have_data, so don't touch svc after it!
-         }
-     }
-     return bytes;
-@@ -143,7 +140,7 @@ static void vmc_have_data(VirtIOSerialPort *port, const uint8_t *buf, size_t len
-     SpiceVirtualChannel *svc = DO_UPCAST(SpiceVirtualChannel, port, port);
-
-     dprintf(svc, 2, "%s: %zd\n", __func__, len);
--    assert(svc->datalen == 0);
-+    assert(svc->datapos == 0);
-     if (svc->bufsize < len) {
-         svc->bufsize = len;
-         svc->buffer = qemu_realloc(svc->buffer, svc->bufsize);
--- 
-1.7.2.3
-
diff --git a/0035-Revert-spice-live-migration-wip.patch b/0035-Revert-spice-live-migration-wip.patch
deleted file mode 100644
index ace3f27..0000000
--- a/0035-Revert-spice-live-migration-wip.patch
+++ /dev/null
@@ -1,181 +0,0 @@
-From 3e0d1b6ed5f8e8b871803337008e104398e4db0a Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Wed, 8 Sep 2010 11:48:57 +0200
-Subject: [PATCH 35/39] Revert "spice: live migration (wip)."
-
-This reverts commit 85b9db9ba993af737c9c402cf2f67db7b1b3cbce.
-
-Conflicts:
-
-	spice.c
----
- monitor.c       |    1 -
- qemu-monitor.hx |   11 -------
- qemu-spice.h    |    2 -
- spice.c         |   87 -------------------------------------------------------
- 4 files changed, 0 insertions(+), 101 deletions(-)
-
-diff --git a/monitor.c b/monitor.c
-index 6674a8c..e51df62 100644
---- a/monitor.c
-+++ b/monitor.c
-@@ -57,7 +57,6 @@
- #include "osdep.h"
- #include "exec-all.h"
- #include "qemu-kvm.h"
--#include "qemu-spice.h"
-
- //#define DEBUG
- //#define DEBUG_COMPLETION
-diff --git a/qemu-monitor.hx b/qemu-monitor.hx
-index c2570d9..da7b796 100644
---- a/qemu-monitor.hx
-+++ b/qemu-monitor.hx
-@@ -2510,17 +2510,6 @@ ETEXI
-
- HXCOMM DO NOT add new commands after 'info', move your addition before it!
-
--#if defined(CONFIG_SPICE)
--    {
--        .name       = "spice_migrate_info",
--        .args_type  = "hostname:s,port:i?,tls-port:i?,cert-subject:s?",
--        .params     = "hostname port tls-port cert-subject",
--        .help       = "send migration info to spice client",
--	.user_print = monitor_user_noop,
--        .mhandler.cmd_new = mon_spice_migrate,
--    },
--#endif
--
- STEXI
- @end table
- ETEXI
-diff --git a/qemu-spice.h b/qemu-spice.h
-index 3c8e959..6f19ba7 100644
---- a/qemu-spice.h
-+++ b/qemu-spice.h
-@@ -16,8 +16,6 @@ void qemu_spice_input_init(void);
- void qemu_spice_audio_init(void);
- void qemu_spice_display_init(DisplayState *ds);
-
--int mon_spice_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data);
--
- #else  /* CONFIG_SPICE */
-
- #define using_spice 0
-diff --git a/spice.c b/spice.c
-index 76e6ac1..e6f047d 100644
---- a/spice.c
-+++ b/spice.c
-@@ -11,7 +11,6 @@
- #include "qemu-queue.h"
- #include "qemu-x509.h"
- #include "monitor.h"
--#include "hw/hw.h"
-
- /* core bits */
-
-@@ -123,90 +122,8 @@ static SpiceCoreInterface core_interface = {
-     .watch_remove       = watch_remove,
- };
-
--/* handle client migration */
--
--static int spice_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
--{
--    static int last_stage;
--    static int migrate_client, client_connected;
--    int ret = 1;
--
--    if (last_stage != stage) {
--        last_stage = stage;
--        fprintf(stderr, "%s: stage %d\n", __FUNCTION__, stage);
--    } else {
--        fprintf(stderr, ".");
--    }
--
--    switch (stage) {
--    case 1:
--        migrate_client = 1;
--        client_connected = 0;
--        fprintf(stderr, "%s: start client migration\n", __FUNCTION__);
--        if (spice_server_migrate_start(spice_server) != 0) {
--            fprintf(stderr, "%s: fail -> no client migration\n", __FUNCTION__);
--            migrate_client = 0;
--        }
--        break;
--    case 2:
--        if (!migrate_client)
--            break;
--        switch (spice_server_migrate_client_state(spice_server)) {
--        case SPICE_MIGRATE_CLIENT_NONE:
--            fprintf(stderr, "%s: no client connected\n", __FUNCTION__);
--            migrate_client = 0;
--            break;
--        case SPICE_MIGRATE_CLIENT_WAITING:
--            ret = 0;
--            break;
--        case SPICE_MIGRATE_CLIENT_READY:
--            if (!client_connected) {
--                fprintf(stderr, "%s: client connected to target\n", __FUNCTION__);
--                client_connected = 1;
--            }
--            break;
--        }
--        break;
--    case 3:
--        if (migrate_client && client_connected) {
--            fprintf(stderr, "%s: finish client migration\n", __FUNCTION__);
--            spice_server_migrate_end(spice_server, 1);
--        }
--        break;
--    }
--    return ret;
--}
--
--static void spice_save(QEMUFile *f, void *opaque)
--{
--    fprintf(stderr, "%s:\n", __FUNCTION__);
--}
--
--static int spice_load(QEMUFile *f, void *opaque, int version_id)
--{
--    fprintf(stderr, "%s:\n", __FUNCTION__);
--    return 0;
--}
--
- /* functions for the rest of qemu */
-
--int mon_spice_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data)
--{
--    const char *hostname = qdict_get_str(qdict, "hostname");
--    const char *subject  = qdict_get_try_str(qdict, "cert-subject");
--    int port             = qdict_get_try_int(qdict, "port", -1);
--    int tls_port         = qdict_get_try_int(qdict, "tls-port", -1);
--
--    if (!spice_server) {
--        qerror_report(QERR_DEVICE_NOT_ACTIVE, "spice");
--        return -1;
--    }
--
--    /* TODO: Convert to QError */
--    return spice_server_migrate_info(spice_server, hostname,
--                                     port, tls_port, subject);
--}
--
- #if defined(SPICE_SERVER_VERSION) && SPICE_SERVER_VERSION >= 0x000503
- static inline spice_wan_compression_t get_wan_compression_value(const char *str)
- {
-@@ -322,10 +239,6 @@ void qemu_spice_init(void)
-     qemu_spice_input_init();
-     qemu_spice_audio_init();
-
--    register_savevm_live(NULL, "spice", -1, 1, NULL,
--                         spice_live, spice_save, spice_load,
--                         spice_server);
--
-     qemu_free(x509_key_file);
-     qemu_free(x509_cert_file);
-     qemu_free(x509_cacert_file);
--- 
-1.7.2.3
-
diff --git a/0036-Revert-spice-add-pci-vdi-port-backend-obsolete.patch b/0036-Revert-spice-add-pci-vdi-port-backend-obsolete.patch
deleted file mode 100644
index fcf7d08..0000000
--- a/0036-Revert-spice-add-pci-vdi-port-backend-obsolete.patch
+++ /dev/null
@@ -1,590 +0,0 @@
-From 7bad8970dd7db3e3e0e0b11626656c68f4238884 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Wed, 8 Sep 2010 11:49:22 +0200
-Subject: [PATCH 36/39] Revert "spice: add pci vdi port backend (obsolete)."
-
-This reverts commit b56a2ed131bdb4ce42db8f33f87603c416e7a60a.
----
- Makefile.target |    2 +-
- hw/spice-vdi.c  |  556 -------------------------------------------------------
- 2 files changed, 1 insertions(+), 557 deletions(-)
- delete mode 100644 hw/spice-vdi.c
-
-diff --git a/Makefile.target b/Makefile.target
-index 025bdb8..90544c5 100644
---- a/Makefile.target
-+++ b/Makefile.target
-@@ -217,7 +217,7 @@ obj-i386-y += pc_piix.o
- obj-i386-y += testdev.o
- obj-i386-y += acpi.o acpi_piix4.o
- obj-i386-$(CONFIG_SPICE) += qxl.o qxl-logger.o qxl-render.o
--obj-i386-$(CONFIG_SPICE) += spice-vmc.o spice-vdi.o
-+obj-i386-$(CONFIG_SPICE) += spice-vmc.o
-
- obj-i386-y += pcspk.o i8254.o
- obj-i386-$(CONFIG_KVM_PIT) += i8254-kvm.o
-diff --git a/hw/spice-vdi.c b/hw/spice-vdi.c
-deleted file mode 100644
-index 23cbbe1..0000000
---- a/hw/spice-vdi.c
-+++ /dev/null
-@@ -1,556 +0,0 @@
--#include <pthread.h>
--#include <signal.h>
--
--#include "qemu-common.h"
--#include "qemu-spice.h"
--#include "hw/hw.h"
--#include "hw/pc.h"
--#include "hw/pci.h"
--#include "console.h"
--#include "hw/vga_int.h"
--#include "qemu-timer.h"
--#include "sysemu.h"
--#include "console.h"
--#include "pci.h"
--#include "hw.h"
--#include "cpu-common.h"
--
--#include <spice.h>
--#include <spice-experimental.h>
--#include <spice/ipc_ring.h>
--#include <spice/barrier.h>
--
--#undef SPICE_RING_PROD_ITEM
--#define SPICE_RING_PROD_ITEM(r, ret) {                                  \
--        typeof(r) start = r;                                            \
--        typeof(r) end = r + 1;                                          \
--        uint32_t prod = (r)->prod & SPICE_RING_INDEX_MASK(r);           \
--        typeof(&(r)->items[prod]) m_item = &(r)->items[prod];           \
--        if (!((uint8_t*)m_item >= (uint8_t*)(start) && (uint8_t*)(m_item + 1) <= (uint8_t*)(end))) { \
--            abort();                                                    \
--        }                                                               \
--        ret = &m_item->el;                                              \
--    }
--
--#undef SPICE_RING_CONS_ITEM
--#define SPICE_RING_CONS_ITEM(r, ret) {                                  \
--        typeof(r) start = r;                                            \
--        typeof(r) end = r + 1;                                          \
--        uint32_t cons = (r)->cons & SPICE_RING_INDEX_MASK(r);           \
--        typeof(&(r)->items[cons]) m_item = &(r)->items[cons];           \
--        if (!((uint8_t*)m_item >= (uint8_t*)(start) && (uint8_t*)(m_item + 1) <= (uint8_t*)(end))) { \
--            abort();                                                    \
--        }                                                               \
--        ret = &m_item->el;                                              \
--    }
--
--
--#undef ALIGN
--#define ALIGN(a, b) (((a) + ((b) - 1)) & ~((b) - 1))
--
--#define REDHAT_PCI_VENDOR_ID 0x1b36
--#define VDI_PORT_DEVICE_ID 0x0105
--#define VDI_PORT_REVISION 0x01
--
--#define VDI_PORT_INTERRUPT (1 << 0)
--
--#define VDI_PORT_MAGIC (*(uint32_t*)"VDIP")
--
--#define VDI_PORT_DEV_NAME "vdi_port"
--#define VDI_PORT_SAVE_VERSION 20
--
--#include <spice/start-packed.h>
--
--typedef struct SPICE_ATTR_PACKED VDIPortPacket {
--    uint32_t gen;
--    uint32_t size;
--    uint8_t data[512 - 2 * sizeof(uint32_t)];
--} VDIPortPacket;
--
--SPICE_RING_DECLARE(VDIPortRing, VDIPortPacket, 32);
--
--enum {
--    VDI_PORT_IO_RANGE_INDEX,
--    VDI_PORT_RAM_RANGE_INDEX,
--};
--
--enum {
--    VDI_PORT_IO_CONNECTION,
--    VDI_PORT_IO_NOTIFY = 4,
--    VDI_PORT_IO_UPDATE_IRQ = 8,
--
--    VDI_PORT_IO_RANGE_SIZE = 12
--};
--
--typedef struct SPICE_ATTR_PACKED VDIPortRam {
--    uint32_t magic;
--    uint32_t generation;
--    uint32_t int_pending;
--    uint32_t int_mask;
--    VDIPortRing input;
--    VDIPortRing output;
--    uint32_t reserv[32];
--} VDIPortRam;
--
--#include <spice/end-packed.h>
--
--typedef struct PCIVDIPortDevice {
--    PCIDevice pci_dev;
--    uint32_t io_base;
--    uint64_t ram_offset;
--    uint32_t ram_size;
--    VDIPortRam *ram;
--    uint32_t connected;
--    int running;
--    int new_gen_on_resume;
--    int active_interface;
--    SpiceVDIPortInstance sin;
--    int plug_read_pos;
--} PCIVDIPortDevice;
--
--static int debug = 1;
--
--static inline uint32_t msb_mask(uint32_t val)
--{
--    uint32_t mask;
--
--    do {
--        mask = ~(val - 1) & val;
--        val &= ~mask;
--    } while (mask < val);
--
--    return mask;
--}
--
--static inline void atomic_or(uint32_t *var, uint32_t add)
--{
--   __asm__ __volatile__ ("lock; orl %1, %0" : "+m" (*var) : "r" (add) : "memory");
--}
--
--static inline uint32_t atomic_exchange(uint32_t val, uint32_t *ptr)
--{
--   __asm__ __volatile__("xchgl %0, %1" : "+q"(val), "+m" (*ptr) : : "memory");
--   return val;
--}
--
--static void set_dirty(void *base, ram_addr_t offset, void *start, uint32_t length)
--{
--    assert(start >= base);
--
--    ram_addr_t addr =  (ram_addr_t)((uint8_t*)start - (uint8_t*)base) + offset;
--    ram_addr_t end =  ALIGN(addr + length, TARGET_PAGE_SIZE);
--
--    do {
--        cpu_physical_memory_set_dirty(addr);
--        addr += TARGET_PAGE_SIZE;
--    } while ( addr < end );
--}
--
--static inline void vdi_port_set_dirty(PCIVDIPortDevice *d, void *start, uint32_t length)
--{
--    set_dirty(d->ram, d->ram_offset, start, length);
--}
--
--static void vdi_port_new_gen(PCIVDIPortDevice *d)
--{
--    d->ram->generation = (d->ram->generation + 1 == 0) ? 1 : d->ram->generation + 1;
--    vdi_port_set_dirty(d, &d->ram->generation, sizeof(d->ram->generation));
--}
--
--static int vdi_port_irq_level(PCIVDIPortDevice *d)
--{
--    return !!(d->ram->int_pending & d->ram->int_mask);
--}
--
--static void vdi_port_notify_guest(PCIVDIPortDevice *d)
--{
--    uint32_t events = VDI_PORT_INTERRUPT;
--    uint32_t old_pending;
--
--    if (!d->connected) {
--        return;
--    }
--    old_pending = __sync_fetch_and_or(&d->ram->int_pending, events);
--    if ((old_pending & events) == events) {
--        return;
--    }
--    qemu_set_irq(d->pci_dev.irq[0], vdi_port_irq_level(d));
--    vdi_port_set_dirty(d, &d->ram->int_pending, sizeof(d->ram->int_pending));
--}
--
--static int vdi_port_interface_write(SpiceVDIPortInstance *sin,
--                                    const uint8_t *buf, int len)
--{
--    PCIVDIPortDevice *d = container_of(sin, PCIVDIPortDevice, sin);
--    VDIPortRing *ring = &d->ram->output;
--    int do_notify = false;
--    int actual_write = 0;
--    int l = len;
--
--    if (!d->running) {
--        return 0;
--    }
--
--    while (len) {
--        VDIPortPacket *packet;
--        int notify;
--        int wait;
--
--        SPICE_RING_PROD_WAIT(ring, wait);
--        if (wait) {
--            break;
--        }
--
--        SPICE_RING_PROD_ITEM(ring, packet);
--        packet->gen = d->ram->generation;
--        packet->size = MIN(len, sizeof(packet->data));
--        memcpy(packet->data, buf, packet->size);
--        vdi_port_set_dirty(d, packet, sizeof(*packet) - (sizeof(packet->data) - packet->size));
--
--        SPICE_RING_PUSH(ring, notify);
--        do_notify = do_notify || notify;
--        len -= packet->size;
--        buf += packet->size;
--        actual_write += packet->size;
--    }
--    vdi_port_set_dirty(d, ring, sizeof(*ring) - sizeof(ring->items));
--
--    if (do_notify) {
--        vdi_port_notify_guest(d);
--    }
--    if (debug > 1) {
--        fprintf(stderr, "%s: %d/%d\n", __FUNCTION__, actual_write, l);
--    }
--    return actual_write;
--}
--
--static int vdi_port_interface_read(SpiceVDIPortInstance *sin,
--                                   uint8_t *buf, int len)
--{
--    PCIVDIPortDevice *d = container_of(sin, PCIVDIPortDevice, sin);
--    VDIPortRing *ring = &d->ram->input;
--    uint32_t gen = d->ram->generation;
--    VDIPortPacket *packet;
--    int do_notify = false;
--    int actual_read = 0;
--    int l = len;
--
--    if (!d->running) {
--        return 0;
--    }
--
--    while (!SPICE_RING_IS_EMPTY(ring)) {
--        int notify;
--
--        SPICE_RING_CONS_ITEM(ring, packet);
--        if (packet->gen == gen) {
--            break;
--        }
--        SPICE_RING_POP(ring, notify);
--        do_notify = do_notify || notify;
--    }
--    while (len) {
--        VDIPortPacket *packet;
--        int wait;
--        int now;
--
--        SPICE_RING_CONS_WAIT(ring, wait);
--
--        if (wait) {
--            break;
--        }
--
--        SPICE_RING_CONS_ITEM(ring, packet);
--        if (packet->size > sizeof(packet->data)) {
--            vdi_port_set_dirty(d, ring, sizeof(*ring) - sizeof(ring->items));
--            printf("%s: bad packet size\n", __FUNCTION__);
--            return 0;
--        }
--        now = MIN(len, packet->size - d->plug_read_pos);
--        memcpy(buf, packet->data + d->plug_read_pos, now);
--        len -= now;
--        buf += now;
--        actual_read +=  now;
--        if ((d->plug_read_pos += now) == packet->size) {
--            int notify;
--
--            d->plug_read_pos = 0;
--            SPICE_RING_POP(ring, notify);
--            do_notify = do_notify || notify;
--        }
--    }
--    vdi_port_set_dirty(d, ring, sizeof(*ring) - sizeof(ring->items));
--
--    if (do_notify) {
--        vdi_port_notify_guest(d);
--    }
--    if (debug > 1) {
--        fprintf(stderr, "%s: %d/%d\n", __FUNCTION__, actual_read, l);
--    }
--    return actual_read;
--}
--
--static SpiceVDIPortInterface vdi_port_interface = {
--    .base.type          = SPICE_INTERFACE_VDI_PORT,
--    .base.description   = "vdi port",
--    .base.major_version = SPICE_INTERFACE_VDI_PORT_MAJOR,
--    .base.minor_version = SPICE_INTERFACE_VDI_PORT_MINOR,
--
--    .write              = vdi_port_interface_write,
--    .read               = vdi_port_interface_read,
--};
--
--static void vdi_port_register_interface(PCIVDIPortDevice *d)
--{
--    if (d->active_interface ) {
--        return;
--    }
--
--    if (debug) {
--        fprintf(stderr, "%s\n", __FUNCTION__);
--    }
--    d->sin.base.sif = &vdi_port_interface.base;
--    spice_server_add_interface(spice_server, &d->sin.base);
--    d->active_interface = true;
--}
--
--static void vdi_port_unregister_interface(PCIVDIPortDevice *d)
--{
--    if (!d->active_interface ) {
--        return;
--    }
--    if (debug) {
--        fprintf(stderr, "%s\n", __FUNCTION__);
--    }
--    spice_server_remove_interface(&d->sin.base);
--    d->active_interface = false;
--}
--
--static uint32_t vdi_port_dev_connect(PCIVDIPortDevice *d)
--{
--    if (d->connected) {
--        if (debug) {
--            fprintf(stderr, "%s: already connected\n", __FUNCTION__);
--        }
--        return 0;
--    }
--    vdi_port_new_gen(d);
--    d->connected = true;
--    vdi_port_register_interface(d);
--    return d->ram->generation;
--}
--
--static void vdi_port_dev_disconnect(PCIVDIPortDevice *d)
--{
--    if (!d->connected) {
--        if (debug) {
--            fprintf(stderr, "%s: not connected\n", __FUNCTION__);
--        }
--        return;
--    }
--    d->connected = false;
--    vdi_port_unregister_interface(d);
--}
--
--static void vdi_port_dev_notify(PCIVDIPortDevice *d)
--{
--    spice_server_vdi_port_wakeup(&d->sin);
--}
--
--static void vdi_port_write_dword(void *opaque, uint32_t addr, uint32_t val)
--{
--    PCIVDIPortDevice *d = opaque;
--    uint32_t io_port = addr - d->io_base;
--
--    if (debug > 1) {
--        fprintf(stderr, "%s: addr 0x%x val 0x%x\n", __FUNCTION__, addr, val);
--    }
--    switch (io_port) {
--    case VDI_PORT_IO_NOTIFY:
--        if (!d->connected) {
--            fprintf(stderr, "%s: not connected\n", __FUNCTION__);
--            return;
--        }
--        vdi_port_dev_notify(d);
--        break;
--    case VDI_PORT_IO_UPDATE_IRQ:
--        qemu_set_irq(d->pci_dev.irq[0], vdi_port_irq_level(d));
--        break;
--    case VDI_PORT_IO_CONNECTION:
--        vdi_port_dev_disconnect(d);
--        break;
--    default:
--        if (debug) {
--            fprintf(stderr, "%s: unexpected addr 0x%x val 0x%x\n",
--                    __FUNCTION__, addr, val);
--        }
--    };
--}
--
--static uint32_t vdi_port_read_dword(void *opaque, uint32_t addr)
--{
--    PCIVDIPortDevice *d = opaque;
--    uint32_t io_port = addr - d->io_base;
--
--    if (debug > 1) {
--        fprintf(stderr, "%s: addr 0x%x\n", __FUNCTION__, addr);
--    }
--    if (io_port == VDI_PORT_IO_CONNECTION) {
--        return vdi_port_dev_connect(d);
--    } else {
--        fprintf(stderr, "%s: unexpected addr 0x%x\n", __FUNCTION__, addr);
--    }
--    return 0xffffffff;
--}
--
--static void vdi_port_io_map(PCIDevice *pci_dev, int region_num,
--                            pcibus_t addr, pcibus_t size, int type)
--{
--    PCIVDIPortDevice *d = DO_UPCAST(PCIVDIPortDevice, pci_dev, pci_dev);
--
--    if (debug) {
--        fprintf(stderr, "%s: base 0x%lx size 0x%lx\n", __FUNCTION__, addr, size);
--    }
--    d->io_base = addr;
--    register_ioport_write(addr, size, 4, vdi_port_write_dword, pci_dev);
--    register_ioport_read(addr, size, 4, vdi_port_read_dword, pci_dev);
--}
--
--static void vdi_port_ram_map(PCIDevice *pci_dev, int region_num,
--                             pcibus_t addr, pcibus_t size, int type)
--{
--    PCIVDIPortDevice *d = DO_UPCAST(PCIVDIPortDevice, pci_dev, pci_dev);
--
--    if (debug) {
--        fprintf(stderr, "%s: addr 0x%lx size 0x%lx\n", __FUNCTION__, addr, size);
--    }
--
--    assert((addr & (size - 1)) == 0);
--    assert(size ==  d->ram_size);
--
--    cpu_register_physical_memory(addr, size, d->ram_offset | IO_MEM_RAM);
--}
--
--static void vdi_port_reset(PCIVDIPortDevice *d)
--{
--    memset(d->ram, 0, sizeof(*d->ram));
--    SPICE_RING_INIT(&d->ram->input);
--    SPICE_RING_INIT(&d->ram->output);
--    d->ram->magic = VDI_PORT_MAGIC;
--    d->ram->generation = 0;
--    d->ram->int_pending = 0;
--    d->ram->int_mask = 0;
--    d->connected = false;
--    d->plug_read_pos = 0;
--    vdi_port_set_dirty(d, d->ram, sizeof(*d->ram));
--}
--
--static void vdi_port_reset_handler(DeviceState *dev)
--{
--    PCIVDIPortDevice *d = DO_UPCAST(PCIVDIPortDevice, pci_dev.qdev, dev);
--
--    if (d->connected) {
--        vdi_port_dev_disconnect(d);
--    }
--
--    vdi_port_reset(d);
--    qemu_set_irq(d->pci_dev.irq[0], vdi_port_irq_level(d));
--}
--
--static int vdi_port_pre_load(void* opaque)
--{
--    PCIVDIPortDevice* d = opaque;
--
--    vdi_port_unregister_interface(d);
--    return 0;
--}
--
--static int vdi_port_post_load(void* opaque,int version_id)
--{
--    PCIVDIPortDevice* d = opaque;
--
--    if (d->connected) {
--        vdi_port_register_interface(d);
--    }
--    return 0;
--}
--
--static void vdi_port_vm_change_state_handler(void *opaque, int running, int reason)
--{
--    PCIVDIPortDevice* d = opaque;
--
--    if (running) {
--        d->running = true;
--        if (d->new_gen_on_resume) {
--            d->new_gen_on_resume = false;
--            vdi_port_new_gen(d);
--            vdi_port_notify_guest(d);
--        }
--        qemu_set_irq(d->pci_dev.irq[0], vdi_port_irq_level(d));
--        vdi_port_dev_notify(d);
--    } else {
--        d->running = false;
--    }
--}
--
--static int vdi_port_init(PCIDevice *dev)
--{
--    PCIVDIPortDevice *vdi = (PCIVDIPortDevice *)dev;
--    uint8_t* config = vdi->pci_dev.config;
--    uint32_t ram_size = msb_mask(sizeof(VDIPortRam) * 2 - 1);
--
--    vdi->ram_offset = qemu_ram_alloc(&vdi->pci_dev.qdev, "bar1", ram_size);
--    vdi->ram = qemu_get_ram_ptr(vdi->ram_offset);
--    vdi_port_reset(vdi);
--    vdi->ram_size = ram_size;
--    vdi->new_gen_on_resume = false;
--    vdi->running = false;
--
--    pci_config_set_vendor_id(config, REDHAT_PCI_VENDOR_ID);
--    pci_config_set_device_id(config, VDI_PORT_DEVICE_ID);
--    pci_config_set_class(config, PCI_CLASS_COMMUNICATION_OTHER);
--    pci_set_byte(&config[PCI_REVISION_ID], VDI_PORT_REVISION);
--    pci_set_byte(&config[PCI_INTERRUPT_PIN], 1);
--
--    pci_register_bar(dev, VDI_PORT_IO_RANGE_INDEX,
--                     msb_mask(VDI_PORT_IO_RANGE_SIZE * 2 - 1),
--                     PCI_BASE_ADDRESS_SPACE_IO, vdi_port_io_map);
--
--    pci_register_bar(dev, VDI_PORT_RAM_RANGE_INDEX,
--                     vdi->ram_size , PCI_BASE_ADDRESS_SPACE_MEMORY,
--                     vdi_port_ram_map);
--
--    qemu_add_vm_change_state_handler(vdi_port_vm_change_state_handler, vdi);
--
--    return 0;
--}
--
--static VMStateDescription vdi_port_vmstate = {
--    .name = VDI_PORT_DEV_NAME,
--    .version_id = VDI_PORT_SAVE_VERSION,
--    .minimum_version_id = VDI_PORT_SAVE_VERSION,
--    .pre_load = vdi_port_pre_load,
--    .post_load = vdi_port_post_load,
--    .fields = (VMStateField []) {
--        VMSTATE_PCI_DEVICE(pci_dev, PCIVDIPortDevice),
--        VMSTATE_UINT32(connected, PCIVDIPortDevice),
--        VMSTATE_END_OF_LIST()
--    }
--};
--
--static PCIDeviceInfo vdi_port_info = {
--    .qdev.name = VDI_PORT_DEV_NAME,
--    .qdev.desc = "spice virtual desktop port (obsolete)",
--    .qdev.size = sizeof(PCIVDIPortDevice),
--    .qdev.vmsd = &vdi_port_vmstate,
--    .qdev.reset = vdi_port_reset_handler,
--
--    .init = vdi_port_init,
--};
--
--static void vdi_port_register(void)
--{
--    pci_qdev_register(&vdi_port_info);
--}
--
--device_init(vdi_port_register);
--- 
-1.7.2.3
-
diff --git a/0037-Revert-spice-add-virtio-serial-based-vdi-port-backen.patch b/0037-Revert-spice-add-virtio-serial-based-vdi-port-backen.patch
deleted file mode 100644
index 654ddc5..0000000
--- a/0037-Revert-spice-add-virtio-serial-based-vdi-port-backen.patch
+++ /dev/null
@@ -1,236 +0,0 @@
-From bebcc44cfe5da8a4881292fa564869a481eea4ae Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Wed, 8 Sep 2010 11:49:40 +0200
-Subject: [PATCH 37/39] Revert "spice: add virtio-serial based vdi port backend."
-
-This reverts commit ef9e975b1d34c1426867cef832ba6238a401b740.
----
- Makefile.target |    1 -
- hw/spice-vmc.c  |  203 -------------------------------------------------------
- 2 files changed, 0 insertions(+), 204 deletions(-)
- delete mode 100644 hw/spice-vmc.c
-
-diff --git a/Makefile.target b/Makefile.target
-index 90544c5..4da33b5 100644
---- a/Makefile.target
-+++ b/Makefile.target
-@@ -217,7 +217,6 @@ obj-i386-y += pc_piix.o
- obj-i386-y += testdev.o
- obj-i386-y += acpi.o acpi_piix4.o
- obj-i386-$(CONFIG_SPICE) += qxl.o qxl-logger.o qxl-render.o
--obj-i386-$(CONFIG_SPICE) += spice-vmc.o
-
- obj-i386-y += pcspk.o i8254.o
- obj-i386-$(CONFIG_KVM_PIT) += i8254-kvm.o
-diff --git a/hw/spice-vmc.c b/hw/spice-vmc.c
-deleted file mode 100644
-index 3f6a2bb..0000000
---- a/hw/spice-vmc.c
-+++ /dev/null
-@@ -1,203 +0,0 @@
--/*
--
-- Spice Virtual Machine Channel (VMC).
--
-- A virtio-serial port used for spice to guest communication, over
-- which spice client and a daemon in the guest operating system
-- communicate.
--
-- Replaces the old vdi_port PCI device.
--
--*/
--
--#include <stdio.h>
--#include <stdbool.h>
--#include <spice.h>
--#include <spice-experimental.h>
--
--#include "virtio-serial.h"
--#include "qemu-spice.h"
--
--#define VMC_GUEST_DEVICE_NAME "com.redhat.spice.0"
--#define VMC_DEVICE_NAME       "spicevmc"
--
--#define dprintf(_svc, _level, _fmt, ...)                                \
--    do {                                                                \
--        if (_svc->debug >= _level) {                                    \
--            fprintf(stderr, "svc: " _fmt, ## __VA_ARGS__);              \
--        }                                                               \
--    } while (0)
--
--typedef struct SpiceVirtualChannel {
--    VirtIOSerialPort      port;
--    VMChangeStateEntry    *vmstate;
--    SpiceVDIPortInstance  sin;
--    bool                  active;
--    uint8_t               *buffer;
--    uint8_t               *datapos;
--    ssize_t               bufsize, datalen;
--    uint32_t              debug;
--} SpiceVirtualChannel;
--
--static int vmc_write(SpiceVDIPortInstance *sin, const uint8_t *buf, int len)
--{
--    SpiceVirtualChannel *svc = container_of(sin, SpiceVirtualChannel, sin);
--    ssize_t out;
--
--    out = virtio_serial_write(&svc->port, buf, len);
--    dprintf(svc, 2, "%s: %lu/%d\n", __func__, out, len);
--    return out;
--}
--
--static int vmc_read(SpiceVDIPortInstance *sin, uint8_t *buf, int len)
--{
--    SpiceVirtualChannel *svc = container_of(sin, SpiceVirtualChannel, sin);
--    int bytes = MIN(len, svc->datalen);
--
--    dprintf(svc, 2, "%s: %d/%zd\n", __func__, bytes, svc->datalen);
--    if (bytes) {
--        memcpy(buf, svc->datapos, bytes);
--        svc->datapos += bytes;
--        svc->datalen -= bytes;
--        if (0 == svc->datalen) {
--            virtio_serial_throttle_port(&svc->port, false);
--        }
--    }
--    return bytes;
--}
--
--static SpiceVDIPortInterface vmc_interface = {
--    .base.type          = SPICE_INTERFACE_VDI_PORT,
--    .base.description   = "spice virtual channel vdi port",
--    .base.major_version = SPICE_INTERFACE_VDI_PORT_MAJOR,
--    .base.minor_version = SPICE_INTERFACE_VDI_PORT_MINOR,
--    .write              = vmc_write,
--    .read               = vmc_read,
--};
--
--static void vmc_register_interface(SpiceVirtualChannel *svc)
--{
--    if (svc->active) {
--        return;
--    }
--    dprintf(svc, 1, "%s\n", __func__);
--    svc->sin.base.sif = &vmc_interface.base;
--    spice_server_add_interface(spice_server, &svc->sin.base);
--    svc->active = true;
--}
--
--static void vmc_unregister_interface(SpiceVirtualChannel *svc)
--{
--    if (!svc->active) {
--        return;
--    }
--    dprintf(svc, 1, "%s\n", __func__);
--    spice_server_remove_interface(&svc->sin.base);
--    svc->active = false;
--}
--
--
--static void vmc_change_state_handler(void *opaque, int running, int reason)
--{
--    SpiceVirtualChannel *svc = opaque;
--
--    if (running && svc->active) {
--        spice_server_vdi_port_wakeup(&svc->sin);
--    }
--}
--
--/*
-- * virtio-serial callbacks
-- */
--
--static void vmc_guest_open(VirtIOSerialPort *port)
--{
--    SpiceVirtualChannel *svc = DO_UPCAST(SpiceVirtualChannel, port, port);
--
--    dprintf(svc, 1, "%s\n", __func__);
--    vmc_register_interface(svc);
--}
--
--static void vmc_guest_close(VirtIOSerialPort *port)
--{
--    SpiceVirtualChannel *svc = DO_UPCAST(SpiceVirtualChannel, port, port);
--
--    dprintf(svc, 1, "%s\n", __func__);
--    vmc_unregister_interface(svc);
--}
--
--static void vmc_guest_ready(VirtIOSerialPort *port)
--{
--    SpiceVirtualChannel *svc = DO_UPCAST(SpiceVirtualChannel, port, port);
--
--    dprintf(svc, 1, "%s\n", __func__);
--    if (svc->active)
--        spice_server_vdi_port_wakeup(&svc->sin);
--}
--
--static void vmc_have_data(VirtIOSerialPort *port, const uint8_t *buf, size_t len)
--{
--    SpiceVirtualChannel *svc = DO_UPCAST(SpiceVirtualChannel, port, port);
--
--    dprintf(svc, 2, "%s: %zd\n", __func__, len);
--    assert(svc->datapos == 0);
--    if (svc->bufsize < len) {
--        svc->bufsize = len;
--        svc->buffer = qemu_realloc(svc->buffer, svc->bufsize);
--    }
--    memcpy(svc->buffer, buf, len);
--    svc->datapos = svc->buffer;
--    svc->datalen = len;
--    virtio_serial_throttle_port(&svc->port, true);
--    spice_server_vdi_port_wakeup(&svc->sin);
--}
--
--static int vmc_initfn(VirtIOSerialDevice *dev)
--{
--    VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev);
--    SpiceVirtualChannel *svc = DO_UPCAST(SpiceVirtualChannel, port, port);
--
--    if (!using_spice)
--        return -1;
--
--    dprintf(svc, 1, "%s\n", __func__);
--    port->name = qemu_strdup(VMC_GUEST_DEVICE_NAME);
--    svc->vmstate = qemu_add_vm_change_state_handler(
--        vmc_change_state_handler, svc);
--    virtio_serial_open(port);
--    return 0;
--}
--
--static int vmc_exitfn(VirtIOSerialDevice *dev)
--{
--    VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev);
--    SpiceVirtualChannel *svc = DO_UPCAST(SpiceVirtualChannel, port, port);
--
--    dprintf(svc, 1, "%s\n", __func__);
--    vmc_unregister_interface(svc);
--    qemu_del_vm_change_state_handler(svc->vmstate);
--    virtio_serial_close(port);
--    return 0;
--}
--
--static VirtIOSerialPortInfo vmc_info = {
--    .qdev.name     = VMC_DEVICE_NAME,
--    .qdev.size     = sizeof(SpiceVirtualChannel),
--    .init          = vmc_initfn,
--    .exit          = vmc_exitfn,
--    .guest_open    = vmc_guest_open,
--    .guest_close   = vmc_guest_close,
--    .guest_ready   = vmc_guest_ready,
--    .have_data     = vmc_have_data,
--    .qdev.props = (Property[]) {
--        DEFINE_PROP_UINT32("nr", SpiceVirtualChannel, port.id, VIRTIO_CONSOLE_BAD_ID),
--        DEFINE_PROP_UINT32("debug", SpiceVirtualChannel, debug, 1),
--        DEFINE_PROP_END_OF_LIST(),
--    }
--};
--
--static void vmc_register(void)
--{
--    virtio_serial_port_qdev_register(&vmc_info);
--}
--device_init(vmc_register)
--- 
-1.7.2.3
-
diff --git a/0038-spice-add-virtio-serial-based-spice-vmchannel-backen.patch b/0038-spice-add-virtio-serial-based-spice-vmchannel-backen.patch
deleted file mode 100644
index 2423deb..0000000
--- a/0038-spice-add-virtio-serial-based-spice-vmchannel-backen.patch
+++ /dev/null
@@ -1,297 +0,0 @@
-From 5bdc01e675a51a123a813d62a8ae837db9360b7f Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Tue, 20 Apr 2010 13:33:54 +0200
-Subject: [PATCH 38/39] spice: add virtio-serial based spice vmchannel backend.
-
-Adds the spicevmc device.  This is a communication channel between the
-spice client and the guest.  It is used to send display information and
-mouse events from the spice clients to the guest.
----
- Makefile.target |    1 +
- hw/spice-vmc.c  |  262 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 263 insertions(+), 0 deletions(-)
- create mode 100644 hw/spice-vmc.c
-
-diff --git a/Makefile.target b/Makefile.target
-index 4da33b5..90544c5 100644
---- a/Makefile.target
-+++ b/Makefile.target
-@@ -217,6 +217,7 @@ obj-i386-y += pc_piix.o
- obj-i386-y += testdev.o
- obj-i386-y += acpi.o acpi_piix4.o
- obj-i386-$(CONFIG_SPICE) += qxl.o qxl-logger.o qxl-render.o
-+obj-i386-$(CONFIG_SPICE) += spice-vmc.o
-
- obj-i386-y += pcspk.o i8254.o
- obj-i386-$(CONFIG_KVM_PIT) += i8254-kvm.o
-diff --git a/hw/spice-vmc.c b/hw/spice-vmc.c
-new file mode 100644
-index 0000000..b77fc60
---- /dev/null
-+++ b/hw/spice-vmc.c
-@@ -0,0 +1,262 @@
-+/*
-+
-+ Spice Virtual Machine Channel (VMC).
-+
-+ A virtio-serial port used for spice to guest communication, over
-+ which spice client and a daemon in the guest operating system
-+ communicate.
-+
-+ Replaces the old vdi_port PCI device.
-+
-+*/
-+
-+#include <stdio.h>
-+#include <stdbool.h>
-+#include <spice.h>
-+#include <spice-experimental.h>
-+
-+#include "virtio-serial.h"
-+#include "qemu-spice.h"
-+
-+#define VMC_GUEST_DEVICE_NAME "com.redhat.spice.0"
-+#define VMC_DEVICE_NAME       "spicevmc"
-+
-+/* windows guest driver bug workaround */
-+#define VMC_MAX_HOST_WRITE    2048
-+
-+#define dprintf(_svc, _level, _fmt, ...)                                \
-+    do {                                                                \
-+        static unsigned __dprintf_counter = 0;                          \
-+        if (_svc->debug >= _level) {                                    \
-+            fprintf(stderr, "svc: %3d: " _fmt, ++__dprintf_counter, ## __VA_ARGS__);\
-+        }                                                               \
-+    } while (0)
-+
-+typedef struct SpiceVirtualChannel {
-+    VirtIOSerialPort         port;
-+    VMChangeStateEntry       *vmstate;
-+    SpiceCharDeviceInstance  sin;
-+    char                     *subtype;
-+    bool                     active;
-+    uint8_t                  *buffer;
-+    uint8_t                  *datapos;
-+    ssize_t                  bufsize, datalen;
-+    uint32_t                 debug;
-+} SpiceVirtualChannel;
-+
-+static int vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len)
-+{
-+    SpiceVirtualChannel *svc = container_of(sin, SpiceVirtualChannel, sin);
-+    ssize_t out = 0;
-+    ssize_t last_out;
-+    uint8_t* p = (uint8_t*)buf;
-+
-+    while (len > 0) {
-+        last_out = virtio_serial_write(&svc->port, p,
-+                            MIN(len, VMC_MAX_HOST_WRITE));
-+        if (last_out > 0) {
-+            out += last_out;
-+            len -= last_out;
-+            p += last_out;
-+        } else {
-+            break;
-+        }
-+    }
-+
-+    dprintf(svc, 3, "%s: %lu/%zd\n", __func__, out, len + out);
-+    return out;
-+}
-+
-+static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len)
-+{
-+    SpiceVirtualChannel *svc = container_of(sin, SpiceVirtualChannel, sin);
-+    int bytes = MIN(len, svc->datalen);
-+
-+    dprintf(svc, 2, "%s: %p %d/%d/%zd\n", __func__, svc->datapos, len, bytes, svc->datalen);
-+    if (bytes > 0) {
-+        memcpy(buf, svc->datapos, bytes);
-+        svc->datapos += bytes;
-+        svc->datalen -= bytes;
-+        assert(svc->datalen >= 0);
-+        if (svc->datalen == 0) {
-+            svc->datapos = 0;
-+            virtio_serial_throttle_port(&svc->port, false);
-+            // ^^^ !!! may call vmc_have_data, so don't touch svc after it!
-+        }
-+    }
-+    return bytes;
-+}
-+
-+static SpiceCharDeviceInterface vmc_interface = {
-+    .base.type          = SPICE_INTERFACE_CHAR_DEVICE,
-+    .base.description   = "spice virtual channel char device",
-+    .base.major_version = SPICE_INTERFACE_CHAR_DEVICE_MAJOR,
-+    .base.minor_version = SPICE_INTERFACE_CHAR_DEVICE_MINOR,
-+    .write              = vmc_write,
-+    .read               = vmc_read,
-+};
-+
-+static void vmc_register_interface(SpiceVirtualChannel *svc)
-+{
-+    if (svc->active) {
-+        return;
-+    }
-+    dprintf(svc, 1, "%s\n", __func__);
-+    svc->sin.base.sif = &vmc_interface.base;
-+    spice_server_add_interface(spice_server, &svc->sin.base);
-+    svc->active = true;
-+}
-+
-+static void vmc_unregister_interface(SpiceVirtualChannel *svc)
-+{
-+    if (!svc->active) {
-+        return;
-+    }
-+    dprintf(svc, 1, "%s\n", __func__);
-+    spice_server_remove_interface(&svc->sin.base);
-+    svc->active = false;
-+}
-+
-+
-+static void vmc_change_state_handler(void *opaque, int running, int reason)
-+{
-+    SpiceVirtualChannel *svc = opaque;
-+
-+    if (running && svc->active) {
-+        spice_server_char_device_wakeup(&svc->sin);
-+    }
-+}
-+
-+/*
-+ * virtio-serial callbacks
-+ */
-+
-+static void vmc_guest_open(VirtIOSerialPort *port)
-+{
-+    SpiceVirtualChannel *svc = DO_UPCAST(SpiceVirtualChannel, port, port);
-+
-+    dprintf(svc, 1, "%s\n", __func__);
-+    vmc_register_interface(svc);
-+}
-+
-+static void vmc_guest_close(VirtIOSerialPort *port)
-+{
-+    SpiceVirtualChannel *svc = DO_UPCAST(SpiceVirtualChannel, port, port);
-+
-+    dprintf(svc, 1, "%s\n", __func__);
-+    vmc_unregister_interface(svc);
-+}
-+
-+static void vmc_guest_ready(VirtIOSerialPort *port)
-+{
-+    SpiceVirtualChannel *svc = DO_UPCAST(SpiceVirtualChannel, port, port);
-+
-+    dprintf(svc, 1, "%s\n", __func__);
-+    if (svc->active) {
-+        spice_server_char_device_wakeup(&svc->sin);
-+    }
-+}
-+
-+static void vmc_have_data(VirtIOSerialPort *port, const uint8_t *buf, size_t len)
-+{
-+    SpiceVirtualChannel *svc = DO_UPCAST(SpiceVirtualChannel, port, port);
-+
-+    dprintf(svc, 2, "%s: %zd\n", __func__, len);
-+    assert(svc->datalen == 0);
-+    if (svc->bufsize < len) {
-+        svc->bufsize = len;
-+        svc->buffer = qemu_realloc(svc->buffer, svc->bufsize);
-+    }
-+    memcpy(svc->buffer, buf, len);
-+    svc->datapos = svc->buffer;
-+    svc->datalen = len;
-+    virtio_serial_throttle_port(&svc->port, true);
-+    spice_server_char_device_wakeup(&svc->sin);
-+}
-+
-+static void vmc_print_optional_subtypes(void)
-+{
-+    const char** psubtype = spice_server_char_device_recognized_subtypes();
-+    int i;
-+
-+    fprintf(stderr, "supported subtypes: ");
-+    for(i=0; *psubtype != NULL; ++psubtype, ++i) {
-+        if (i == 0) {
-+            fprintf(stderr, *psubtype);
-+        } else {
-+            fprintf(stderr, ", %s", *psubtype);
-+        }
-+    }
-+    fprintf(stderr, "\n");
-+}
-+
-+static int vmc_initfn(VirtIOSerialDevice *dev)
-+{
-+    VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev);
-+    SpiceVirtualChannel *svc = DO_UPCAST(SpiceVirtualChannel, port, port);
-+    const char** psubtype = spice_server_char_device_recognized_subtypes();
-+    const char *subtype = NULL;
-+
-+    if (!using_spice) {
-+        return -1;
-+    }
-+
-+    dprintf(svc, 1, "%s\n", __func__);
-+
-+    if (svc->subtype == NULL) {
-+        svc->subtype = strdup("vdagent");
-+    }
-+
-+    for(;*psubtype != NULL; ++psubtype) {
-+        if (strcmp(svc->subtype, *psubtype) == 0) {
-+            subtype = *psubtype;
-+            break;
-+        }
-+    }
-+    if (subtype == NULL) {
-+        fprintf(stderr, "spice-vmc: unsupported subtype\n");
-+        vmc_print_optional_subtypes();
-+        return -1;
-+    }
-+    port->name = qemu_strdup(VMC_GUEST_DEVICE_NAME);
-+    svc->vmstate = qemu_add_vm_change_state_handler
-+        (vmc_change_state_handler, svc);
-+    svc->sin.subtype = svc->subtype;
-+    virtio_serial_open(port);
-+    return 0;
-+}
-+
-+static int vmc_exitfn(VirtIOSerialDevice *dev)
-+{
-+    VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev);
-+    SpiceVirtualChannel *svc = DO_UPCAST(SpiceVirtualChannel, port, port);
-+
-+    dprintf(svc, 1, "%s\n", __func__);
-+    vmc_unregister_interface(svc);
-+    qemu_del_vm_change_state_handler(svc->vmstate);
-+    virtio_serial_close(port);
-+    return 0;
-+}
-+
-+static VirtIOSerialPortInfo vmc_info = {
-+    .qdev.name     = VMC_DEVICE_NAME,
-+    .qdev.size     = sizeof(SpiceVirtualChannel),
-+    .init          = vmc_initfn,
-+    .exit          = vmc_exitfn,
-+    .guest_open    = vmc_guest_open,
-+    .guest_close   = vmc_guest_close,
-+    .guest_ready   = vmc_guest_ready,
-+    .have_data     = vmc_have_data,
-+    .qdev.props = (Property[]) {
-+        DEFINE_PROP_UINT32("nr", SpiceVirtualChannel, port.id, VIRTIO_CONSOLE_BAD_ID),
-+        DEFINE_PROP_UINT32("debug", SpiceVirtualChannel, debug, 1),
-+        DEFINE_PROP_STRING("subtype", SpiceVirtualChannel, subtype),
-+        DEFINE_PROP_END_OF_LIST(),
-+    }
-+};
-+
-+static void vmc_register(void)
-+{
-+    virtio_serial_port_qdev_register(&vmc_info);
-+}
-+device_init(vmc_register)
--- 
-1.7.2.3
-
diff --git a/0039-qxl-fix-release-ring-overrun.patch b/0039-qxl-fix-release-ring-overrun.patch
deleted file mode 100644
index a8d041a..0000000
--- a/0039-qxl-fix-release-ring-overrun.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 9394cbaab7701fe421d5c0168854d39d6a8ecfc2 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Tue, 7 Sep 2010 16:45:27 +0200
-Subject: [PATCH 39/39] qxl: fix release ring overrun
-
----
- hw/qxl.c |    6 +++---
- 1 files changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/hw/qxl.c b/hw/qxl.c
-index 4a15200..8448893 100644
---- a/hw/qxl.c
-+++ b/hw/qxl.c
-@@ -377,10 +377,10 @@ static inline void qxl_push_free_res(PCIQXLDevice *d)
-     QXLReleaseRing *ring = &d->ram->release_ring;
-     uint64_t *item;
-
--#define QXL_FREE_BUNCH_SIZE 10
-+#define QXL_FREE_BUNCH_SIZE 32
-
--    if (SPICE_RING_IS_EMPTY(ring) || (d->num_free_res == QXL_FREE_BUNCH_SIZE &&
--                                      ring->prod - ring->cons + 1 != ring->num_items)) {
-+    if (SPICE_RING_IS_EMPTY(ring) || (d->num_free_res >= QXL_FREE_BUNCH_SIZE &&
-+                                      ring->prod - ring->cons + 2 != ring->num_items)) {
-         int notify;
-
-         SPICE_RING_PUSH(ring, notify);
--- 
-1.7.2.3
-
diff --git a/0040-qxl-flip-default-to-stable-pci-revision.patch b/0040-qxl-flip-default-to-stable-pci-revision.patch
deleted file mode 100644
index 2fe6928..0000000
--- a/0040-qxl-flip-default-to-stable-pci-revision.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From b0f3b268c79c532725ae23af56621ab2948ac480 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Thu, 16 Sep 2010 12:07:51 +0000
-Subject: [PATCH 40/40] qxl: flip default to stable pci revision.
-
----
- hw/qxl.c |    2 +-
- 1 files changed, 1 insertions(+), 1 deletions(-)
-
-diff --git a/hw/qxl.c b/hw/qxl.c
-index 8448893..d2a0c16 100644
---- a/hw/qxl.c
-+++ b/hw/qxl.c
-@@ -1455,7 +1455,7 @@ static PCIDeviceInfo qxl_info = {
-     .qdev.props = (Property[]) {
-         DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size, 64 * 1024 * 1024),
-         DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram_size, 64 * 1024 * 1024),
--        DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision, 3),
-+        DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision, 2),
-         DEFINE_PROP_UINT32("debug", PCIQXLDevice, debug, 0),
-         DEFINE_PROP_UINT32("cmdlog", PCIQXLDevice, cmdlog, 0),
-         DEFINE_PROP_END_OF_LIST(),
--- 
-1.7.2.3
-
diff --git a/0041-vmmouse-adapt-to-mouse-handler-changes.patch b/0041-vmmouse-adapt-to-mouse-handler-changes.patch
deleted file mode 100644
index 8914831..0000000
--- a/0041-vmmouse-adapt-to-mouse-handler-changes.patch
+++ /dev/null
@@ -1,116 +0,0 @@
-From ff53b62094b009f34dd3312e32a637ca73c752e3 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Fri, 8 Oct 2010 00:30:13 +0000
-Subject: [PATCH 41/42] vmmouse: adapt to mouse handler changes.
-
-This patch updates the vmmouse handler registration and activation.
-
-Old behavior:
-  vmmouse_read_id, vmmouse_request_relative and vmmouse_request_absolute
-  unregister the handler and re-register it.
-
-New behavior:
-  vmmouse_request_relative and vmmouse_request_absolute will unregister
-  the handler in case the mode did change.  Then register and active the
-  handler with current mode if needed.
-
-Note that the old code never ever *activates* the handler, so the
-vmmouse doesn't receive events.  This trips up Fedora 14 for example:
-Boot a default install without usb tablet, watch the X-Server activating
-the vmmouse then, enjoy a non-functional mouse.
-
-Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
----
- hw/vmmouse.c |   31 +++++++++++++++++++++----------
- 1 files changed, 21 insertions(+), 10 deletions(-)
-
-diff --git a/hw/vmmouse.c b/hw/vmmouse.c
-index f359304..2097119 100644
---- a/hw/vmmouse.c
-+++ b/hw/vmmouse.c
-@@ -100,16 +100,29 @@ static void vmmouse_mouse_event(void *opaque, int x, int y, int dz, int buttons_
-     i8042_isa_mouse_fake_event(s->ps2_mouse);
- }
-
--static void vmmouse_update_handler(VMMouseState *s)
-+static void vmmouse_remove_handler(VMMouseState *s)
- {
-     if (s->entry) {
-         qemu_remove_mouse_event_handler(s->entry);
-         s->entry = NULL;
-     }
--    if (s->status == 0)
-+}
-+
-+static void vmmouse_update_handler(VMMouseState *s, int absolute)
-+{
-+    if (s->status != 0) {
-+        return;
-+    }
-+    if (s->absolute != absolute) {
-+        s->absolute = absolute;
-+        vmmouse_remove_handler(s);
-+    }
-+    if (s->entry == NULL) {
-         s->entry = qemu_add_mouse_event_handler(vmmouse_mouse_event,
-                                                 s, s->absolute,
-                                                 "vmmouse");
-+        qemu_activate_mouse_event_handler(s->entry);
-+    }
- }
-
- static void vmmouse_read_id(VMMouseState *s)
-@@ -121,28 +134,25 @@ static void vmmouse_read_id(VMMouseState *s)
-
-     s->queue[s->nb_queue++] = VMMOUSE_VERSION;
-     s->status = 0;
--    vmmouse_update_handler(s);
- }
-
- static void vmmouse_request_relative(VMMouseState *s)
- {
-     DPRINTF("vmmouse_request_relative()\n");
--    s->absolute = 0;
--    vmmouse_update_handler(s);
-+    vmmouse_update_handler(s, 0);
- }
-
- static void vmmouse_request_absolute(VMMouseState *s)
- {
-     DPRINTF("vmmouse_request_absolute()\n");
--    s->absolute = 1;
--    vmmouse_update_handler(s);
-+    vmmouse_update_handler(s, 1);
- }
-
- static void vmmouse_disable(VMMouseState *s)
- {
-     DPRINTF("vmmouse_disable()\n");
-     s->status = 0xffff;
--    vmmouse_update_handler(s);
-+    vmmouse_remove_handler(s);
- }
-
- static void vmmouse_data(VMMouseState *s, uint32_t *data, uint32_t size)
-@@ -154,7 +164,7 @@ static void vmmouse_data(VMMouseState *s, uint32_t *data, uint32_t size)
-     if (size == 0 || size > 6 || size > s->nb_queue) {
-         printf("vmmouse: driver requested too much data %d\n", size);
-         s->status = 0xffff;
--        vmmouse_update_handler(s);
-+        vmmouse_remove_handler(s);
-         return;
-     }
-
-@@ -239,7 +249,8 @@ static int vmmouse_post_load(void *opaque, int version_id)
- {
-     VMMouseState *s = opaque;
-
--    vmmouse_update_handler(s);
-+    vmmouse_remove_handler(s);
-+    vmmouse_update_handler(s, s->absolute);
-     return 0;
- }
-
--- 
-1.7.2.3
-
diff --git a/0042-vhost-net-patches-for-qemu-0.13.0-tarball.patch b/0042-vhost-net-patches-for-qemu-0.13.0-tarball.patch
deleted file mode 100644
index d8478d7..0000000
--- a/0042-vhost-net-patches-for-qemu-0.13.0-tarball.patch
+++ /dev/null
@@ -1,316 +0,0 @@
-From 2ed38f61f1054e188838bae9244fc1c327f8cda4 Mon Sep 17 00:00:00 2001
-From: Marcelo Tosatti <mtosatti@redhat.com>
-Date: Mon, 18 Oct 2010 16:17:00 -0200
-Subject: [PATCH 42/42] vhost-net patches for qemu-0.13.0 tarball
-
-Justin,
-
-Attached are the patches to fix vhost-net on the 0.13.0 tarball.
-Untested.
-
-commit f76cfc6f0882f227101f21d5a5b80804710b88cb
-Author: Michael S. Tsirkin <mst@redhat.com>
-Date:   Wed Oct 6 07:22:00 2010 +0200
-
-    vhost: fix up irqfd support
-
-    vhost irqfd support: case where many vqs are
-    mapped to a single msix vector is currently broken.
-    Fix it up.
-
-    	Includes this patch from qemu.git:
-
-    virtio: change set guest notifier to per-device
-
-    When using irqfd with vhost-net to inject interrupts,
-    a single evenfd might inject multiple interrupts.
-    Implementing this is much easier with a single
-    per-device callback to set guest notifiers.
-
-    Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
----
- hw/msix.c       |   82 +++++++++++++++++++++++++++++++-----------------------
- hw/msix.h       |    4 +-
- hw/pci.h        |    3 +-
- hw/virtio-pci.c |   56 +++++++++++++++++++++++++++++++------
- 4 files changed, 97 insertions(+), 48 deletions(-)
-
-diff --git a/hw/msix.c b/hw/msix.c
-index 3dd0456..c0c6b50 100644
---- a/hw/msix.c
-+++ b/hw/msix.c
-@@ -300,10 +300,8 @@ static void msix_mmio_writel(void *opaque, target_phys_addr_t addr,
-     if (kvm_enabled() && kvm_irqchip_in_kernel()) {
-         kvm_msix_update(dev, vector, was_masked, msix_is_masked(dev, vector));
-     }
--    if (was_masked != msix_is_masked(dev, vector) &&
--        dev->msix_mask_notifier && dev->msix_mask_notifier_opaque[vector]) {
-+    if (was_masked != msix_is_masked(dev, vector) && dev->msix_mask_notifier) {
-         int r = dev->msix_mask_notifier(dev, vector,
--					dev->msix_mask_notifier_opaque[vector],
- 					msix_is_masked(dev, vector));
-         assert(r >= 0);
-     }
-@@ -351,9 +349,8 @@ static void msix_mask_all(struct PCIDevice *dev, unsigned nentries)
-         int was_masked = msix_is_masked(dev, vector);
-         dev->msix_table_page[offset] |= MSIX_VECTOR_MASK;
-         if (was_masked != msix_is_masked(dev, vector) &&
--            dev->msix_mask_notifier && dev->msix_mask_notifier_opaque[vector]) {
-+            dev->msix_mask_notifier) {
-             r = dev->msix_mask_notifier(dev, vector,
--                                        dev->msix_mask_notifier_opaque[vector],
-                                         msix_is_masked(dev, vector));
-             assert(r >= 0);
-         }
-@@ -379,8 +376,6 @@ int msix_init(struct PCIDevice *dev, unsigned short nentries,
-                                             sizeof *dev->msix_irq_entries);
-     }
- #endif
--    dev->msix_mask_notifier_opaque =
--        qemu_mallocz(nentries * sizeof *dev->msix_mask_notifier_opaque);
-     dev->msix_mask_notifier = NULL;
-     dev->msix_entry_used = qemu_mallocz(MSIX_MAX_ENTRIES *
-                                         sizeof *dev->msix_entry_used);
-@@ -444,8 +439,6 @@ int msix_uninit(PCIDevice *dev)
-     dev->msix_entry_used = NULL;
-     qemu_free(dev->msix_irq_entries);
-     dev->msix_irq_entries = NULL;
--    qemu_free(dev->msix_mask_notifier_opaque);
--    dev->msix_mask_notifier_opaque = NULL;
-     dev->cap_present &= ~QEMU_PCI_CAP_MSIX;
-     return 0;
- }
-@@ -590,46 +583,65 @@ void msix_unuse_all_vectors(PCIDevice *dev)
-     msix_free_irq_entries(dev);
- }
-
--int msix_set_mask_notifier(PCIDevice *dev, unsigned vector, void *opaque)
-+/* Invoke the notifier if vector entry is used and unmasked. */
-+static int msix_notify_if_unmasked(PCIDevice *dev, unsigned vector, int masked)
- {
--    int r = 0;
--    if (vector >= dev->msix_entries_nr || !dev->msix_entry_used[vector])
-+    assert(dev->msix_mask_notifier);
-+    if (!dev->msix_entry_used[vector] || msix_is_masked(dev, vector)) {
-         return 0;
-+    }
-+    return dev->msix_mask_notifier(dev, vector, masked);
-+}
-
--    assert(dev->msix_mask_notifier);
--    assert(opaque);
--    assert(!dev->msix_mask_notifier_opaque[vector]);
-+static int msix_set_mask_notifier_for_vector(PCIDevice *dev, unsigned vector)
-+{
-+	/* Notifier has been set. Invoke it on unmasked vectors. */
-+	return msix_notify_if_unmasked(dev, vector, 0);
-+}
-+
-+static int msix_unset_mask_notifier_for_vector(PCIDevice *dev, unsigned vector)
-+{
-+	/* Notifier will be unset. Invoke it to mask unmasked entries. */
-+	return msix_notify_if_unmasked(dev, vector, 1);
-+}
-
--    /* Unmask the new notifier unless vector is masked. */
--    if (!msix_is_masked(dev, vector)) {
--        r = dev->msix_mask_notifier(dev, vector, opaque, false);
-+int msix_set_mask_notifier(PCIDevice *dev, msix_mask_notifier_func f)
-+{
-+    int r, n;
-+    assert(!dev->msix_mask_notifier);
-+    dev->msix_mask_notifier = f;
-+    for (n = 0; n < dev->msix_entries_nr; ++n) {
-+        r = msix_set_mask_notifier_for_vector(dev, n);
-         if (r < 0) {
--            return r;
-+            goto undo;
-         }
-     }
--    dev->msix_mask_notifier_opaque[vector] = opaque;
-+    return 0;
-+
-+undo:
-+    while (--n >= 0) {
-+        msix_unset_mask_notifier_for_vector(dev, n);
-+    }
-+    dev->msix_mask_notifier = NULL;
-     return r;
- }
-
--int msix_unset_mask_notifier(PCIDevice *dev, unsigned vector)
-+int msix_unset_mask_notifier(PCIDevice *dev)
- {
--    int r = 0;
--    void *opaque;
--    if (vector >= dev->msix_entries_nr || !dev->msix_entry_used[vector])
--        return 0;
--
--    opaque = dev->msix_mask_notifier_opaque[vector];
--
-+    int r, n;
-     assert(dev->msix_mask_notifier);
--    assert(opaque);
--
--    /* Mask the old notifier unless it is already masked. */
--    if (!msix_is_masked(dev, vector)) {
--        r = dev->msix_mask_notifier(dev, vector, opaque, true);
-+    for (n = 0; n < dev->msix_entries_nr; ++n) {
-+        r = msix_unset_mask_notifier_for_vector(dev, n);
-         if (r < 0) {
--            return r;
-+            goto undo;
-         }
-     }
--    dev->msix_mask_notifier_opaque[vector] = NULL;
-+    dev->msix_mask_notifier = NULL;
-+    return 0;
-+
-+undo:
-+    while (--n >= 0) {
-+        msix_set_mask_notifier_for_vector(dev, n);
-+    }
-     return r;
- }
-diff --git a/hw/msix.h b/hw/msix.h
-index 6b21ffb..5a81df5 100644
---- a/hw/msix.h
-+++ b/hw/msix.h
-@@ -33,6 +33,6 @@ void msix_reset(PCIDevice *dev);
-
- extern int msix_supported;
-
--int msix_set_mask_notifier(PCIDevice *dev, unsigned vector, void *opaque);
--int msix_unset_mask_notifier(PCIDevice *dev, unsigned vector);
-+int msix_set_mask_notifier(PCIDevice *dev, msix_mask_notifier_func);
-+int msix_unset_mask_notifier(PCIDevice *dev);
- #endif
-diff --git a/hw/pci.h b/hw/pci.h
-index ccb99d0..a40dc14 100644
---- a/hw/pci.h
-+++ b/hw/pci.h
-@@ -131,7 +131,7 @@ enum {
- #define PCI_CAPABILITY_CONFIG_MSIX_LENGTH 0x10
-
- typedef int (*msix_mask_notifier_func)(PCIDevice *, unsigned vector,
--				       void *opaque, int masked);
-+				       int masked);
-
- struct PCIDevice {
-     DeviceState qdev;
-@@ -198,7 +198,6 @@ struct PCIDevice {
-
-     struct kvm_irq_routing_entry *msix_irq_entries;
-
--    void **msix_mask_notifier_opaque;
-     msix_mask_notifier_func msix_mask_notifier;
-
-     /* Device capability configuration space */
-diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
-index 83b7871..72bc80e 100644
---- a/hw/virtio-pci.c
-+++ b/hw/virtio-pci.c
-@@ -427,11 +427,10 @@ static void virtio_pci_guest_notifier_read(void *opaque)
-     }
- }
-
--static int virtio_pci_mask_notifier(PCIDevice *dev, unsigned vector,
--                                    void *opaque, int masked)
-+static int virtio_pci_mask_vq(PCIDevice *dev, unsigned vector,
-+                              VirtQueue *vq, int masked)
- {
- #ifdef CONFIG_KVM
--    VirtQueue *vq = opaque;
-     EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
-     int r = kvm_set_irqfd(dev->msix_irq_entries[vector].gsi,
-                           event_notifier_get_fd(notifier),
-@@ -452,6 +451,34 @@ static int virtio_pci_mask_notifier(PCIDevice *dev, unsigned vector,
- #endif
- }
-
-+static int virtio_pci_mask_notifier(PCIDevice *dev, unsigned vector,
-+                                    int masked)
-+{
-+    VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
-+    VirtIODevice *vdev = proxy->vdev;
-+    int r, n;
-+
-+    for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
-+        if (!virtio_queue_get_num(vdev, n)) {
-+            break;
-+        }
-+        if (virtio_queue_vector(vdev, n) != vector) {
-+            continue;
-+        }
-+        r = virtio_pci_mask_vq(dev, vector, virtio_get_queue(vdev, n), masked);
-+        if (r < 0) {
-+            goto undo;
-+        }
-+    }
-+    return 0;
-+undo:
-+    while (--n >= 0) {
-+        virtio_pci_mask_vq(dev, vector, virtio_get_queue(vdev, n), !masked);
-+    }
-+    return r;
-+}
-+
-+
- static int virtio_pci_set_guest_notifier(void *opaque, int n, bool assign)
- {
-     VirtIOPCIProxy *proxy = opaque;
-@@ -465,11 +492,7 @@ static int virtio_pci_set_guest_notifier(void *opaque, int n, bool assign)
-         }
-         qemu_set_fd_handler(event_notifier_get_fd(notifier),
-                             virtio_pci_guest_notifier_read, NULL, vq);
--        msix_set_mask_notifier(&proxy->pci_dev,
--                               virtio_queue_vector(proxy->vdev, n), vq);
-     } else {
--        msix_unset_mask_notifier(&proxy->pci_dev,
--				 virtio_queue_vector(proxy->vdev, n));
-         qemu_set_fd_handler(event_notifier_get_fd(notifier),
-                             NULL, NULL, NULL);
-         /* Test and clear notifier before closing it,
-@@ -487,6 +510,13 @@ static int virtio_pci_set_guest_notifiers(void *opaque, bool assign)
-     VirtIODevice *vdev = proxy->vdev;
-     int r, n;
-
-+    /* Must unset mask notifier while guest notifier
-+     * is still assigned */
-+    if (!assign) {
-+	    r = msix_unset_mask_notifier(&proxy->pci_dev);
-+            assert(r >= 0);
-+    }
-+
-     for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
-         if (!virtio_queue_get_num(vdev, n)) {
-             break;
-@@ -498,6 +528,16 @@ static int virtio_pci_set_guest_notifiers(void *opaque, bool assign)
-         }
-     }
-
-+    /* Must set mask notifier after guest notifier
-+     * has been assigned */
-+    if (assign) {
-+        r = msix_set_mask_notifier(&proxy->pci_dev,
-+                                   virtio_pci_mask_notifier);
-+        if (r < 0) {
-+            goto assign_error;
-+        }
-+    }
-+
-     return 0;
-
- assign_error:
-@@ -583,8 +623,6 @@ static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
-
-     proxy->pci_dev.config_write = virtio_write_config;
-
--    proxy->pci_dev.msix_mask_notifier = virtio_pci_mask_notifier;
--
-     size = VIRTIO_PCI_REGION_SIZE(&proxy->pci_dev) + vdev->config_len;
-     if (size & (size-1))
-         size = 1 << qemu_fls(size);
--- 
-1.7.2.3
-
diff --git a/avoid-llseek.patch b/avoid-llseek.patch
deleted file mode 100644
index 18c4e8b..0000000
--- a/avoid-llseek.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-commit d35b261c7a94be9e2fcad5484343544d58ff99be
-Author: Richard Henderson <rth@twiddle.net>
-Date:   Fri Jun 4 12:14:10 2010 -0700
-
-    s390x: Avoid _llseek.
-    
-    There's no _llseek on s390x either.  Replace the existing
-    test for __x86_64__ with a functional test for __NR_llseek.
-    
-    Signed-off-by: Richard Henderson <rth@twiddle.net>
-    Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
-
-diff --git a/linux-user/syscall.c b/linux-user/syscall.c
-index 8222cb9..e94f1ee 100644
---- a/linux-user/syscall.c
-+++ b/linux-user/syscall.c
-@@ -208,7 +208,7 @@ _syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count)
- _syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
- #endif
- _syscall2(int, sys_getpriority, int, which, int, who);
--#if defined(TARGET_NR__llseek) && !defined (__x86_64__)
-+#if defined(TARGET_NR__llseek) && defined(__NR_llseek)
- _syscall5(int, _llseek,  uint,  fd, ulong, hi, ulong, lo,
-           loff_t *, res, uint, wh);
- #endif
-@@ -5933,7 +5933,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
- #ifdef TARGET_NR__llseek /* Not on alpha */
-     case TARGET_NR__llseek:
-         {
--#if defined (__x86_64__)
-+#if !defined(__NR_llseek)
-             ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
-             if (put_user_s64(ret, arg4))
-                 goto efault;
diff --git a/block-vvfat.c-fix-warnings-with-_FORTIFY_SOURCE.patch b/block-vvfat.c-fix-warnings-with-_FORTIFY_SOURCE.patch
deleted file mode 100644
index d3cdf2e..0000000
--- a/block-vvfat.c-fix-warnings-with-_FORTIFY_SOURCE.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From e69a45b96be09d25429175fa8f0f85e3d7fab5a8 Mon Sep 17 00:00:00 2001
-Message-Id: <e69a45b96be09d25429175fa8f0f85e3d7fab5a8.1277191832.git.amit.shah@redhat.com>
-From: Kirill A. Shutemov <kirill@shutemov.name>
-Date: Wed, 20 Jan 2010 00:56:14 +0100
-Subject: [PATCH] block/vvfat.c: fix warnings with _FORTIFY_SOURCE
-
-CC    block/vvfat.o
-cc1: warnings being treated as errors
-block/vvfat.c: In function 'commit_one_file':
-block/vvfat.c:2259: error: ignoring return value of 'ftruncate', declared with attribute warn_unused_result
-make: *** [block/vvfat.o] Error 1
-  CC    block/vvfat.o
-In file included from /usr/include/stdio.h:912,
-                 from ./qemu-common.h:19,
-                 from block/vvfat.c:27:
-In function 'snprintf',
-    inlined from 'init_directories' at block/vvfat.c:871,
-    inlined from 'vvfat_open' at block/vvfat.c:1068:
-/usr/include/bits/stdio2.h:65: error: call to __builtin___snprintf_chk will always overflow destination buffer
-make: *** [block/vvfat.o] Error 1
-
-Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
-Signed-off-by: Juan Quintela <quintela@redhat.com>
-Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
-(cherry picked from commit 2dedf83ef0cc3463783d6b71bf1b25476f691f3a)
-
-This fixes Fedora bug 605202.
-
-Signed-off-by: Amit Shah <amit.shah@redhat.com>
----
- block/vvfat.c |    9 +++++++--
- 1 files changed, 7 insertions(+), 2 deletions(-)
-
-diff --git a/block/vvfat.c b/block/vvfat.c
-index c1acb35..592d6e6 100644
---- a/block/vvfat.c
-+++ b/block/vvfat.c
-@@ -868,7 +868,8 @@ static int init_directories(BDRVVVFATState* s,
-     {
- 	direntry_t* entry=array_get_next(&(s->directory));
- 	entry->attributes=0x28; /* archive | volume label */
--	snprintf((char*)entry->name,11,"QEMU VVFAT");
-+	memcpy(entry->name,"QEMU VVF",8);
-+	memcpy(entry->extension,"AT ",3);
-     }
- 
-     /* Now build FAT, and write back information into directory */
-@@ -2256,7 +2257,11 @@ static int commit_one_file(BDRVVVFATState* s,
- 	c = c1;
-     }
- 
--    ftruncate(fd, size);
-+    if (ftruncate(fd, size)) {
-+        perror("ftruncate()");
-+        close(fd);
-+        return -4;
-+    }
-     close(fd);
- 
-     return commit_mappings(s, first_cluster, dir_index);
--- 
-1.7.0.1
-
diff --git a/qemu-vhost-fix-dirty-page-handling.patch b/qemu-vhost-fix-dirty-page-handling.patch
new file mode 100644
index 0000000..e3fabb7
--- /dev/null
+++ b/qemu-vhost-fix-dirty-page-handling.patch
@@ -0,0 +1,31 @@
+vhost was passing a physical address to cpu_physical_memory_set_dirty,
+which is wrong: we need to translate to ram address first.
+
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+
+Note: this lead to crashes during migration, so the patch
+is needed on the stable branch too.
+
+---
+ hw/vhost.c |    4 +++-
+ 1 files changed, 3 insertions(+), 1 deletions(-)
+
+diff --git a/hw/vhost.c b/hw/vhost.c
+index aaa34e4..97a1299 100644
+--- a/hw/vhost.c
++++ b/hw/vhost.c
+@@ -49,8 +49,10 @@ static void vhost_dev_sync_region(struct vhost_dev *dev,
+         log = __sync_fetch_and_and(from, 0);
+         while ((bit = sizeof(log) > sizeof(int) ?
+                 ffsll(log) : ffs(log))) {
++            ram_addr_t ram_addr;
+             bit -= 1;
+-            cpu_physical_memory_set_dirty(addr + bit * VHOST_LOG_PAGE);
++            ram_addr = cpu_get_physical_page_desc(addr + bit * VHOST_LOG_PAGE);
++            cpu_physical_memory_set_dirty(ram_addr);
+             log &= ~(0x1ull << bit);
+         }
+         addr += VHOST_LOG_CHUNK;
+-- 
+1.7.3.2.91.g446ac
+
diff --git a/qemu.spec b/qemu.spec
index 98c115b..630116b 100644
--- a/qemu.spec
+++ b/qemu.spec
@@ -1,7 +1,7 @@
 Summary: QEMU is a FAST! processor emulator
 Name: qemu
 Version: 0.14.0
-Release: 2%{?dist}
+Release: 3%{?dist}
 # Epoch because we pushed a qemu-1.0 package
 Epoch: 2
 License: GPLv2+ and LGPLv2+ and BSD
@@ -37,7 +37,16 @@ Source8: ksmtuned.conf
 # with F-13/
 Patch00: pc-add-a-Fedora-13-machine-type-for-backward-compat.patch
 
+# Patches from upstream:
 Patch01: qemu-fix-non-PCI-target-build.patch
+Patch02: qemu-vhost-fix-dirty-page-handling.patch
+
+# Spice fixes
+Patch20: 0001-qxl-spice-display-move-pipe-to-ssd.patch
+Patch21: 0002-qxl-implement-get_command-in-vga-mode-without-locks.patch
+Patch22: 0003-qxl-spice-remove-qemu_mutex_-un-lock_iothread-around.patch
+Patch23: 0004-hw-qxl-render-drop-cursor-locks-replace-with-pipe.patch
+
 
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildRequires: SDL-devel zlib-devel which texi2html gnutls-devel cyrus-sasl-devel
@@ -570,6 +579,10 @@ fi
 %{_mandir}/man1/qemu-img.1*
 
 %changelog
+* Wed Mar 16 2011 Justin M. Forbes <jforbes@redhat.com> - 2:0.14.0-3
+- Fix migration issue with vhost
+- Fix qxl locking issues for spice
+
 * Wed Mar 02 2011 Justin M. Forbes <jforbes@redhat.com> - 2:0.14.0-2
 - Re-enable sparc and cris builds