diff --git a/0001-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch b/0001-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch
deleted file mode 100644
index 5a7dc4c..0000000
--- a/0001-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch
+++ /dev/null
@@ -1,57 +0,0 @@
->From c0295cc7cc626a2d51de58ac0a9eeee94b6cc9d4 Mon Sep 17 00:00:00 2001
-From: Amit Shah <amit.shah@redhat.com>
-Date: Mon, 21 Mar 2011 21:57:47 +0100
-Subject: [PATCH 01/28] char: Split out tcp socket close code in a separate
- function
-
-Signed-off-by: Amit Shah <amit.shah@redhat.com>
----
- qemu-char.c |   25 ++++++++++++++++---------
- 1 files changed, 16 insertions(+), 9 deletions(-)
-
-diff --git a/qemu-char.c b/qemu-char.c
-index 8e8cf31..5682aea 100644
---- a/qemu-char.c
-+++ b/qemu-char.c
-@@ -1946,6 +1946,21 @@ typedef struct {
- 
- static void tcp_chr_accept(void *opaque);
- 
-+static void tcp_closed(void *opaque)
-+{
-+    CharDriverState *chr = opaque;
-+    TCPCharDriver *s = chr->opaque;
-+
-+    s->connected = 0;
-+    if (s->listen_fd >= 0) {
-+        qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
-+    }
-+    qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
-+    closesocket(s->fd);
-+    s->fd = -1;
-+    qemu_chr_event(chr, CHR_EVENT_CLOSED);
-+}
-+
- static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
- {
-     TCPCharDriver *s = chr->opaque;
-@@ -2096,15 +2111,7 @@ static void tcp_chr_read(void *opaque)
-         len = s->max_size;
-     size = tcp_chr_recv(chr, (void *)buf, len);
-     if (size == 0) {
--        /* connection closed */
--        s->connected = 0;
--        if (s->listen_fd >= 0) {
--            qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
--        }
--        qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
--        closesocket(s->fd);
--        s->fd = -1;
--        qemu_chr_event(chr, CHR_EVENT_CLOSED);
-+        tcp_closed(chr);
-     } else if (size > 0) {
-         if (s->do_telnetopt)
-             tcp_chr_process_IAC_bytes(chr, s, buf, &size);
--- 
-1.7.5.1
-
diff --git a/0001-malta-Fix-regression-i8259-interrupts-did-not-work.patch b/0001-malta-Fix-regression-i8259-interrupts-did-not-work.patch
new file mode 100644
index 0000000..a57f4ec
--- /dev/null
+++ b/0001-malta-Fix-regression-i8259-interrupts-did-not-work.patch
@@ -0,0 +1,132 @@
+From 0b23c5d40ea933cfece3b4f69427f79c8a23256d Mon Sep 17 00:00:00 2001
+From: Stefan Weil <sw@weilnetz.de>
+Date: Tue, 29 Nov 2011 06:34:48 +0100
+Subject: [PATCH 01/25] malta: Fix regression (i8259 interrupts did not work)
+
+Commit 5632ae46d5bda798e971dae48ebb318ac2c3686a passes the address
+of i8259 to qemu_irq_proxy. i8259 is an auto variable with undefined
+value outside of mips_malta_init.
+
+This made the interrupt proxy unusable: either QEMU crashes, or
+the interrupt handler was not called.
+
+Ethernet for example no longer worked with MIPS Malta.
+
+v2:
+While v1 used a static variable for i8259, this patch introduces
+a qdev for the malta machine. i8259 is now part of the device status.
+This is a minimal qdev implementation to keep the patch small.
+
+Signed-off-by: Stefan Weil <sw@weilnetz.de>
+Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
+(cherry picked from commit e9b40fd34ceb23461083d505a444a389c094455b)
+---
+ hw/mips_malta.c |   39 +++++++++++++++++++++++++++++++++++----
+ 1 files changed, 35 insertions(+), 4 deletions(-)
+
+diff --git a/hw/mips_malta.c b/hw/mips_malta.c
+index bb49749..941b9bd 100644
+--- a/hw/mips_malta.c
++++ b/hw/mips_malta.c
+@@ -47,6 +47,7 @@
+ #include "mc146818rtc.h"
+ #include "blockdev.h"
+ #include "exec-memory.h"
++#include "sysbus.h"             /* SysBusDevice */
+
+ //#define DEBUG_BOARD_INIT
+
+@@ -72,6 +73,11 @@ typedef struct {
+     SerialState *uart;
+ } MaltaFPGAState;
+
++typedef struct {
++    SysBusDevice busdev;
++    qemu_irq *i8259;
++} MaltaState;
++
+ static ISADevice *pit;
+
+ static struct _loaderparams {
+@@ -775,7 +781,7 @@ void mips_malta_init (ram_addr_t ram_size,
+     int64_t kernel_entry;
+     PCIBus *pci_bus;
+     CPUState *env;
+-    qemu_irq *i8259 = NULL, *isa_irq;
++    qemu_irq *isa_irq;
+     qemu_irq *cpu_exit_irq;
+     int piix4_devfn;
+     i2c_bus *smbus;
+@@ -787,6 +793,11 @@ void mips_malta_init (ram_addr_t ram_size,
+     int fl_sectors = 0;
+     int be;
+
++    DeviceState *dev = qdev_create(NULL, "mips-malta");
++    MaltaState *s = DO_UPCAST(MaltaState, busdev.qdev, dev);
++
++    qdev_init_nofail(dev);
++
+     /* Make sure the first 3 serial ports are associated with a device. */
+     for(i = 0; i < 3; i++) {
+         if (!serial_hds[i]) {
+@@ -932,7 +943,7 @@ void mips_malta_init (ram_addr_t ram_size,
+      * qemu_irq_proxy() adds an extra bit of indirection, allowing us
+      * to resolve the isa_irq -> i8259 dependency after i8259 is initialized.
+      */
+-    isa_irq = qemu_irq_proxy(&i8259, 16);
++    isa_irq = qemu_irq_proxy(&s->i8259, 16);
+
+     /* Northbridge */
+     pci_bus = gt64120_register(isa_irq);
+@@ -944,9 +955,9 @@ void mips_malta_init (ram_addr_t ram_size,
+
+     /* Interrupt controller */
+     /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
+-    i8259 = i8259_init(env->irq[2]);
++    s->i8259 = i8259_init(env->irq[2]);
+
+-    isa_bus_irqs(i8259);
++    isa_bus_irqs(s->i8259);
+     pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1);
+     usb_uhci_piix4_init(pci_bus, piix4_devfn + 2);
+     smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100, isa_get_irq(9),
+@@ -990,6 +1001,20 @@ void mips_malta_init (ram_addr_t ram_size,
+     }
+ }
+
++static int mips_malta_sysbus_device_init(SysBusDevice *sysbusdev)
++{
++    return 0;
++}
++
++static SysBusDeviceInfo mips_malta_device = {
++    .init = mips_malta_sysbus_device_init,
++    .qdev.name  = "mips-malta",
++    .qdev.size  = sizeof(MaltaState),
++    .qdev.props = (Property[]) {
++        DEFINE_PROP_END_OF_LIST(),
++    }
++};
++
+ static QEMUMachine mips_malta_machine = {
+     .name = "malta",
+     .desc = "MIPS Malta Core LV",
+@@ -998,9 +1023,15 @@ static QEMUMachine mips_malta_machine = {
+     .is_default = 1,
+ };
+
++static void mips_malta_device_init(void)
++{
++    sysbus_register_withprop(&mips_malta_device);
++}
++
+ static void mips_malta_machine_init(void)
+ {
+     qemu_register_machine(&mips_malta_machine);
+ }
+
++device_init(mips_malta_device_init);
+ machine_init(mips_malta_machine_init);
+-- 
+1.7.7.5
+
diff --git a/0002-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch b/0002-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch
deleted file mode 100644
index 2f3bd6a..0000000
--- a/0002-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch
+++ /dev/null
@@ -1,882 +0,0 @@
->From 9e799828d3a805184687792254c379ba4887ec60 Mon Sep 17 00:00:00 2001
-From: Amit Shah <amit.shah@redhat.com>
-Date: Mon, 21 Mar 2011 20:31:45 +0100
-Subject: [PATCH 02/28] char: Add a QemuChrHandlers struct to initialise
- chardev handlers
-
-Instead of passing each handler in the qemu_add_handlers() function,
-create a struct of handlers that can be passed to the function instead.
-
-Signed-off-by: Amit Shah <amit.shah@redhat.com>
----
- gdbstub.c               |    9 +++++++--
- hw/ccid-card-passthru.c |   11 +++++++----
- hw/debugcon.c           |    2 +-
- hw/escc.c               |    9 +++++++--
- hw/etraxfs_ser.c        |   13 +++++++++----
- hw/grlib_apbuart.c      |   12 +++++++-----
- hw/ivshmem.c            |   28 ++++++++++++++++++++++------
- hw/lm32_juart.c         |    8 +++++++-
- hw/lm32_uart.c          |    8 +++++++-
- hw/mcf_uart.c           |    9 +++++++--
- hw/milkymist-uart.c     |    8 +++++++-
- hw/pl011.c              |    9 +++++++--
- hw/pxa2xx.c             |   13 +++++++++----
- hw/serial.c             |    9 +++++++--
- hw/sh_serial.c          |   12 +++++++++---
- hw/spapr_vty.c          |    8 ++++++--
- hw/strongarm.c          |   12 +++++++-----
- hw/syborg_serial.c      |    9 +++++++--
- hw/usb-serial.c         |    9 +++++++--
- hw/virtio-console.c     |   11 ++++++++---
- hw/xen_console.c        |   16 +++++++++++-----
- hw/xilinx_uartlite.c    |   11 +++++++++--
- monitor.c               |   18 ++++++++++++++----
- net/slirp.c             |    8 ++++++--
- qemu-char.c             |   32 ++++++++++++++++++++++----------
- qemu-char.h             |   13 +++++++++----
- usb-redir.c             |    9 +++++++--
- 27 files changed, 233 insertions(+), 83 deletions(-)
-
-diff --git a/gdbstub.c b/gdbstub.c
-index 27b0cfa..6639849 100644
---- a/gdbstub.c
-+++ b/gdbstub.c
-@@ -2739,6 +2739,12 @@ static void gdb_sigterm_handler(int signal)
- }
- #endif
- 
-+static const QemuChrHandlers gdb_handlers = {
-+    .fd_can_read = gdb_chr_can_receive,
-+    .fd_read = gdb_chr_receive,
-+    .fd_event = gdb_chr_event,
-+};
-+
- int gdbserver_start(const char *device)
- {
-     GDBState *s;
-@@ -2768,8 +2774,7 @@ int gdbserver_start(const char *device)
-         if (!chr)
-             return -1;
- 
--        qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive,
--                              gdb_chr_event, NULL);
-+        qemu_chr_add_handlers(chr, &gdb_handlers, NULL);
-     }
- 
-     s = gdbserver_state;
-diff --git a/hw/ccid-card-passthru.c b/hw/ccid-card-passthru.c
-index 28eb9d1..1dee6f7 100644
---- a/hw/ccid-card-passthru.c
-+++ b/hw/ccid-card-passthru.c
-@@ -273,6 +273,12 @@ static const uint8_t *passthru_get_atr(CCIDCardState *base, uint32_t *len)
-     return card->atr;
- }
- 
-+static const QemuChrHandlers passthru_handlers = {
-+    .fd_can_read = ccid_card_vscard_can_read,
-+    .fd_read = ccid_card_vscard_read,
-+    .fd_event = ccid_card_vscard_event,
-+};
-+
- static int passthru_initfn(CCIDCardState *base)
- {
-     PassthruState *card = DO_UPCAST(PassthruState, base, base);
-@@ -281,10 +287,7 @@ static int passthru_initfn(CCIDCardState *base)
-     card->vscard_in_hdr = 0;
-     if (card->cs) {
-         DPRINTF(card, D_INFO, "initing chardev\n");
--        qemu_chr_add_handlers(card->cs,
--            ccid_card_vscard_can_read,
--            ccid_card_vscard_read,
--            ccid_card_vscard_event, card);
-+        qemu_chr_add_handlers(card->cs, &passthru_handlers, card);
-         ccid_card_vscard_send_init(card);
-     } else {
-         error_report("missing chardev");
-diff --git a/hw/debugcon.c b/hw/debugcon.c
-index 5ee6821..e79a595 100644
---- a/hw/debugcon.c
-+++ b/hw/debugcon.c
-@@ -73,7 +73,7 @@ static void debugcon_init_core(DebugconState *s)
-         exit(1);
-     }
- 
--    qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, s);
-+    qemu_chr_add_handlers(s->chr, NULL, s);
- }
- 
- static int debugcon_isa_initfn(ISADevice *dev)
-diff --git a/hw/escc.c b/hw/escc.c
-index f6fd919..dfa329a 100644
---- a/hw/escc.c
-+++ b/hw/escc.c
-@@ -898,6 +898,12 @@ void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq,
-     sysbus_mmio_map(s, 0, base);
- }
- 
-+static const QemuChrHandlers serial_handlers = {
-+    .fd_can_read = serial_can_receive,
-+    .fd_read = serial_receive1,
-+    .fd_event = serial_event,
-+};
-+
- static int escc_init1(SysBusDevice *dev)
- {
-     SerialState *s = FROM_SYSBUS(SerialState, dev);
-@@ -911,8 +917,7 @@ static int escc_init1(SysBusDevice *dev)
-         s->chn[i].chn = 1 - i;
-         s->chn[i].clock = s->frequency / 2;
-         if (s->chn[i].chr) {
--            qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
--                                  serial_receive1, serial_event, &s->chn[i]);
-+            qemu_chr_add_handlers(s->chn[i].chr, &serial_handlers, &s->chn[i]);
-         }
-     }
-     s->chn[0].otherchn = &s->chn[1];
-diff --git a/hw/etraxfs_ser.c b/hw/etraxfs_ser.c
-index b917d4d..ebbad77 100644
---- a/hw/etraxfs_ser.c
-+++ b/hw/etraxfs_ser.c
-@@ -202,6 +202,12 @@ static void etraxfs_ser_reset(DeviceState *d)
- 
- }
- 
-+static const QemuChrHandlers serial_handlers = {
-+    .fd_can_read = serial_can_receive,
-+    .fd_read = serial_receive,
-+    .fd_event = serial_event,
-+};
-+
- static int etraxfs_ser_init(SysBusDevice *dev)
- {
-     struct etrax_serial *s = FROM_SYSBUS(typeof (*s), dev);
-@@ -212,10 +218,9 @@ static int etraxfs_ser_init(SysBusDevice *dev)
-                                       DEVICE_NATIVE_ENDIAN);
-     sysbus_init_mmio(dev, R_MAX * 4, ser_regs);
-     s->chr = qdev_init_chardev(&dev->qdev);
--    if (s->chr)
--        qemu_chr_add_handlers(s->chr,
--                      serial_can_receive, serial_receive,
--                      serial_event, s);
-+    if (s->chr) {
-+        qemu_chr_add_handlers(s->chr, &serial_handlers, s);
-+    }
-     return 0;
- }
- 
-diff --git a/hw/grlib_apbuart.c b/hw/grlib_apbuart.c
-index 169a56e..310687b 100644
---- a/hw/grlib_apbuart.c
-+++ b/hw/grlib_apbuart.c
-@@ -144,16 +144,18 @@ static CPUWriteMemoryFunc * const grlib_apbuart_write[] = {
-     NULL, NULL, grlib_apbuart_writel,
- };
- 
-+static const QemuChrHandlers grlib_handlers = {
-+    .fd_can_read = grlib_apbuart_can_receive,
-+    .fd_read = grlib_apbuart_receive,
-+    .fd_event = grlib_apbuart_event,
-+};
-+
- static int grlib_apbuart_init(SysBusDevice *dev)
- {
-     UART *uart      = FROM_SYSBUS(typeof(*uart), dev);
-     int   uart_regs = 0;
- 
--    qemu_chr_add_handlers(uart->chr,
--                          grlib_apbuart_can_receive,
--                          grlib_apbuart_receive,
--                          grlib_apbuart_event,
--                          uart);
-+    qemu_chr_add_handlers(uart->chr, &grlib_handlers, uart);
- 
-     sysbus_init_irq(dev, &uart->irq);
- 
-diff --git a/hw/ivshmem.c b/hw/ivshmem.c
-index 3055dd2..4f59575 100644
---- a/hw/ivshmem.c
-+++ b/hw/ivshmem.c
-@@ -312,6 +312,18 @@ static void fake_irqfd(void *opaque, const uint8_t *buf, int size) {
-     msix_notify(pdev, entry->vector);
- }
- 
-+static const QemuChrHandlers ivshmem_handlers = {
-+    .fd_can_read = ivshmem_can_receive,
-+    .fd_read = ivshmem_receive,
-+    .fd_event = ivshmem_event,
-+};
-+
-+static const QemuChrHandlers ivshmem_msi_handlers = {
-+    .fd_can_read = ivshmem_can_receive,
-+    .fd_read = fake_irqfd,
-+    .fd_event = ivshmem_event,
-+};
-+
- static CharDriverState* create_eventfd_chr_device(void * opaque, int eventfd,
-                                                                     int vector)
- {
-@@ -331,11 +343,10 @@ static CharDriverState* create_eventfd_chr_device(void * opaque, int eventfd,
-         s->eventfd_table[vector].pdev = &s->dev;
-         s->eventfd_table[vector].vector = vector;
- 
--        qemu_chr_add_handlers(chr, ivshmem_can_receive, fake_irqfd,
--                      ivshmem_event, &s->eventfd_table[vector]);
-+        qemu_chr_add_handlers(chr, &ivshmem_msi_handlers,
-+                              &s->eventfd_table[vector]);
-     } else {
--        qemu_chr_add_handlers(chr, ivshmem_can_receive, ivshmem_receive,
--                      ivshmem_event, s);
-+        qemu_chr_add_handlers(chr, &ivshmem_handlers, s);
-     }
- 
-     return chr;
-@@ -666,6 +677,12 @@ static int ivshmem_load(QEMUFile* f, void *opaque, int version_id)
-     return 0;
- }
- 
-+static const QemuChrHandlers ivshmem_server_handlers = {
-+    .fd_can_read = ivshmem_can_receive,
-+    .fd_read = ivshmem_read,
-+    .fd_event = ivshmem_event,
-+};
-+
- static int pci_ivshmem_init(PCIDevice *dev)
- {
-     IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev);
-@@ -749,8 +766,7 @@ static int pci_ivshmem_init(PCIDevice *dev)
- 
-         s->eventfd_chr = qemu_mallocz(s->vectors * sizeof(CharDriverState *));
- 
--        qemu_chr_add_handlers(s->server_chr, ivshmem_can_receive, ivshmem_read,
--                     ivshmem_event, s);
-+        qemu_chr_add_handlers(s->server_chr, &ivshmem_server_handlers, s);
-     } else {
-         /* just map the file immediately, we're not using a server */
-         int fd;
-diff --git a/hw/lm32_juart.c b/hw/lm32_juart.c
-index fddcf7e..12dd1e8 100644
---- a/hw/lm32_juart.c
-+++ b/hw/lm32_juart.c
-@@ -110,13 +110,19 @@ static void juart_reset(DeviceState *d)
-     s->jrx = 0;
- }
- 
-+static const QemuChrHandlers juart_handlers = {
-+    .fd_can_read = juart_can_rx,
-+    .fd_read = juart_rx,
-+    .fd_event = juart_event,
-+};
-+
- static int lm32_juart_init(SysBusDevice *dev)
- {
-     LM32JuartState *s = FROM_SYSBUS(typeof(*s), dev);
- 
-     s->chr = qdev_init_chardev(&dev->qdev);
-     if (s->chr) {
--        qemu_chr_add_handlers(s->chr, juart_can_rx, juart_rx, juart_event, s);
-+        qemu_chr_add_handlers(s->chr, juart_handlers, s);
-     }
- 
-     return 0;
-diff --git a/hw/lm32_uart.c b/hw/lm32_uart.c
-index 09090e9..5438660 100644
---- a/hw/lm32_uart.c
-+++ b/hw/lm32_uart.c
-@@ -242,6 +242,12 @@ static void uart_reset(DeviceState *d)
-     s->regs[R_LSR] = LSR_THRE | LSR_TEMT;
- }
- 
-+static const QemuChrHandlers uart_handlers = {
-+    .fd_can_read = uart_can_rx,
-+    .fd_read = uart_rx,
-+    .fd_event = uart_event,
-+};
-+
- static int lm32_uart_init(SysBusDevice *dev)
- {
-     LM32UartState *s = FROM_SYSBUS(typeof(*s), dev);
-@@ -255,7 +261,7 @@ static int lm32_uart_init(SysBusDevice *dev)
- 
-     s->chr = qdev_init_chardev(&dev->qdev);
-     if (s->chr) {
--        qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
-+        qemu_chr_add_handlers(s->chr, uart_handlers, s);
-     }
- 
-     return 0;
-diff --git a/hw/mcf_uart.c b/hw/mcf_uart.c
-index 905e116..bb5740c 100644
---- a/hw/mcf_uart.c
-+++ b/hw/mcf_uart.c
-@@ -268,6 +268,12 @@ static void mcf_uart_receive(void *opaque, const uint8_t *buf, int size)
-     mcf_uart_push_byte(s, buf[0]);
- }
- 
-+static const QemuChrHandlers mcf_uart_handlers = {
-+    .fd_can_read = mcf_uart_can_receive,
-+    .fd_read = mcf_uart_receive,
-+    .fd_event = mcf_uart_event,
-+};
-+
- void *mcf_uart_init(qemu_irq irq, CharDriverState *chr)
- {
-     mcf_uart_state *s;
-@@ -276,8 +282,7 @@ void *mcf_uart_init(qemu_irq irq, CharDriverState *chr)
-     s->chr = chr;
-     s->irq = irq;
-     if (chr) {
--        qemu_chr_add_handlers(chr, mcf_uart_can_receive, mcf_uart_receive,
--                              mcf_uart_event, s);
-+        qemu_chr_add_handlers(chr, &mcf_uart_handlers, s);
-     }
-     mcf_uart_reset(s);
-     return s;
-diff --git a/hw/milkymist-uart.c b/hw/milkymist-uart.c
-index 56c90da..4412b1b 100644
---- a/hw/milkymist-uart.c
-+++ b/hw/milkymist-uart.c
-@@ -133,6 +133,12 @@ static void milkymist_uart_reset(DeviceState *d)
-     }
- }
- 
-+static const QemuChrHandlers uart_handlers = {
-+    .fd_can_read = uart_can_rx,
-+    .fd_read = uart_rx,
-+    .fd_event = uart_event,
-+};
-+
- static int milkymist_uart_init(SysBusDevice *dev)
- {
-     MilkymistUartState *s = FROM_SYSBUS(typeof(*s), dev);
-@@ -147,7 +153,7 @@ static int milkymist_uart_init(SysBusDevice *dev)
- 
-     s->chr = qdev_init_chardev(&dev->qdev);
-     if (s->chr) {
--        qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
-+        qemu_chr_add_handlers(s->chr, uart_handlers, s);
-     }
- 
-     return 0;
-diff --git a/hw/pl011.c b/hw/pl011.c
-index 997ce84..37ba7f6 100644
---- a/hw/pl011.c
-+++ b/hw/pl011.c
-@@ -260,6 +260,12 @@ static const VMStateDescription vmstate_pl011 = {
-     }
- };
- 
-+static const QemuChrHandlers pl011_handlers = {
-+    .fd_can_read = pl011_can_receive,
-+    .fd_read = pl011_receive,
-+    .fd_event = pl011_event,
-+};
-+
- static int pl011_init(SysBusDevice *dev, const unsigned char *id)
- {
-     int iomemtype;
-@@ -278,8 +284,7 @@ static int pl011_init(SysBusDevice *dev, const unsigned char *id)
-     s->cr = 0x300;
-     s->flags = 0x90;
-     if (s->chr) {
--        qemu_chr_add_handlers(s->chr, pl011_can_receive, pl011_receive,
--                              pl011_event, s);
-+        qemu_chr_add_handlers(s->chr, &pl011_handlers, s);
-     }
-     vmstate_register(&dev->qdev, -1, &vmstate_pl011, s);
-     return 0;
-diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
-index cf93110..18bbe48 100644
---- a/hw/pxa2xx.c
-+++ b/hw/pxa2xx.c
-@@ -2019,6 +2019,12 @@ static int pxa2xx_fir_load(QEMUFile *f, void *opaque, int version_id)
-     return 0;
- }
- 
-+static const QemuChrHandlers pxa2xx_handlers = {
-+    .fd_can_read = pxa2xx_fir_is_empty,
-+    .fd_read = pxa2xx_fir_rx,
-+    .fd_event = pxa2xx_fir_event,
-+};
-+
- static PXA2xxFIrState *pxa2xx_fir_init(target_phys_addr_t base,
-                 qemu_irq irq, qemu_irq rx_dma, qemu_irq tx_dma,
-                 CharDriverState *chr)
-@@ -2038,10 +2044,9 @@ static PXA2xxFIrState *pxa2xx_fir_init(target_phys_addr_t base,
-                     pxa2xx_fir_writefn, s, DEVICE_NATIVE_ENDIAN);
-     cpu_register_physical_memory(base, 0x1000, iomemtype);
- 
--    if (chr)
--        qemu_chr_add_handlers(chr, pxa2xx_fir_is_empty,
--                        pxa2xx_fir_rx, pxa2xx_fir_event, s);
--
-+    if (chr) {
-+        qemu_chr_add_handlers(chr, &pxa2xx_handlers, s);
-+    }
-     register_savevm(NULL, "pxa2xx_fir", 0, 0, pxa2xx_fir_save,
-                     pxa2xx_fir_load, s);
- 
-diff --git a/hw/serial.c b/hw/serial.c
-index 0ee61dd..d496bcf 100644
---- a/hw/serial.c
-+++ b/hw/serial.c
-@@ -727,6 +727,12 @@ static void serial_reset(void *opaque)
-     qemu_irq_lower(s->irq);
- }
- 
-+static const QemuChrHandlers serial_handlers = {
-+    .fd_can_read = serial_can_receive1,
-+    .fd_read = serial_receive1,
-+    .fd_event = serial_event,
-+};
-+
- static void serial_init_core(SerialState *s)
- {
-     if (!s->chr) {
-@@ -741,8 +747,7 @@ static void serial_init_core(SerialState *s)
- 
-     qemu_register_reset(serial_reset, s);
- 
--    qemu_chr_add_handlers(s->chr, serial_can_receive1, serial_receive1,
--                          serial_event, s);
-+    qemu_chr_add_handlers(s->chr, &serial_handlers, s);
- }
- 
- /* Change the main reference oscillator frequency. */
-diff --git a/hw/sh_serial.c b/hw/sh_serial.c
-index 191f4a6..8b6460d 100644
---- a/hw/sh_serial.c
-+++ b/hw/sh_serial.c
-@@ -350,6 +350,12 @@ static CPUWriteMemoryFunc * const sh_serial_writefn[] = {
-     &sh_serial_write,
- };
- 
-+static const QemuChrHandlers sh_serial_handlers = {
-+    .fd_can_read = sh_serial_can_receive1,
-+    .fd_read = sh_serial_receive1,
-+    .fd_event = sh_serial_event,
-+};
-+
- void sh_serial_init (target_phys_addr_t base, int feat,
- 		     uint32_t freq, CharDriverState *chr,
- 		     qemu_irq eri_source,
-@@ -389,9 +395,9 @@ void sh_serial_init (target_phys_addr_t base, int feat,
- 
-     s->chr = chr;
- 
--    if (chr)
--        qemu_chr_add_handlers(chr, sh_serial_can_receive1, sh_serial_receive1,
--			      sh_serial_event, s);
-+    if (chr) {
-+        qemu_chr_add_handlers(chr, &sh_serial_handlers, s);
-+    }
- 
-     s->eri = eri_source;
-     s->rxi = rxi_source;
-diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c
-index 6fc0105..5968d85 100644
---- a/hw/spapr_vty.c
-+++ b/hw/spapr_vty.c
-@@ -54,12 +54,16 @@ void vty_putchars(VIOsPAPRDevice *sdev, uint8_t *buf, int len)
-     qemu_chr_write(dev->chardev, buf, len);
- }
- 
-+static const QemuChrHandlers vty_handlers = {
-+    .fd_can_read = vty_can_receive,
-+    .fd_read = vty_receive,
-+};
-+
- static int spapr_vty_init(VIOsPAPRDevice *sdev)
- {
-     VIOsPAPRVTYDevice *dev = (VIOsPAPRVTYDevice *)sdev;
- 
--    qemu_chr_add_handlers(dev->chardev, vty_can_receive,
--                          vty_receive, NULL, dev);
-+    qemu_chr_add_handlers(dev->chardev, vty_handlers, dev);
- 
-     return 0;
- }
-diff --git a/hw/strongarm.c b/hw/strongarm.c
-index 0e03d61..c2dce95 100644
---- a/hw/strongarm.c
-+++ b/hw/strongarm.c
-@@ -1188,6 +1188,12 @@ static CPUWriteMemoryFunc * const strongarm_uart_writefn[] = {
-     strongarm_uart_write,
- };
- 
-+static const QemuChrHandlers strongarm_uart_handlers = {
-+    .fd_can_read = strongarm_uart_can_receive,
-+    .fd_read = strongarm_uart_receive,
-+    .fd_event = strongarm_uart_event,
-+};
-+
- static int strongarm_uart_init(SysBusDevice *dev)
- {
-     StrongARMUARTState *s = FROM_SYSBUS(StrongARMUARTState, dev);
-@@ -1202,11 +1208,7 @@ static int strongarm_uart_init(SysBusDevice *dev)
-     s->tx_timer = qemu_new_timer_ns(vm_clock, strongarm_uart_tx, s);
- 
-     if (s->chr) {
--        qemu_chr_add_handlers(s->chr,
--                        strongarm_uart_can_receive,
--                        strongarm_uart_receive,
--                        strongarm_uart_event,
--                        s);
-+        qemu_chr_add_handlers(s->chr, &strongarm_uart_handlers, s);
-     }
- 
-     return 0;
-diff --git a/hw/syborg_serial.c b/hw/syborg_serial.c
-index 2ef7175..ac68022 100644
---- a/hw/syborg_serial.c
-+++ b/hw/syborg_serial.c
-@@ -292,6 +292,12 @@ static const VMStateDescription vmstate_syborg_serial = {
-     }
- };
- 
-+static const QemuChrHandlers syborg_serial_handlers = {
-+    .fd_can_read = syborg_serial_can_receive,
-+    .fd_read = syborg_serial_receive,
-+    .fd_event = syborg_serial_event,
-+};
-+
- static int syborg_serial_init(SysBusDevice *dev)
- {
-     SyborgSerialState *s = FROM_SYSBUS(SyborgSerialState, dev);
-@@ -304,8 +310,7 @@ static int syborg_serial_init(SysBusDevice *dev)
-     sysbus_init_mmio(dev, 0x1000, iomemtype);
-     s->chr = qdev_init_chardev(&dev->qdev);
-     if (s->chr) {
--        qemu_chr_add_handlers(s->chr, syborg_serial_can_receive,
--                              syborg_serial_receive, syborg_serial_event, s);
-+        qemu_chr_add_handlers(s->chr, &syborg_serial_handlers, s);
-     }
-     if (s->fifo_size <= 0) {
-         fprintf(stderr, "syborg_serial: fifo too small\n");
-diff --git a/hw/usb-serial.c b/hw/usb-serial.c
-index c69c437..45d48ee 100644
---- a/hw/usb-serial.c
-+++ b/hw/usb-serial.c
-@@ -476,6 +476,12 @@ static void usb_serial_event(void *opaque, int event)
-     }
- }
- 
-+static const QemuChrHandlers usb_serial_handlers = {
-+    .fd_can_read = usb_serial_can_read,
-+    .fd_read = usb_serial_read,
-+    .fd_event = usb_serial_event,
-+};
-+
- static int usb_serial_initfn(USBDevice *dev)
- {
-     USBSerialState *s = DO_UPCAST(USBSerialState, dev, dev);
-@@ -487,8 +493,7 @@ static int usb_serial_initfn(USBDevice *dev)
-         return -1;
-     }
- 
--    qemu_chr_add_handlers(s->cs, usb_serial_can_read, usb_serial_read,
--                          usb_serial_event, s);
-+    qemu_chr_add_handlers(s->cs, &usb_serial_handlers, s);
-     usb_serial_handle_reset(dev);
-     return 0;
- }
-diff --git a/hw/virtio-console.c b/hw/virtio-console.c
-index fe5e188..cfc3087 100644
---- a/hw/virtio-console.c
-+++ b/hw/virtio-console.c
-@@ -95,6 +95,12 @@ static void chr_event(void *opaque, int event)
-     }
- }
- 
-+static const QemuChrHandlers chr_handlers = {
-+    .fd_can_read = chr_can_read,
-+    .fd_read = chr_read,
-+    .fd_event = chr_event,
-+};
-+
- static int virtconsole_initfn(VirtIOSerialPort *port)
- {
-     VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
-@@ -107,8 +113,7 @@ static int virtconsole_initfn(VirtIOSerialPort *port)
-     }
- 
-     if (vcon->chr) {
--        qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, chr_event,
--                              vcon);
-+        qemu_chr_add_handlers(vcon->chr, &chr_handlers, vcon);
-         info->have_data = flush_buf;
-         info->guest_open = guest_open;
-         info->guest_close = guest_close;
-@@ -126,7 +131,7 @@ static int virtconsole_exitfn(VirtIOSerialPort *port)
- 	 * Instead of closing the chardev, free it so it can be used
- 	 * for other purposes.
- 	 */
--	qemu_chr_add_handlers(vcon->chr, NULL, NULL, NULL, NULL);
-+	qemu_chr_add_handlers(vcon->chr, NULL, NULL);
-     }
- 
-     return 0;
-diff --git a/hw/xen_console.c b/hw/xen_console.c
-index 8ef104c..85e8a22 100644
---- a/hw/xen_console.c
-+++ b/hw/xen_console.c
-@@ -212,6 +212,11 @@ out:
-     return ret;
- }
- 
-+static const QemuChrHandlers xencons_handlers = {
-+    .fd_can_read = xencons_can_receive,
-+    .fd_read = xencons_receive,
-+};
-+
- static int con_connect(struct XenDevice *xendev)
- {
-     struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);
-@@ -232,9 +237,9 @@ static int con_connect(struct XenDevice *xendev)
- 	return -1;
- 
-     xen_be_bind_evtchn(&con->xendev);
--    if (con->chr)
--        qemu_chr_add_handlers(con->chr, xencons_can_receive, xencons_receive,
--                              NULL, con);
-+    if (con->chr) {
-+        qemu_chr_add_handlers(con->chr, &xencons_handlers, con);
-+    }
- 
-     xen_be_printf(xendev, 1, "ring mfn %d, remote port %d, local port %d, limit %zd\n",
- 		  con->ring_ref,
-@@ -248,8 +253,9 @@ static void con_disconnect(struct XenDevice *xendev)
- {
-     struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);
- 
--    if (con->chr)
--        qemu_chr_add_handlers(con->chr, NULL, NULL, NULL, NULL);
-+    if (con->chr) {
-+        qemu_chr_add_handlers(con->chr, NULL, NULL);
-+    }
-     xen_be_unbind_evtchn(&con->xendev);
- 
-     if (con->sring) {
-diff --git a/hw/xilinx_uartlite.c b/hw/xilinx_uartlite.c
-index 9b94e98..1845577 100644
---- a/hw/xilinx_uartlite.c
-+++ b/hw/xilinx_uartlite.c
-@@ -193,6 +193,12 @@ static void uart_event(void *opaque, int event)
- 
- }
- 
-+static const QemuChrHandlers uart_handlers = {
-+    .fd_can_read = uart_can_rx,
-+    .fd_read = uart_rx,
-+    .fd_event = uart_event,
-+};
-+
- static int xilinx_uartlite_init(SysBusDevice *dev)
- {
-     struct xlx_uartlite *s = FROM_SYSBUS(typeof (*s), dev);
-@@ -206,8 +212,9 @@ static int xilinx_uartlite_init(SysBusDevice *dev)
-     sysbus_init_mmio(dev, R_MAX * 4, uart_regs);
- 
-     s->chr = qdev_init_chardev(&dev->qdev);
--    if (s->chr)
--        qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
-+    if (s->chr) {
-+        qemu_chr_add_handlers(s->chr, &uart_handlers, s);
-+    }
-     return 0;
- }
- 
-diff --git a/monitor.c b/monitor.c
-index 718935b..5b79dde 100644
---- a/monitor.c
-+++ b/monitor.c
-@@ -5249,6 +5249,18 @@ static void monitor_event(void *opaque, int event)
-  * End:
-  */
- 
-+static const QemuChrHandlers monitor_handlers = {
-+    .fd_can_read = monitor_can_read,
-+    .fd_read = monitor_read,
-+    .fd_event = monitor_event,
-+};
-+
-+static const QemuChrHandlers monitor_control_handlers = {
-+    .fd_can_read = monitor_can_read,
-+    .fd_read = monitor_control_read,
-+    .fd_event = monitor_control_event,
-+};
-+
- void monitor_init(CharDriverState *chr, int flags)
- {
-     static int is_first_init = 1;
-@@ -5271,12 +5283,10 @@ void monitor_init(CharDriverState *chr, int flags)
-     if (monitor_ctrl_mode(mon)) {
-         mon->mc = qemu_mallocz(sizeof(MonitorControl));
-         /* Control mode requires special handlers */
--        qemu_chr_add_handlers(chr, monitor_can_read, monitor_control_read,
--                              monitor_control_event, mon);
-+        qemu_chr_add_handlers(chr, &monitor_control_handlers, mon);
-         qemu_chr_set_echo(chr, true);
-     } else {
--        qemu_chr_add_handlers(chr, monitor_can_read, monitor_read,
--                              monitor_event, mon);
-+        qemu_chr_add_handlers(chr, &monitor_handlers, mon);
-     }
- 
-     QLIST_INSERT_HEAD(&mon_list, mon, entry);
-diff --git a/net/slirp.c b/net/slirp.c
-index 157b80a..8eeec7e 100644
---- a/net/slirp.c
-+++ b/net/slirp.c
-@@ -577,6 +577,11 @@ static void guestfwd_read(void *opaque, const uint8_t *buf, int size)
-     slirp_socket_recv(fwd->slirp, fwd->server, fwd->port, buf, size);
- }
- 
-+static const QemuChrHandlers guestfwd_handlers = {
-+    .fd_can_read = guestfwd_can_read,
-+    .fd_read = guestfwd_read,
-+};
-+
- static int slirp_guestfwd(SlirpState *s, const char *config_str,
-                           int legacy_format)
- {
-@@ -633,8 +638,7 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str,
-     fwd->port = port;
-     fwd->slirp = s->slirp;
- 
--    qemu_chr_add_handlers(fwd->hd, guestfwd_can_read, guestfwd_read,
--                          NULL, fwd);
-+    qemu_chr_add_handlers(fwd->hd, &guestfwd_handlers, fwd);
-     return 0;
- 
-  fail_syntax:
-diff --git a/qemu-char.c b/qemu-char.c
-index 5682aea..52bcc0e 100644
---- a/qemu-char.c
-+++ b/qemu-char.c
-@@ -195,19 +195,26 @@ void qemu_chr_send_event(CharDriverState *s, int event)
-         s->chr_send_event(s, event);
- }
- 
-+static const QemuChrHandlers null_handlers = {
-+    /* All handlers are initialised to NULL */
-+};
-+
- void qemu_chr_add_handlers(CharDriverState *s,
--                           IOCanReadHandler *fd_can_read,
--                           IOReadHandler *fd_read,
--                           IOEventHandler *fd_event,
--                           void *opaque)
-+                           const QemuChrHandlers *handlers, void *opaque)
- {
--    if (!opaque && !fd_can_read && !fd_read && !fd_event) {
-+    if (!s) {
-+        return;
-+    }
-+    if (!opaque && !handlers) {
-         /* chr driver being released. */
-         ++s->avail_connections;
-     }
--    s->chr_can_read = fd_can_read;
--    s->chr_read = fd_read;
--    s->chr_event = fd_event;
-+    if (!handlers) {
-+        handlers = &null_handlers;
-+    }
-+    s->chr_can_read = handlers->fd_can_read;
-+    s->chr_read = handlers->fd_read;
-+    s->chr_event = handlers->fd_event;
-     s->handler_opaque = opaque;
-     if (s->chr_update_read_handler)
-         s->chr_update_read_handler(s);
-@@ -447,6 +454,12 @@ static void mux_chr_event(void *opaque, int event)
-         mux_chr_send_event(d, i, event);
- }
- 
-+static const QemuChrHandlers mux_chr_handlers = {
-+    .fd_can_read = mux_chr_can_read,
-+    .fd_read = mux_chr_read,
-+    .fd_event = mux_chr_event,
-+};
-+
- static void mux_chr_update_read_handler(CharDriverState *chr)
- {
-     MuxDriver *d = chr->opaque;
-@@ -461,8 +474,7 @@ static void mux_chr_update_read_handler(CharDriverState *chr)
-     d->chr_event[d->mux_cnt] = chr->chr_event;
-     /* Fix up the real driver with mux routines */
-     if (d->mux_cnt == 0) {
--        qemu_chr_add_handlers(d->drv, mux_chr_can_read, mux_chr_read,
--                              mux_chr_event, chr);
-+        qemu_chr_add_handlers(d->drv, &mux_chr_handlers, chr);
-     }
-     if (d->focus != -1) {
-         mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT);
-diff --git a/qemu-char.h b/qemu-char.h
-index f361c6d..b8372ea 100644
---- a/qemu-char.h
-+++ b/qemu-char.h
-@@ -1,6 +1,7 @@
- #ifndef QEMU_CHAR_H
- #define QEMU_CHAR_H
- 
-+#include <stdbool.h>
- #include "qemu-common.h"
- #include "qemu-queue.h"
- #include "qemu-option.h"
-@@ -77,6 +78,13 @@ struct CharDriverState {
-     QTAILQ_ENTRY(CharDriverState) next;
- };
- 
-+typedef struct QemuChrHandlers {
-+    IOCanReadHandler *fd_can_read;
-+    IOReadHandler *fd_read;
-+    IOHandler *fd_write_unblocked;
-+    IOEventHandler *fd_event;
-+} QemuChrHandlers;
-+
- QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename);
- CharDriverState *qemu_chr_open_opts(QemuOpts *opts,
-                                     void (*init)(struct CharDriverState *s));
-@@ -89,10 +97,7 @@ void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
-     GCC_FMT_ATTR(2, 3);
- int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len);
- void qemu_chr_send_event(CharDriverState *s, int event);
--void qemu_chr_add_handlers(CharDriverState *s,
--                           IOCanReadHandler *fd_can_read,
--                           IOReadHandler *fd_read,
--                           IOEventHandler *fd_event,
-+void qemu_chr_add_handlers(CharDriverState *s, const QemuChrHandlers *handlers,
-                            void *opaque);
- int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg);
- void qemu_chr_generic_open(CharDriverState *s);
-diff --git a/usb-redir.c b/usb-redir.c
-index e212993..e2b5a2c 100644
---- a/usb-redir.c
-+++ b/usb-redir.c
-@@ -782,6 +782,12 @@ static void usbredir_chardev_event(void *opaque, int event)
-     }
- }
- 
-+static const QemuChrHandlers usbredir_chr_handlers = {
-+    .fd_can_read = usbredir_chardev_can_read,
-+    .fd_read = usbredir_chardev_read,
-+    .fd_event = usbredir_chardev_event,
-+};
-+
- /*
-  * init + destroy
-  */
-@@ -807,8 +813,7 @@ static int usbredir_initfn(USBDevice *udev)
-     /* We'll do the attach once we receive the speed from the usb-host */
-     udev->auto_attach = 0;
- 
--    qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read,
--                          usbredir_chardev_read, usbredir_chardev_event, dev);
-+    qemu_chr_add_handlers(dev->cs, &usbredir_chr_handlers, dev);
- 
-     return 0;
- }
--- 
-1.7.5.1
-
diff --git a/0002-exec.c-Fix-subpage-memory-access-to-RAM-MemoryRegion.patch b/0002-exec.c-Fix-subpage-memory-access-to-RAM-MemoryRegion.patch
new file mode 100644
index 0000000..e49a049
--- /dev/null
+++ b/0002-exec.c-Fix-subpage-memory-access-to-RAM-MemoryRegion.patch
@@ -0,0 +1,134 @@
+From 2061800b85ddcc9b34b5ccbfaa87f7e8b94626a6 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Andreas=20F=C3=A4rber?= <afaerber@suse.de>
+Date: Wed, 30 Nov 2011 16:26:21 +0100
+Subject: [PATCH 02/25] exec.c: Fix subpage memory access to RAM MemoryRegion
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Commit 95c318f5e1f88d7e5bcc6deac17330fd4806a2d3 (Fix segfault in mmio
+subpage handling code.) prevented a segfault by making all subpage
+registrations over an existing memory page perform an unassigned access.
+Symptoms were writes not taking effect and reads returning zero.
+
+Very small page sizes are not currently supported either,
+so subpage memory areas cannot fully be avoided.
+
+Therefore change the previous fix to use a new IO_MEM_SUBPAGE_RAM
+instead of IO_MEM_UNASSIGNED. Suggested by Avi.
+
+Reviewed-by: Avi Kivity <avi@redhat.com>
+Signed-off-by: Andreas Färber <afaerber@suse.de>
+Cc: Avi Kivity <avi@redhat.com>
+Cc: Gleb Natapov <gleb@redhat.com>
+Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
+---
+ cpu-common.h |    1 +
+ exec.c       |   65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 64 insertions(+), 2 deletions(-)
+
+diff --git a/cpu-common.h b/cpu-common.h
+index c9878ba..3f45428 100644
+--- a/cpu-common.h
++++ b/cpu-common.h
+@@ -172,6 +172,7 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr,
+ #define IO_MEM_ROM         (1 << IO_MEM_SHIFT) /* hardcoded offset */
+ #define IO_MEM_UNASSIGNED  (2 << IO_MEM_SHIFT)
+ #define IO_MEM_NOTDIRTY    (3 << IO_MEM_SHIFT)
++#define IO_MEM_SUBPAGE_RAM (4 << IO_MEM_SHIFT)
+
+ /* Acts like a ROM when read and like a device when written.  */
+ #define IO_MEM_ROMD        (1)
+diff --git a/exec.c b/exec.c
+index 6b92198..6c206ff 100644
+--- a/exec.c
++++ b/exec.c
+@@ -3570,6 +3570,63 @@ static CPUWriteMemoryFunc * const subpage_write[] = {
+     &subpage_writel,
+ };
+
++static uint32_t subpage_ram_readb(void *opaque, target_phys_addr_t addr)
++{
++    ram_addr_t raddr = addr;
++    void *ptr = qemu_get_ram_ptr(raddr);
++    return ldub_p(ptr);
++}
++
++static void subpage_ram_writeb(void *opaque, target_phys_addr_t addr,
++                               uint32_t value)
++{
++    ram_addr_t raddr = addr;
++    void *ptr = qemu_get_ram_ptr(raddr);
++    stb_p(ptr, value);
++}
++
++static uint32_t subpage_ram_readw(void *opaque, target_phys_addr_t addr)
++{
++    ram_addr_t raddr = addr;
++    void *ptr = qemu_get_ram_ptr(raddr);
++    return lduw_p(ptr);
++}
++
++static void subpage_ram_writew(void *opaque, target_phys_addr_t addr,
++                               uint32_t value)
++{
++    ram_addr_t raddr = addr;
++    void *ptr = qemu_get_ram_ptr(raddr);
++    stw_p(ptr, value);
++}
++
++static uint32_t subpage_ram_readl(void *opaque, target_phys_addr_t addr)
++{
++    ram_addr_t raddr = addr;
++    void *ptr = qemu_get_ram_ptr(raddr);
++    return ldl_p(ptr);
++}
++
++static void subpage_ram_writel(void *opaque, target_phys_addr_t addr,
++                               uint32_t value)
++{
++    ram_addr_t raddr = addr;
++    void *ptr = qemu_get_ram_ptr(raddr);
++    stl_p(ptr, value);
++}
++
++static CPUReadMemoryFunc * const subpage_ram_read[] = {
++    &subpage_ram_readb,
++    &subpage_ram_readw,
++    &subpage_ram_readl,
++};
++
++static CPUWriteMemoryFunc * const subpage_ram_write[] = {
++    &subpage_ram_writeb,
++    &subpage_ram_writew,
++    &subpage_ram_writel,
++};
++
+ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
+                              ram_addr_t memory, ram_addr_t region_offset)
+ {
+@@ -3583,8 +3640,9 @@ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
+     printf("%s: %p start %08x end %08x idx %08x eidx %08x mem %ld\n", __func__,
+            mmio, start, end, idx, eidx, memory);
+ #endif
+-    if ((memory & ~TARGET_PAGE_MASK) == IO_MEM_RAM)
+-        memory = IO_MEM_UNASSIGNED;
++    if ((memory & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
++        memory = IO_MEM_SUBPAGE_RAM;
++    }
+     memory = (memory >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
+     for (; idx <= eidx; idx++) {
+         mmio->sub_io_index[idx] = memory;
+@@ -3817,6 +3875,9 @@ static void io_mem_init(void)
+     cpu_register_io_memory_fixed(IO_MEM_NOTDIRTY, error_mem_read,
+                                  notdirty_mem_write, NULL,
+                                  DEVICE_NATIVE_ENDIAN);
++    cpu_register_io_memory_fixed(IO_MEM_SUBPAGE_RAM, subpage_ram_read,
++                                 subpage_ram_write, NULL,
++                                 DEVICE_NATIVE_ENDIAN);
+     for (i=0; i<5; i++)
+         io_mem_used[i] = 1;
+
+-- 
+1.7.7.5
+
diff --git a/0003-hw-9pfs-Improve-portability-to-older-systems.patch b/0003-hw-9pfs-Improve-portability-to-older-systems.patch
new file mode 100644
index 0000000..4e91a9f
--- /dev/null
+++ b/0003-hw-9pfs-Improve-portability-to-older-systems.patch
@@ -0,0 +1,101 @@
+From f03969b952bc2aaf9f4445b6da28aebb0a9abde5 Mon Sep 17 00:00:00 2001
+From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
+Date: Sun, 4 Dec 2011 22:35:27 +0530
+Subject: [PATCH 03/25] hw/9pfs: Improve portability to older systems
+
+handle fs driver require a set of newly added syscalls. Don't
+Compile handle FS driver if those syscalls are not available.
+Instead of adding #ifdef for all those syscalls we check for
+open by handle syscall. If that is available then rest of the
+syscalls used by the driver should be available.
+
+Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+---
+ Makefile.objs              |    4 ++--
+ fsdev/qemu-fsdev.c         |    2 ++
+ hw/9pfs/virtio-9p-handle.c |   33 ---------------------------------
+ 3 files changed, 4 insertions(+), 35 deletions(-)
+
+diff --git a/Makefile.objs b/Makefile.objs
+index d7a6539..3a699ee 100644
+--- a/Makefile.objs
++++ b/Makefile.objs
+@@ -310,8 +310,8 @@ hw-obj-$(CONFIG_SOUND) += $(sound-obj-y)
+ 9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-local.o virtio-9p-xattr.o
+ 9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-xattr-user.o virtio-9p-posix-acl.o
+ 9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-coth.o cofs.o codir.o cofile.o
+-9pfs-nested-$(CONFIG_VIRTFS) += coxattr.o virtio-9p-handle.o
+-9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-synth.o
++9pfs-nested-$(CONFIG_VIRTFS) += coxattr.o virtio-9p-synth.o
++9pfs-nested-$(CONFIG_OPEN_BY_HANDLE) +=  virtio-9p-handle.o
+
+ hw-obj-$(CONFIG_REALLY_VIRTFS) += $(addprefix 9pfs/, $(9pfs-nested-y))
+ $(addprefix 9pfs/, $(9pfs-nested-y)): QEMU_CFLAGS+=$(GLIB_CFLAGS)
+diff --git a/fsdev/qemu-fsdev.c b/fsdev/qemu-fsdev.c
+index 7fd2aa7..6684f7e 100644
+--- a/fsdev/qemu-fsdev.c
++++ b/fsdev/qemu-fsdev.c
+@@ -23,7 +23,9 @@ static QTAILQ_HEAD(FsDriverEntry_head, FsDriverListEntry) fsdriver_entries =
+
+ static FsDriverTable FsDrivers[] = {
+     { .name = "local", .ops = &local_ops},
++#ifdef CONFIG_OPEN_BY_HANDLE
+     { .name = "handle", .ops = &handle_ops},
++#endif
+     { .name = "synth", .ops = &synth_ops},
+ };
+
+diff --git a/hw/9pfs/virtio-9p-handle.c b/hw/9pfs/virtio-9p-handle.c
+index 7644ae5..a62f690 100644
+--- a/hw/9pfs/virtio-9p-handle.c
++++ b/hw/9pfs/virtio-9p-handle.c
+@@ -45,7 +45,6 @@ struct handle_data {
+     int handle_bytes;
+ };
+
+-#ifdef CONFIG_OPEN_BY_HANDLE
+ static inline int name_to_handle(int dirfd, const char *name,
+                                  struct file_handle *fh, int *mnt_id, int flags)
+ {
+@@ -56,38 +55,6 @@ static inline int open_by_handle(int mountfd, const char *fh, int flags)
+ {
+     return open_by_handle_at(mountfd, (struct file_handle *)fh, flags);
+ }
+-#else
+-
+-struct rpl_file_handle {
+-    unsigned int handle_bytes;
+-    int handle_type;
+-    unsigned char handle[0];
+-};
+-#define file_handle rpl_file_handle
+-
+-#ifndef AT_REMOVEDIR
+-#define AT_REMOVEDIR    0x200
+-#endif
+-#ifndef AT_EMPTY_PATH
+-#define AT_EMPTY_PATH   0x1000  /* Allow empty relative pathname */
+-#endif
+-#ifndef O_PATH
+-#define O_PATH    010000000
+-#endif
+-
+-static inline int name_to_handle(int dirfd, const char *name,
+-                                 struct file_handle *fh, int *mnt_id, int flags)
+-{
+-    errno = ENOSYS;
+-    return -1;
+-}
+-
+-static inline int open_by_handle(int mountfd, const char *fh, int flags)
+-{
+-    errno = ENOSYS;
+-    return -1;
+-}
+-#endif
+
+ static int handle_update_file_cred(int dirfd, const char *name, FsCred *credp)
+ {
+-- 
+1.7.7.5
+
diff --git a/0003-iohandlers-Add-enable-disable_write_fd_handler-funct.patch b/0003-iohandlers-Add-enable-disable_write_fd_handler-funct.patch
deleted file mode 100644
index 92d01aa..0000000
--- a/0003-iohandlers-Add-enable-disable_write_fd_handler-funct.patch
+++ /dev/null
@@ -1,77 +0,0 @@
->From c8cf564bc5c080540287ecd5bd944d85873755df Mon Sep 17 00:00:00 2001
-From: Amit Shah <amit.shah@redhat.com>
-Date: Mon, 21 Mar 2011 20:32:58 +0100
-Subject: [PATCH 03/28] iohandlers: Add enable/disable_write_fd_handler()
- functions
-
-These will be used to provide a cleaner API for the nonblocking case.
-
-Signed-off-by: Amit Shah <amit.shah@redhat.com>
----
- iohandler.c |   35 +++++++++++++++++++++++++++++++++++
- qemu-char.h |    3 +++
- 2 files changed, 38 insertions(+), 0 deletions(-)
-
-diff --git a/iohandler.c b/iohandler.c
-index 2b82421..8e6628b 100644
---- a/iohandler.c
-+++ b/iohandler.c
-@@ -44,6 +44,41 @@ typedef struct IOHandlerRecord {
- static QLIST_HEAD(, IOHandlerRecord) io_handlers =
-     QLIST_HEAD_INITIALIZER(io_handlers);
- 
-+static IOHandlerRecord *find_iohandler(int fd)
-+{
-+    IOHandlerRecord *ioh;
-+
-+    QLIST_FOREACH(ioh, &io_handlers, next) {
-+        if (ioh->fd == fd) {
-+            return ioh;
-+        }
-+    }
-+    return NULL;
-+}
-+
-+void enable_write_fd_handler(int fd, IOHandler *fd_write)
-+{
-+    IOHandlerRecord *ioh;
-+
-+    ioh = find_iohandler(fd);
-+    if (!ioh) {
-+        return;
-+    }
-+
-+    ioh->fd_write = fd_write;
-+}
-+
-+void disable_write_fd_handler(int fd)
-+{
-+    IOHandlerRecord *ioh;
-+
-+    ioh = find_iohandler(fd);
-+    if (!ioh) {
-+        return;
-+    }
-+
-+    ioh->fd_write = NULL;
-+}
- 
- /* XXX: fd_read_poll should be suppressed, but an API change is
-    necessary in the character devices to suppress fd_can_read(). */
-diff --git a/qemu-char.h b/qemu-char.h
-index b8372ea..9fe1b82 100644
---- a/qemu-char.h
-+++ b/qemu-char.h
-@@ -123,6 +123,9 @@ size_t qemu_chr_mem_osize(const CharDriverState *chr);
- 
- /* async I/O support */
- 
-+void enable_write_fd_handler(int fd, IOHandler *fd_write);
-+void disable_write_fd_handler(int fd);
-+
- int qemu_set_fd_handler2(int fd,
-                          IOCanReadHandler *fd_read_poll,
-                          IOHandler *fd_read,
--- 
-1.7.5.1
-
diff --git a/0004-char-Add-framework-for-a-write-unblocked-callback.patch b/0004-char-Add-framework-for-a-write-unblocked-callback.patch
deleted file mode 100644
index c4bd019..0000000
--- a/0004-char-Add-framework-for-a-write-unblocked-callback.patch
+++ /dev/null
@@ -1,61 +0,0 @@
->From 3ad2ca8e46ba078e69254ca5886de89b30f823bb Mon Sep 17 00:00:00 2001
-From: Amit Shah <amit.shah@redhat.com>
-Date: Mon, 21 Mar 2011 21:41:42 +0100
-Subject: [PATCH 04/28] char: Add framework for a 'write unblocked' callback
-
-The char layer can let users know that the driver will block on further
-input.  For users interested in not blocking, they can assign a function
-pointer that will be called back when the driver becomes writable.  This
-patch just adds the function pointers to the CharDriverState structure,
-future patches will enable the nonblocking and callback functionality.
-
-Signed-off-by: Amit Shah <amit.shah@redhat.com>
----
- qemu-char.c |    3 +++
- qemu-char.h |    4 ++++
- 2 files changed, 7 insertions(+), 0 deletions(-)
-
-diff --git a/qemu-char.c b/qemu-char.c
-index 52bcc0e..bc07b20 100644
---- a/qemu-char.c
-+++ b/qemu-char.c
-@@ -214,11 +214,14 @@ void qemu_chr_add_handlers(CharDriverState *s,
-     }
-     s->chr_can_read = handlers->fd_can_read;
-     s->chr_read = handlers->fd_read;
-+    s->chr_write_unblocked = handlers->fd_write_unblocked;
-     s->chr_event = handlers->fd_event;
-     s->handler_opaque = opaque;
-     if (s->chr_update_read_handler)
-         s->chr_update_read_handler(s);
- 
-+    s->write_blocked = false;
-+
-     /* We're connecting to an already opened device, so let's make sure we
-        also get the open event */
-     if (s->opened) {
-diff --git a/qemu-char.h b/qemu-char.h
-index 9fe1b82..68e7b5b 100644
---- a/qemu-char.h
-+++ b/qemu-char.h
-@@ -62,6 +62,9 @@ struct CharDriverState {
-     IOEventHandler *chr_event;
-     IOCanReadHandler *chr_can_read;
-     IOReadHandler *chr_read;
-+    IOHandler *chr_write_unblocked;
-+    void (*chr_enable_write_fd_handler)(struct CharDriverState *chr);
-+    void (*chr_disable_write_fd_handler)(struct CharDriverState *chr);
-     void *handler_opaque;
-     void (*chr_send_event)(struct CharDriverState *chr, int event);
-     void (*chr_close)(struct CharDriverState *chr);
-@@ -75,6 +78,7 @@ struct CharDriverState {
-     char *filename;
-     int opened;
-     int avail_connections;
-+    bool write_blocked; /* Are we in a blocked state? */
-     QTAILQ_ENTRY(CharDriverState) next;
- };
- 
--- 
-1.7.5.1
-
diff --git a/0004-hw-9pfs-use-migration-blockers-to-prevent-live-migra.patch b/0004-hw-9pfs-use-migration-blockers-to-prevent-live-migra.patch
new file mode 100644
index 0000000..a63b9e1
--- /dev/null
+++ b/0004-hw-9pfs-use-migration-blockers-to-prevent-live-migra.patch
@@ -0,0 +1,171 @@
+From 77a02621812952acfde887244f6f480de1b51f95 Mon Sep 17 00:00:00 2001
+From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
+Date: Sun, 4 Dec 2011 22:35:28 +0530
+Subject: [PATCH 04/25] hw/9pfs: use migration blockers to prevent live
+ migration when virtfs export path is mounted
+
+Now when you try to migrate with VirtFS export path mounted, you get a proper QMP error:
+
+(qemu) migrate tcp:localhost:4444
+Migration is disabled when VirtFS export path '/tmp/' is mounted in the guest using mount_tag 'v_tmp'
+(qemu)
+
+Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+---
+ hw/9pfs/virtio-9p-device.c |   22 +++++++++++-----------
+ hw/9pfs/virtio-9p.c        |   19 +++++++++++++++++++
+ hw/9pfs/virtio-9p.h        |    5 +++--
+ qerror.c                   |    5 +++++
+ qerror.h                   |    3 +++
+ 5 files changed, 41 insertions(+), 13 deletions(-)
+
+diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
+index bba4c54..c9bca8b 100644
+--- a/hw/9pfs/virtio-9p-device.c
++++ b/hw/9pfs/virtio-9p-device.c
+@@ -33,13 +33,15 @@ static V9fsState *to_virtio_9p(VirtIODevice *vdev)
+
+ static void virtio_9p_get_config(VirtIODevice *vdev, uint8_t *config)
+ {
++    int len;
+     struct virtio_9p_config *cfg;
+     V9fsState *s = to_virtio_9p(vdev);
+
+-    cfg = g_malloc0(sizeof(struct virtio_9p_config) +
+-                        s->tag_len);
+-    stw_raw(&cfg->tag_len, s->tag_len);
+-    memcpy(cfg->tag, s->tag, s->tag_len);
++    len = strlen(s->tag);
++    cfg = g_malloc0(sizeof(struct virtio_9p_config) + len);
++    stw_raw(&cfg->tag_len, len);
++    /* We don't copy the terminating null to config space */
++    memcpy(cfg->tag, s->tag, len);
+     memcpy(config, cfg, s->config_size);
+     g_free(cfg);
+ }
+@@ -96,20 +98,18 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
+     }
+
+     len = strlen(conf->tag);
+-    if (len > MAX_TAG_LEN) {
++    if (len > MAX_TAG_LEN - 1) {
+         fprintf(stderr, "mount tag '%s' (%d bytes) is longer than "
+-                "maximum (%d bytes)", conf->tag, len, MAX_TAG_LEN);
++                "maximum (%d bytes)", conf->tag, len, MAX_TAG_LEN - 1);
+         exit(1);
+     }
+-    /* s->tag is non-NULL terminated string */
+-    s->tag = g_malloc(len);
+-    memcpy(s->tag, conf->tag, len);
+-    s->tag_len = len;
++
++    s->tag = strdup(conf->tag);
+     s->ctx.uid = -1;
+
+     s->ops = fse->ops;
+     s->vdev.get_features = virtio_9p_get_features;
+-    s->config_size = sizeof(struct virtio_9p_config) + s->tag_len;
++    s->config_size = sizeof(struct virtio_9p_config) + len;
+     s->vdev.get_config = virtio_9p_get_config;
+     s->fid_list = NULL;
+     qemu_co_rwlock_init(&s->rename_lock);
+diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
+index 1b2fc5d..32b98dd 100644
+--- a/hw/9pfs/virtio-9p.c
++++ b/hw/9pfs/virtio-9p.c
+@@ -23,6 +23,7 @@
+ #include "virtio-9p-xattr.h"
+ #include "virtio-9p-coth.h"
+ #include "trace.h"
++#include "migration.h"
+
+ int open_fd_hw;
+ int total_open_fd;
+@@ -373,6 +374,19 @@ static void put_fid(V9fsPDU *pdu, V9fsFidState *fidp)
+      * Don't free the fid if it is in reclaim list
+      */
+     if (!fidp->ref && fidp->clunked) {
++        if (fidp->fid == pdu->s->root_fid) {
++            /*
++             * if the clunked fid is root fid then we
++             * have unmounted the fs on the client side.
++             * delete the migration blocker. Ideally, this
++             * should be hooked to transport close notification
++             */
++            if (pdu->s->migration_blocker) {
++                migrate_del_blocker(pdu->s->migration_blocker);
++                error_free(pdu->s->migration_blocker);
++                pdu->s->migration_blocker = NULL;
++            }
++        }
+         free_fid(pdu, fidp);
+     }
+ }
+@@ -1235,6 +1249,11 @@ static void v9fs_attach(void *opaque)
+     err = offset;
+     trace_v9fs_attach_return(pdu->tag, pdu->id,
+                              qid.type, qid.version, qid.path);
++    s->root_fid = fid;
++    /* disable migration */
++    error_set(&s->migration_blocker, QERR_VIRTFS_FEATURE_BLOCKS_MIGRATION,
++              s->ctx.fs_root, s->tag);
++    migrate_add_blocker(s->migration_blocker);
+ out:
+     put_fid(pdu, fidp);
+ out_nofid:
+diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
+index 7f88356..8b612da 100644
+--- a/hw/9pfs/virtio-9p.h
++++ b/hw/9pfs/virtio-9p.h
+@@ -246,8 +246,7 @@ typedef struct V9fsState
+     V9fsFidState *fid_list;
+     FileOperations *ops;
+     FsContext ctx;
+-    uint16_t tag_len;
+-    uint8_t *tag;
++    char *tag;
+     size_t config_size;
+     enum p9_proto_version proto_version;
+     int32_t msize;
+@@ -256,6 +255,8 @@ typedef struct V9fsState
+      * on rename.
+      */
+     CoRwlock rename_lock;
++    int32_t root_fid;
++    Error *migration_blocker;
+ } V9fsState;
+
+ typedef struct V9fsStatState {
+diff --git a/qerror.c b/qerror.c
+index fdf62b9..25bc91e 100644
+--- a/qerror.c
++++ b/qerror.c
+@@ -235,6 +235,11 @@ static const QErrorStringTable qerror_table[] = {
+                      "supported by this qemu version: %(feature)",
+     },
+     {
++        .error_fmt = QERR_VIRTFS_FEATURE_BLOCKS_MIGRATION,
++        .desc      = "Migration is disabled when VirtFS export path '%(path)' "
++                     "is mounted in the guest using mount_tag '%(tag)'",
++    },
++    {
+         .error_fmt = QERR_VNC_SERVER_FAILED,
+         .desc      = "Could not start VNC server on %(target)",
+     },
+diff --git a/qerror.h b/qerror.h
+index 2d3d43b..6414cd9 100644
+--- a/qerror.h
++++ b/qerror.h
+@@ -192,6 +192,9 @@ QError *qobject_to_qerror(const QObject *obj);
+ #define QERR_UNKNOWN_BLOCK_FORMAT_FEATURE \
+     "{ 'class': 'UnknownBlockFormatFeature', 'data': { 'device': %s, 'format': %s, 'feature': %s } }"
+
++#define QERR_VIRTFS_FEATURE_BLOCKS_MIGRATION \
++    "{ 'class': 'VirtFSFeatureBlocksMigration', 'data': { 'path': %s, 'tag': %s } }"
++
+ #define QERR_VNC_SERVER_FAILED \
+     "{ 'class': 'VNCServerFailed', 'data': { 'target': %s } }"
+
+-- 
+1.7.7.5
+
diff --git a/0005-char-Update-send_all-to-handle-nonblocking-chardev-w.patch b/0005-char-Update-send_all-to-handle-nonblocking-chardev-w.patch
deleted file mode 100644
index 383ba63..0000000
--- a/0005-char-Update-send_all-to-handle-nonblocking-chardev-w.patch
+++ /dev/null
@@ -1,199 +0,0 @@
->From a962453ed73a671f566cc94858dc21ab694cc85f Mon Sep 17 00:00:00 2001
-From: Amit Shah <amit.shah@redhat.com>
-Date: Mon, 21 Mar 2011 22:00:27 +0100
-Subject: [PATCH 05/28] char: Update send_all() to handle nonblocking chardev
- write requests
-
-The send_all function is modified to return to the caller in case the
-driver cannot handle any more data.  It returns -EAGAIN or
-WSAEWOULDBLOCK on non-Windows and Windows platforms respectively.  This
-is only done when the caller sets a callback function handler indicating
-it's not interested in blocking till the driver has written out all the
-data.
-
-Currently there's no driver or caller that supports this.  Future
-commits will add such capability.
-
-Signed-off-by: Amit Shah <amit.shah@redhat.com>
----
- net/socket.c  |    4 +-
- qemu-char.c   |   80 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
- qemu_socket.h |    2 +-
- 3 files changed, 77 insertions(+), 9 deletions(-)
-
-diff --git a/net/socket.c b/net/socket.c
-index 11fe5f3..14706fc 100644
---- a/net/socket.c
-+++ b/net/socket.c
-@@ -56,8 +56,8 @@ static ssize_t net_socket_receive(VLANClientState *nc, const uint8_t *buf, size_
-     uint32_t len;
-     len = htonl(size);
- 
--    send_all(s->fd, (const uint8_t *)&len, sizeof(len));
--    return send_all(s->fd, buf, size);
-+    send_all(NULL, s->fd, (const uint8_t *)&len, sizeof(len));
-+    return send_all(NULL, s->fd, buf, size);
- }
- 
- static ssize_t net_socket_receive_dgram(VLANClientState *nc, const uint8_t *buf, size_t size)
-diff --git a/qemu-char.c b/qemu-char.c
-index bc07b20..5dbf063 100644
---- a/qemu-char.c
-+++ b/qemu-char.c
-@@ -513,7 +513,7 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
- 
- 
- #ifdef _WIN32
--int send_all(int fd, const void *buf, int len1)
-+static int do_send(int fd, const void *buf, int len1, bool nonblock)
- {
-     int ret, len;
- 
-@@ -521,9 +521,14 @@ int send_all(int fd, const void *buf, int len1)
-     while (len > 0) {
-         ret = send(fd, buf, len, 0);
-         if (ret < 0) {
-+            if (nonblock && len1 - len) {
-+                return len1 - len;
-+            }
-             errno = WSAGetLastError();
-             if (errno != WSAEWOULDBLOCK) {
-                 return -1;
-+            } else if (errno == WSAEWOULDBLOCK && nonblock) {
-+                return WSAEWOULDBLOCK;
-             }
-         } else if (ret == 0) {
-             break;
-@@ -537,7 +542,7 @@ int send_all(int fd, const void *buf, int len1)
- 
- #else
- 
--int send_all(int fd, const void *_buf, int len1)
-+static int do_send(int fd, const void *_buf, int len1, bool nonblock)
- {
-     int ret, len;
-     const uint8_t *buf = _buf;
-@@ -546,8 +551,15 @@ int send_all(int fd, const void *_buf, int len1)
-     while (len > 0) {
-         ret = write(fd, buf, len);
-         if (ret < 0) {
--            if (errno != EINTR && errno != EAGAIN)
-+            if (nonblock && len1 - len) {
-+                return len1 - len;
-+            }
-+            if (errno == EAGAIN && nonblock) {
-+                return -EAGAIN;
-+            }
-+            if (errno != EINTR && errno != EAGAIN) {
-                 return -1;
-+            }
-         } else if (ret == 0) {
-             break;
-         } else {
-@@ -559,6 +571,55 @@ int send_all(int fd, const void *_buf, int len1)
- }
- #endif /* !_WIN32 */
- 
-+int send_all(CharDriverState *chr, int fd, const void *_buf, int len1)
-+{
-+    int ret, eagain_errno;
-+    bool nonblock;
-+
-+    if (chr && chr->write_blocked) {
-+        /*
-+         * We don't handle this situation: the caller should not send
-+         * us data while we're blocked.
-+         *
-+         * We could buffer this data here but that'll only encourage
-+         * bad behaviour on part of the callers.
-+         *
-+         * Also, the data already in fd's buffers isn't easily
-+         * migratable.  If we want full migration support, all the
-+         * data landing here needs to be buffered and on migration,
-+         * anything that's unsent needs to be transferred to the
-+         * dest. machine (which again isn't a very good way of solving
-+         * the problem, as the src may become writable just during
-+         * migration and the reader could receive some data twice,
-+         * essentially corrupting the data).
-+         */
-+        abort();
-+    }
-+
-+    nonblock = false;
-+    /*
-+     * Ensure the char backend is able to receive and handle the
-+     * 'write unblocked' event before we turn on nonblock support.
-+     */
-+    if (chr && chr->chr_enable_write_fd_handler && chr->chr_write_unblocked) {
-+        nonblock = true;
-+    }
-+    ret = do_send(fd, _buf, len1, nonblock);
-+
-+#ifdef _WIN32
-+    eagain_errno = WSAEWOULDBLOCK;
-+#else
-+    eagain_errno = -EAGAIN;
-+#endif
-+
-+    if (nonblock && (ret == eagain_errno || (ret >= 0 && ret < len1))) {
-+        /* Update fd handler to wake up when chr becomes writable */
-+        chr->chr_enable_write_fd_handler(chr);
-+        chr->write_blocked = true;
-+    }
-+    return ret;
-+}
-+
- #ifndef _WIN32
- 
- typedef struct {
-@@ -572,7 +633,7 @@ static int stdio_nb_clients = 0;
- static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
- {
-     FDCharDriver *s = chr->opaque;
--    return send_all(s->fd_out, buf, len);
-+    return send_all(chr, s->fd_out, buf, len);
- }
- 
- static int fd_chr_read_poll(void *opaque)
-@@ -897,7 +958,7 @@ static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
-         pty_chr_update_read_handler(chr);
-         return 0;
-     }
--    return send_all(s->fd, buf, len);
-+    return send_all(chr, s->fd, buf, len);
- }
- 
- static int pty_chr_read_poll(void *opaque)
-@@ -1979,8 +2040,15 @@ static void tcp_closed(void *opaque)
- static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
- {
-     TCPCharDriver *s = chr->opaque;
-+
-     if (s->connected) {
--        return send_all(s->fd, buf, len);
-+        int ret;
-+
-+        ret = send_all(chr, s->fd, buf, len);
-+        if (ret == -1 && errno == EPIPE) {
-+            tcp_closed(chr);
-+        }
-+        return ret;
-     } else {
-         /* XXX: indicate an error ? */
-         return len;
-diff --git a/qemu_socket.h b/qemu_socket.h
-index 180e4db..6f453e5 100644
---- a/qemu_socket.h
-+++ b/qemu_socket.h
-@@ -36,7 +36,7 @@ int inet_aton(const char *cp, struct in_addr *ia);
- int qemu_socket(int domain, int type, int protocol);
- int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
- void socket_set_nonblock(int fd);
--int send_all(int fd, const void *buf, int len1);
-+int send_all(CharDriverState *chr, int fd, const void *buf, int len1);
- 
- /* New, ipv6-ready socket helper functions, see qemu-sockets.c */
- int inet_listen_opts(QemuOpts *opts, int port_offset);
--- 
-1.7.5.1
-
diff --git a/0005-hw-9pfs-Reset-server-state-during-TVERSION.patch b/0005-hw-9pfs-Reset-server-state-during-TVERSION.patch
new file mode 100644
index 0000000..585b7cc
--- /dev/null
+++ b/0005-hw-9pfs-Reset-server-state-during-TVERSION.patch
@@ -0,0 +1,64 @@
+From c554919f74e5a79f15360c4c2f417003477634cf Mon Sep 17 00:00:00 2001
+From: Deepak C Shetty <deepakcs@linux.vnet.ibm.com>
+Date: Sun, 4 Dec 2011 22:35:28 +0530
+Subject: [PATCH 05/25] hw/9pfs: Reset server state during TVERSION
+
+As per the 9p rfc, during TVERSION its necessary to clean all the active
+fids, so that we start the session from a clean state. Its also needed in
+scenarios where the guest is booting off 9p, and boot fails, and client
+restarts, without any knowledge of the past, it will issue a TVERSION again
+so this ensures that we always start from a clean state.
+
+Signed-off-by: Deepak C Shetty <deepakcs@linux.vnet.ibm.com>
+Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+---
+ hw/9pfs/virtio-9p.c |   26 ++++++++++++++++++++++++++
+ 1 files changed, 26 insertions(+), 0 deletions(-)
+
+diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
+index 32b98dd..dd43209 100644
+--- a/hw/9pfs/virtio-9p.c
++++ b/hw/9pfs/virtio-9p.c
+@@ -523,6 +523,30 @@ static int v9fs_mark_fids_unreclaim(V9fsPDU *pdu, V9fsPath *path)
+     return 0;
+ }
+
++static void virtfs_reset(V9fsPDU *pdu)
++{
++    V9fsState *s = pdu->s;
++    V9fsFidState *fidp = NULL;
++
++    /* Free all fids */
++    while (s->fid_list) {
++        fidp = s->fid_list;
++        s->fid_list = fidp->next;
++
++        if (fidp->ref) {
++            fidp->clunked = 1;
++        } else {
++            free_fid(pdu, fidp);
++        }
++    }
++    if (fidp) {
++        /* One or more unclunked fids found... */
++        error_report("9pfs:%s: One or more uncluncked fids "
++                     "found during reset", __func__);
++    }
++    return;
++}
++
+ #define P9_QID_TYPE_DIR         0x80
+ #define P9_QID_TYPE_SYMLINK     0x02
+
+@@ -1196,6 +1220,8 @@ static void v9fs_version(void *opaque)
+     pdu_unmarshal(pdu, offset, "ds", &s->msize, &version);
+     trace_v9fs_version(pdu->tag, pdu->id, s->msize, version.data);
+
++    virtfs_reset(pdu);
++
+     if (!strcmp(version.data, "9P2000.u")) {
+         s->proto_version = V9FS_PROTO_2000U;
+     } else if (!strcmp(version.data, "9P2000.L")) {
+-- 
+1.7.7.5
+
diff --git a/0006-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch b/0006-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch
deleted file mode 100644
index 49bf64d..0000000
--- a/0006-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch
+++ /dev/null
@@ -1,81 +0,0 @@
->From 5fc1c0fc4c8153ea927aa8580c78c484f966be64 Mon Sep 17 00:00:00 2001
-From: Amit Shah <amit.shah@redhat.com>
-Date: Mon, 21 Mar 2011 22:02:47 +0100
-Subject: [PATCH 06/28] char: Equip the unix/tcp backend to handle nonblocking
- writes#
-
-Now that the infrastructure is in place to return -EAGAIN to callers,
-individual char drivers can set their update_fd_handlers() function to
-set or remove an fd's write handler.  This handler checks if the driver
-became writable.
-
-A generic callback routine is used for unblocking writes and letting
-users of chardevs know that a driver became writable again.
-
-Signed-off-by: Amit Shah <amit.shah@redhat.com>
----
- qemu-char.c |   34 ++++++++++++++++++++++++++++++++++
- 1 files changed, 34 insertions(+), 0 deletions(-)
-
-diff --git a/qemu-char.c b/qemu-char.c
-index 5dbf063..f54ce04 100644
---- a/qemu-char.c
-+++ b/qemu-char.c
-@@ -106,6 +106,19 @@
- static QTAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs =
-     QTAILQ_HEAD_INITIALIZER(chardevs);
- 
-+/*
-+ * Generic routine that gets called when chardev becomes writable.
-+ * Lets chardev user know it's OK to send more data.
-+ */
-+static void char_write_unblocked(void *opaque)
-+{
-+    CharDriverState *chr = opaque;
-+
-+    chr->write_blocked = false;
-+    chr->chr_disable_write_fd_handler(chr);
-+    chr->chr_write_unblocked(chr->handler_opaque);
-+}
-+
- static void qemu_chr_event(CharDriverState *s, int event)
- {
-     /* Keep track if the char device is open */
-@@ -2309,6 +2322,25 @@ static void tcp_chr_close(CharDriverState *chr)
-     qemu_chr_event(chr, CHR_EVENT_CLOSED);
- }
- 
-+static void tcp_enable_write_fd_handler(CharDriverState *chr)
-+{
-+    TCPCharDriver *s = chr->opaque;
-+
-+    /*
-+     * This function is called only after tcp_chr_connect() is called
-+     * (either in 'server' mode or client mode.  So we're sure of
-+     * s->fd being initialised.
-+     */
-+    enable_write_fd_handler(s->fd, char_write_unblocked);
-+}
-+
-+static void tcp_disable_write_fd_handler(CharDriverState *chr)
-+{
-+    TCPCharDriver *s = chr->opaque;
-+
-+    disable_write_fd_handler(s->fd);
-+}
-+
- static int qemu_chr_open_socket(QemuOpts *opts, CharDriverState **_chr)
- {
-     CharDriverState *chr = NULL;
-@@ -2365,6 +2397,8 @@ static int qemu_chr_open_socket(QemuOpts *opts, CharDriverState **_chr)
-     chr->chr_close = tcp_chr_close;
-     chr->get_msgfd = tcp_get_msgfd;
-     chr->chr_add_client = tcp_chr_add_client;
-+    chr->chr_enable_write_fd_handler = tcp_enable_write_fd_handler;
-+    chr->chr_disable_write_fd_handler = tcp_disable_write_fd_handler;
- 
-     if (is_listen) {
-         s->listen_fd = fd;
--- 
-1.7.5.1
-
diff --git a/0006-hw-9pfs-Add-qdev.reset-callback-for-virtio-9p-pci-de.patch b/0006-hw-9pfs-Add-qdev.reset-callback-for-virtio-9p-pci-de.patch
new file mode 100644
index 0000000..aa49abb
--- /dev/null
+++ b/0006-hw-9pfs-Add-qdev.reset-callback-for-virtio-9p-pci-de.patch
@@ -0,0 +1,57 @@
+From 64dd41bc2de392fa018c5ce804cc451b83f18b94 Mon Sep 17 00:00:00 2001
+From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
+Date: Sun, 4 Dec 2011 22:35:28 +0530
+Subject: [PATCH 06/25] hw/9pfs: Add qdev.reset callback for virtio-9p-pci
+ device
+
+Add the device reset callback
+
+Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+---
+ hw/9pfs/virtio-9p-device.c |    3 ++-
+ hw/virtio-pci.c            |    2 +-
+ hw/virtio-pci.h            |    1 +
+ 3 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
+index c9bca8b..cd343e1 100644
+--- a/hw/9pfs/virtio-9p-device.c
++++ b/hw/9pfs/virtio-9p-device.c
+@@ -176,7 +176,8 @@ static PCIDeviceInfo virtio_9p_info = {
+         DEFINE_PROP_STRING("mount_tag", VirtIOPCIProxy, fsconf.tag),
+         DEFINE_PROP_STRING("fsdev", VirtIOPCIProxy, fsconf.fsdev_id),
+         DEFINE_PROP_END_OF_LIST(),
+-    }
++    },
++    .qdev.reset = virtio_pci_reset,
+ };
+
+ static void virtio_9p_register_devices(void)
+diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
+index 64c6a94..c665f5c 100644
+--- a/hw/virtio-pci.c
++++ b/hw/virtio-pci.c
+@@ -266,7 +266,7 @@ static void virtio_pci_stop_ioeventfd(VirtIOPCIProxy *proxy)
+     proxy->ioeventfd_started = false;
+ }
+
+-static void virtio_pci_reset(DeviceState *d)
++void virtio_pci_reset(DeviceState *d)
+ {
+     VirtIOPCIProxy *proxy = container_of(d, VirtIOPCIProxy, pci_dev.qdev);
+     virtio_pci_stop_ioeventfd(proxy);
+diff --git a/hw/virtio-pci.h b/hw/virtio-pci.h
+index f8404de..344c22b 100644
+--- a/hw/virtio-pci.h
++++ b/hw/virtio-pci.h
+@@ -45,6 +45,7 @@ typedef struct {
+ } VirtIOPCIProxy;
+
+ void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev);
++void virtio_pci_reset(DeviceState *d);
+
+ /* Virtio ABI version, if we increment this, we break the guest driver. */
+ #define VIRTIO_PCI_ABI_VERSION          0
+-- 
+1.7.7.5
+
diff --git a/0007-char-Throttle-when-host-connection-is-down.patch b/0007-char-Throttle-when-host-connection-is-down.patch
deleted file mode 100644
index 7a131d8..0000000
--- a/0007-char-Throttle-when-host-connection-is-down.patch
+++ /dev/null
@@ -1,56 +0,0 @@
->From 5121e48706408e28c811e74d3e6da5b78aa9137d Mon Sep 17 00:00:00 2001
-From: Amit Shah <amit.shah@redhat.com>
-Date: Mon, 21 Mar 2011 22:05:10 +0100
-Subject: [PATCH 07/28] char: Throttle when host connection is down#
-
-When the host-side connection goes down, throttle the virtio-serial bus
-and later unthrottle when a connection gets established.  This helps
-prevent any lost IO (guest->host) while the host connection was down.
-
-Bugzilla: 621484
-
-This commit actually helps the bug mentioned above as no writes will now
-get lost because of the throttling done here.  With just the patches
-sent earlier for that bug, one write will end up getting lost in the
-worst case (host d/c, guest write, host connect).
-
-Signed-off-by: Amit Shah <amit.shah@redhat.com>
----
- qemu-char.c |   14 ++++++++++++++
- 1 files changed, 14 insertions(+), 0 deletions(-)
-
-diff --git a/qemu-char.c b/qemu-char.c
-index f54ce04..8d39500 100644
---- a/qemu-char.c
-+++ b/qemu-char.c
-@@ -140,6 +140,9 @@ static void qemu_chr_generic_open_bh(void *opaque)
- {
-     CharDriverState *s = opaque;
-     qemu_chr_event(s, CHR_EVENT_OPENED);
-+    if (s->write_blocked) {
-+        char_write_unblocked(s);
-+    }
-     qemu_bh_delete(s->bh);
-     s->bh = NULL;
- }
-@@ -2060,6 +2063,17 @@ static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
-         ret = send_all(chr, s->fd, buf, len);
-         if (ret == -1 && errno == EPIPE) {
-             tcp_closed(chr);
-+
-+            if (chr->chr_enable_write_fd_handler && chr->chr_write_unblocked) {
-+                /*
-+                 * Since we haven't written out anything, let's say
-+                 * we're throttled.  This will prevent any output from
-+                 * the guest getting lost if host-side chardev goes
-+                 * down.  Unthrottle when we re-connect.
-+                 */
-+                chr->write_blocked = true;
-+                return 0;
-+            }
-         }
-         return ret;
-     } else {
--- 
-1.7.5.1
-
diff --git a/0007-hw-9pfs-Use-the-correct-file-descriptor-in-Fsdriver-.patch b/0007-hw-9pfs-Use-the-correct-file-descriptor-in-Fsdriver-.patch
new file mode 100644
index 0000000..446716c
--- /dev/null
+++ b/0007-hw-9pfs-Use-the-correct-file-descriptor-in-Fsdriver-.patch
@@ -0,0 +1,210 @@
+From ed6857bf98e6c8b8080be208ffe15bb678591466 Mon Sep 17 00:00:00 2001
+From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
+Date: Sun, 4 Dec 2011 22:35:28 +0530
+Subject: [PATCH 07/25] hw/9pfs: Use the correct file descriptor in Fsdriver
+ Callback
+
+Fsdriver callback that operate on file descriptor need to
+differentiate between directory fd and file fd.
+
+Based on the original patch from Sassan Panahinejad <sassan@sassan.me.uk>
+
+Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+---
+ fsdev/file-op-9p.h         |    4 ++--
+ hw/9pfs/cofile.c           |    4 ++--
+ hw/9pfs/virtio-9p-handle.c |   28 ++++++++++++++++++++++------
+ hw/9pfs/virtio-9p-local.c  |   36 ++++++++++++++++++++++++++----------
+ hw/9pfs/virtio-9p-synth.c  |    5 +++--
+ 5 files changed, 55 insertions(+), 22 deletions(-)
+
+diff --git a/fsdev/file-op-9p.h b/fsdev/file-op-9p.h
+index 1928da2..a85ecd3 100644
+--- a/fsdev/file-op-9p.h
++++ b/fsdev/file-op-9p.h
+@@ -112,10 +112,10 @@ typedef struct FileOperations
+     ssize_t (*pwritev)(FsContext *, V9fsFidOpenState *,
+                        const struct iovec *, int, off_t);
+     int (*mkdir)(FsContext *, V9fsPath *, const char *, FsCred *);
+-    int (*fstat)(FsContext *, V9fsFidOpenState *, struct stat *);
++    int (*fstat)(FsContext *, int, V9fsFidOpenState *, struct stat *);
+     int (*rename)(FsContext *, const char *, const char *);
+     int (*truncate)(FsContext *, V9fsPath *, off_t);
+-    int (*fsync)(FsContext *, V9fsFidOpenState *, int);
++    int (*fsync)(FsContext *, int, V9fsFidOpenState *, int);
+     int (*statfs)(FsContext *s, V9fsPath *path, struct statfs *stbuf);
+     ssize_t (*lgetxattr)(FsContext *, V9fsPath *,
+                          const char *, void *, size_t);
+diff --git a/hw/9pfs/cofile.c b/hw/9pfs/cofile.c
+index 586b038..b15838c 100644
+--- a/hw/9pfs/cofile.c
++++ b/hw/9pfs/cofile.c
+@@ -71,7 +71,7 @@ int v9fs_co_fstat(V9fsPDU *pdu, V9fsFidState *fidp, struct stat *stbuf)
+     }
+     v9fs_co_run_in_worker(
+         {
+-            err = s->ops->fstat(&s->ctx, &fidp->fs, stbuf);
++            err = s->ops->fstat(&s->ctx, fidp->fid_type, &fidp->fs, stbuf);
+             if (err < 0) {
+                 err = -errno;
+             }
+@@ -192,7 +192,7 @@ int v9fs_co_fsync(V9fsPDU *pdu, V9fsFidState *fidp, int datasync)
+     }
+     v9fs_co_run_in_worker(
+         {
+-            err = s->ops->fsync(&s->ctx, &fidp->fs, datasync);
++            err = s->ops->fsync(&s->ctx, fidp->fid_type, &fidp->fs, datasync);
+             if (err < 0) {
+                 err = -errno;
+             }
+diff --git a/hw/9pfs/virtio-9p-handle.c b/hw/9pfs/virtio-9p-handle.c
+index a62f690..f97d898 100644
+--- a/hw/9pfs/virtio-9p-handle.c
++++ b/hw/9pfs/virtio-9p-handle.c
+@@ -255,10 +255,17 @@ static int handle_mkdir(FsContext *fs_ctx, V9fsPath *dir_path,
+     return ret;
+ }
+
+-static int handle_fstat(FsContext *fs_ctx, V9fsFidOpenState *fs,
+-                        struct stat *stbuf)
++static int handle_fstat(FsContext *fs_ctx, int fid_type,
++                        V9fsFidOpenState *fs, struct stat *stbuf)
+ {
+-    return fstat(fs->fd, stbuf);
++    int fd;
++
++    if (fid_type == P9_FID_DIR) {
++        fd = dirfd(fs->dir);
++    } else {
++        fd = fs->fd;
++    }
++    return fstat(fd, stbuf);
+ }
+
+ static int handle_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
+@@ -395,12 +402,21 @@ static int handle_remove(FsContext *ctx, const char *path)
+     return -1;
+ }
+
+-static int handle_fsync(FsContext *ctx, V9fsFidOpenState *fs, int datasync)
++static int handle_fsync(FsContext *ctx, int fid_type,
++                        V9fsFidOpenState *fs, int datasync)
+ {
++    int fd;
++
++    if (fid_type == P9_FID_DIR) {
++        fd = dirfd(fs->dir);
++    } else {
++        fd = fs->fd;
++    }
++
+     if (datasync) {
+-        return qemu_fdatasync(fs->fd);
++        return qemu_fdatasync(fd);
+     } else {
+-        return fsync(fs->fd);
++        return fsync(fd);
+     }
+ }
+
+diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c
+index 99ef0cd..371a94d 100644
+--- a/hw/9pfs/virtio-9p-local.c
++++ b/hw/9pfs/virtio-9p-local.c
+@@ -366,11 +366,18 @@ out:
+     return err;
+ }
+
+-static int local_fstat(FsContext *fs_ctx,
++static int local_fstat(FsContext *fs_ctx, int fid_type,
+                        V9fsFidOpenState *fs, struct stat *stbuf)
+ {
+-    int err;
+-    err = fstat(fs->fd, stbuf);
++    int err, fd;
++
++    if (fid_type == P9_FID_DIR) {
++        fd = dirfd(fs->dir);
++    } else {
++        fd = fs->fd;
++    }
++
++    err = fstat(fd, stbuf);
+     if (err) {
+         return err;
+     }
+@@ -381,19 +388,19 @@ static int local_fstat(FsContext *fs_ctx,
+         mode_t tmp_mode;
+         dev_t tmp_dev;
+
+-        if (fgetxattr(fs->fd, "user.virtfs.uid",
++        if (fgetxattr(fd, "user.virtfs.uid",
+                       &tmp_uid, sizeof(uid_t)) > 0) {
+             stbuf->st_uid = tmp_uid;
+         }
+-        if (fgetxattr(fs->fd, "user.virtfs.gid",
++        if (fgetxattr(fd, "user.virtfs.gid",
+                       &tmp_gid, sizeof(gid_t)) > 0) {
+             stbuf->st_gid = tmp_gid;
+         }
+-        if (fgetxattr(fs->fd, "user.virtfs.mode",
++        if (fgetxattr(fd, "user.virtfs.mode",
+                       &tmp_mode, sizeof(mode_t)) > 0) {
+             stbuf->st_mode = tmp_mode;
+         }
+-        if (fgetxattr(fs->fd, "user.virtfs.rdev",
++        if (fgetxattr(fd, "user.virtfs.rdev",
+                       &tmp_dev, sizeof(dev_t)) > 0) {
+                 stbuf->st_rdev = tmp_dev;
+         }
+@@ -592,12 +599,21 @@ static int local_remove(FsContext *ctx, const char *path)
+     return remove(rpath(ctx, path, buffer));
+ }
+
+-static int local_fsync(FsContext *ctx, V9fsFidOpenState *fs, int datasync)
++static int local_fsync(FsContext *ctx, int fid_type,
++                       V9fsFidOpenState *fs, int datasync)
+ {
++    int fd;
++
++    if (fid_type == P9_FID_DIR) {
++        fd = dirfd(fs->dir);
++    } else {
++        fd = fs->fd;
++    }
++
+     if (datasync) {
+-        return qemu_fdatasync(fs->fd);
++        return qemu_fdatasync(fd);
+     } else {
+-        return fsync(fs->fd);
++        return fsync(fd);
+     }
+ }
+
+diff --git a/hw/9pfs/virtio-9p-synth.c b/hw/9pfs/virtio-9p-synth.c
+index f573616..92e0b09 100644
+--- a/hw/9pfs/virtio-9p-synth.c
++++ b/hw/9pfs/virtio-9p-synth.c
+@@ -166,7 +166,7 @@ static int v9fs_synth_lstat(FsContext *fs_ctx,
+     return 0;
+ }
+
+-static int v9fs_synth_fstat(FsContext *fs_ctx,
++static int v9fs_synth_fstat(FsContext *fs_ctx, int fid_type,
+                             V9fsFidOpenState *fs, struct stat *stbuf)
+ {
+     V9fsSynthOpenState *synth_open = fs->private;
+@@ -414,7 +414,8 @@ static int v9fs_synth_remove(FsContext *ctx, const char *path)
+     return -1;
+ }
+
+-static int v9fs_synth_fsync(FsContext *ctx, V9fsFidOpenState *fs, int datasync)
++static int v9fs_synth_fsync(FsContext *ctx, int fid_type,
++                            V9fsFidOpenState *fs, int datasync)
+ {
+     errno = ENOSYS;
+     return 0;
+-- 
+1.7.7.5
+
diff --git a/0008-hw-9pfs-replace-iovec-manipulation-with-QEMUIOVector.patch b/0008-hw-9pfs-replace-iovec-manipulation-with-QEMUIOVector.patch
new file mode 100644
index 0000000..95c3f05
--- /dev/null
+++ b/0008-hw-9pfs-replace-iovec-manipulation-with-QEMUIOVector.patch
@@ -0,0 +1,305 @@
+From 45d6cdff48356dc8974497ec0524f971b646dd70 Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
+Date: Wed, 21 Dec 2011 12:37:22 +0530
+Subject: [PATCH 08/25] hw/9pfs: replace iovec manipulation with QEMUIOVector
+
+The v9fs_read() and v9fs_write() functions rely on iovec[] manipulation
+code should be replaced with QEMUIOVector to avoid duplicating code.
+In the future it may be possible to make the code even more concise by
+using QEMUIOVector consistently across virtio and 9pfs.
+
+The "v" format specifier for pdu_marshal() and pdu_unmarshal() is
+dropped since it does not actually pack/unpack anything.  The specifier
+was also not implemented to update the offset variable and could only be
+used at the end of a format string, another sign that this shouldn't
+really be a format specifier.  Instead, see the new
+v9fs_init_qiov_from_pdu() function.
+
+This change avoids a possible iovec[] buffer overflow when indirect
+vrings are used since the number of vectors is now limited by the
+underlying VirtQueueElement and cannot be out-of-bounds.
+
+Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
+Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+---
+ hw/9pfs/virtio-9p.c |  162 +++++++++++++++++++--------------------------------
+ 1 files changed, 60 insertions(+), 102 deletions(-)
+
+diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
+index dd43209..c018916 100644
+--- a/hw/9pfs/virtio-9p.c
++++ b/hw/9pfs/virtio-9p.c
+@@ -674,40 +674,6 @@ static size_t pdu_pack(V9fsPDU *pdu, size_t offset, const void *src,
+                              offset, size, 1);
+ }
+
+-static int pdu_copy_sg(V9fsPDU *pdu, size_t offset, int rx, struct iovec *sg)
+-{
+-    size_t pos = 0;
+-    int i, j;
+-    struct iovec *src_sg;
+-    unsigned int num;
+-
+-    if (rx) {
+-        src_sg = pdu->elem.in_sg;
+-        num = pdu->elem.in_num;
+-    } else {
+-        src_sg = pdu->elem.out_sg;
+-        num = pdu->elem.out_num;
+-    }
+-
+-    j = 0;
+-    for (i = 0; i < num; i++) {
+-        if (offset <= pos) {
+-            sg[j].iov_base = src_sg[i].iov_base;
+-            sg[j].iov_len = src_sg[i].iov_len;
+-            j++;
+-        } else if (offset < (src_sg[i].iov_len + pos)) {
+-            sg[j].iov_base = src_sg[i].iov_base;
+-            sg[j].iov_len = src_sg[i].iov_len;
+-            sg[j].iov_base += (offset - pos);
+-            sg[j].iov_len -= (offset - pos);
+-            j++;
+-        }
+-        pos += src_sg[i].iov_len;
+-    }
+-
+-    return j;
+-}
+-
+ static size_t pdu_unmarshal(V9fsPDU *pdu, size_t offset, const char *fmt, ...)
+ {
+     size_t old_offset = offset;
+@@ -743,12 +709,6 @@ static size_t pdu_unmarshal(V9fsPDU *pdu, size_t offset, const char *fmt, ...)
+             *valp = le64_to_cpu(val);
+             break;
+         }
+-        case 'v': {
+-            struct iovec *iov = va_arg(ap, struct iovec *);
+-            int *iovcnt = va_arg(ap, int *);
+-            *iovcnt = pdu_copy_sg(pdu, offset, 0, iov);
+-            break;
+-        }
+         case 's': {
+             V9fsString *str = va_arg(ap, V9fsString *);
+             offset += pdu_unmarshal(pdu, offset, "w", &str->size);
+@@ -827,12 +787,6 @@ static size_t pdu_marshal(V9fsPDU *pdu, size_t offset, const char *fmt, ...)
+             offset += pdu_pack(pdu, offset, &val, sizeof(val));
+             break;
+         }
+-        case 'v': {
+-            struct iovec *iov = va_arg(ap, struct iovec *);
+-            int *iovcnt = va_arg(ap, int *);
+-            *iovcnt = pdu_copy_sg(pdu, offset, 1, iov);
+-            break;
+-        }
+         case 's': {
+             V9fsString *str = va_arg(ap, V9fsString *);
+             offset += pdu_marshal(pdu, offset, "w", str->size);
+@@ -1143,42 +1097,6 @@ static void stat_to_v9stat_dotl(V9fsState *s, const struct stat *stbuf,
+     stat_to_qid(stbuf, &v9lstat->qid);
+ }
+
+-static struct iovec *adjust_sg(struct iovec *sg, int len, int *iovcnt)
+-{
+-    while (len && *iovcnt) {
+-        if (len < sg->iov_len) {
+-            sg->iov_len -= len;
+-            sg->iov_base += len;
+-            len = 0;
+-        } else {
+-            len -= sg->iov_len;
+-            sg++;
+-            *iovcnt -= 1;
+-        }
+-    }
+-
+-    return sg;
+-}
+-
+-static struct iovec *cap_sg(struct iovec *sg, int cap, int *cnt)
+-{
+-    int i;
+-    int total = 0;
+-
+-    for (i = 0; i < *cnt; i++) {
+-        if ((total + sg[i].iov_len) > cap) {
+-            sg[i].iov_len -= ((total + sg[i].iov_len) - cap);
+-            i++;
+-            break;
+-        }
+-        total += sg[i].iov_len;
+-    }
+-
+-    *cnt = i;
+-
+-    return sg;
+-}
+-
+ static void print_sg(struct iovec *sg, int cnt)
+ {
+     int i;
+@@ -1861,6 +1779,38 @@ out:
+     return count;
+ }
+
++/*
++ * Create a QEMUIOVector for a sub-region of PDU iovecs
++ *
++ * @qiov:       uninitialized QEMUIOVector
++ * @skip:       number of bytes to skip from beginning of PDU
++ * @size:       number of bytes to include
++ * @is_write:   true - write, false - read
++ *
++ * The resulting QEMUIOVector has heap-allocated iovecs and must be cleaned up
++ * with qemu_iovec_destroy().
++ */
++static void v9fs_init_qiov_from_pdu(QEMUIOVector *qiov, V9fsPDU *pdu,
++                                    uint64_t skip, size_t size,
++                                    bool is_write)
++{
++    QEMUIOVector elem;
++    struct iovec *iov;
++    unsigned int niov;
++
++    if (is_write) {
++        iov = pdu->elem.out_sg;
++        niov = pdu->elem.out_num;
++    } else {
++        iov = pdu->elem.in_sg;
++        niov = pdu->elem.in_num;
++    }
++
++    qemu_iovec_init_external(&elem, iov, niov);
++    qemu_iovec_init(qiov, niov);
++    qemu_iovec_copy(qiov, &elem, skip, size);
++}
++
+ static void v9fs_read(void *opaque)
+ {
+     int32_t fid;
+@@ -1895,21 +1845,21 @@ static void v9fs_read(void *opaque)
+         err += pdu_marshal(pdu, offset, "d", count);
+         err += count;
+     } else if (fidp->fid_type == P9_FID_FILE) {
+-        int32_t cnt;
++        QEMUIOVector qiov_full;
++        QEMUIOVector qiov;
+         int32_t len;
+-        struct iovec *sg;
+-        struct iovec iov[128]; /* FIXME: bad, bad, bad */
+
+-        sg = iov;
+-        pdu_marshal(pdu, offset + 4, "v", sg, &cnt);
+-        sg = cap_sg(sg, max_count, &cnt);
++        v9fs_init_qiov_from_pdu(&qiov_full, pdu, offset + 4, max_count, false);
++        qemu_iovec_init(&qiov, qiov_full.niov);
+         do {
++            qemu_iovec_reset(&qiov);
++            qemu_iovec_copy(&qiov, &qiov_full, count, qiov_full.size - count);
+             if (0) {
+-                print_sg(sg, cnt);
++                print_sg(qiov.iov, qiov.niov);
+             }
+             /* Loop in case of EINTR */
+             do {
+-                len = v9fs_co_preadv(pdu, fidp, sg, cnt, off);
++                len = v9fs_co_preadv(pdu, fidp, qiov.iov, qiov.niov, off);
+                 if (len >= 0) {
+                     off   += len;
+                     count += len;
+@@ -1920,11 +1870,12 @@ static void v9fs_read(void *opaque)
+                 err = len;
+                 goto out;
+             }
+-            sg = adjust_sg(sg, len, &cnt);
+         } while (count < max_count && len > 0);
+         err = offset;
+         err += pdu_marshal(pdu, offset, "d", count);
+         err += count;
++        qemu_iovec_destroy(&qiov);
++        qemu_iovec_destroy(&qiov_full);
+     } else if (fidp->fid_type == P9_FID_XATTR) {
+         err = v9fs_xattr_read(s, pdu, fidp, off, max_count);
+     } else {
+@@ -2095,7 +2046,6 @@ out:
+
+ static void v9fs_write(void *opaque)
+ {
+-    int cnt;
+     ssize_t err;
+     int32_t fid;
+     int64_t off;
+@@ -2104,13 +2054,14 @@ static void v9fs_write(void *opaque)
+     int32_t total = 0;
+     size_t offset = 7;
+     V9fsFidState *fidp;
+-    struct iovec iov[128]; /* FIXME: bad, bad, bad */
+-    struct iovec *sg = iov;
+     V9fsPDU *pdu = opaque;
+     V9fsState *s = pdu->s;
++    QEMUIOVector qiov_full;
++    QEMUIOVector qiov;
+
+-    pdu_unmarshal(pdu, offset, "dqdv", &fid, &off, &count, sg, &cnt);
+-    trace_v9fs_write(pdu->tag, pdu->id, fid, off, count, cnt);
++    offset += pdu_unmarshal(pdu, offset, "dqd", &fid, &off, &count);
++    v9fs_init_qiov_from_pdu(&qiov_full, pdu, offset, count, true);
++    trace_v9fs_write(pdu->tag, pdu->id, fid, off, count, qiov_full.niov);
+
+     fidp = get_fid(pdu, fid);
+     if (fidp == NULL) {
+@@ -2126,20 +2077,23 @@ static void v9fs_write(void *opaque)
+         /*
+          * setxattr operation
+          */
+-        err = v9fs_xattr_write(s, pdu, fidp, off, count, sg, cnt);
++        err = v9fs_xattr_write(s, pdu, fidp, off, count,
++                               qiov_full.iov, qiov_full.niov);
+         goto out;
+     } else {
+         err = -EINVAL;
+         goto out;
+     }
+-    sg = cap_sg(sg, count, &cnt);
++    qemu_iovec_init(&qiov, qiov_full.niov);
+     do {
++        qemu_iovec_reset(&qiov);
++        qemu_iovec_copy(&qiov, &qiov_full, total, qiov_full.size - total);
+         if (0) {
+-            print_sg(sg, cnt);
++            print_sg(qiov.iov, qiov.niov);
+         }
+         /* Loop in case of EINTR */
+         do {
+-            len = v9fs_co_pwritev(pdu, fidp, sg, cnt, off);
++            len = v9fs_co_pwritev(pdu, fidp, qiov.iov, qiov.niov, off);
+             if (len >= 0) {
+                 off   += len;
+                 total += len;
+@@ -2148,16 +2102,20 @@ static void v9fs_write(void *opaque)
+         if (len < 0) {
+             /* IO error return the error */
+             err = len;
+-            goto out;
++            goto out_qiov;
+         }
+-        sg = adjust_sg(sg, len, &cnt);
+     } while (total < count && len > 0);
++
++    offset = 7;
+     offset += pdu_marshal(pdu, offset, "d", total);
+     err = offset;
+     trace_v9fs_write_return(pdu->tag, pdu->id, total, err);
++out_qiov:
++    qemu_iovec_destroy(&qiov);
+ out:
+     put_fid(pdu, fidp);
+ out_nofid:
++    qemu_iovec_destroy(&qiov_full);
+     complete_pdu(s, pdu, err);
+ }
+
+-- 
+1.7.7.5
+
diff --git a/0008-virtio-console-Enable-port-throttling-when-chardev-i.patch b/0008-virtio-console-Enable-port-throttling-when-chardev-i.patch
deleted file mode 100644
index 740e25d..0000000
--- a/0008-virtio-console-Enable-port-throttling-when-chardev-i.patch
+++ /dev/null
@@ -1,49 +0,0 @@
->From 8750ea70a68e74ca3ecea6149d1d5289cc77dae3 Mon Sep 17 00:00:00 2001
-From: Amit Shah <amit.shah@redhat.com>
-Date: Mon, 21 Mar 2011 22:06:41 +0100
-Subject: [PATCH 08/28] virtio-console: Enable port throttling when chardev is
- slow to consume data
-
-When a chardev indicates it can't accept more data, we tell the
-virtio-serial code to stop sending us any more data till we tell
-otherwise.  This helps in guests continuing to run normally while the vq
-keeps getting full and eventually the guest stops queueing more data.
-As soon as the chardev indicates it can accept more data, start pushing!
-
-Signed-off-by: Amit Shah <amit.shah@redhat.com>
----
- hw/virtio-console.c |   11 +++++++++++
- 1 files changed, 11 insertions(+), 0 deletions(-)
-
-diff --git a/hw/virtio-console.c b/hw/virtio-console.c
-index cfc3087..b91f46e 100644
---- a/hw/virtio-console.c
-+++ b/hw/virtio-console.c
-@@ -20,6 +20,16 @@ typedef struct VirtConsole {
-     CharDriverState *chr;
- } VirtConsole;
- 
-+/*
-+ * Callback function that's called from chardevs when backend becomes
-+ * writable.
-+ */
-+static void chr_write_unblocked(void *opaque)
-+{
-+    VirtConsole *vcon = opaque;
-+
-+    virtio_serial_throttle_port(&vcon->port, false);
-+}
- 
- /* Callback function that's called when the guest sends us data */
- static ssize_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len)
-@@ -99,6 +109,7 @@ static const QemuChrHandlers chr_handlers = {
-     .fd_can_read = chr_can_read,
-     .fd_read = chr_read,
-     .fd_event = chr_event,
-+    .fd_write_unblocked = chr_write_unblocked,
- };
- 
- static int virtconsole_initfn(VirtIOSerialPort *port)
--- 
-1.7.5.1
-
diff --git a/0009-hw-9pfs-Use-the-correct-signed-type-for-different-va.patch b/0009-hw-9pfs-Use-the-correct-signed-type-for-different-va.patch
new file mode 100644
index 0000000..c0b02f2
--- /dev/null
+++ b/0009-hw-9pfs-Use-the-correct-signed-type-for-different-va.patch
@@ -0,0 +1,133 @@
+From 3d3ec7b809b91f2a71fb78fc6b5b079963383243 Mon Sep 17 00:00:00 2001
+From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
+Date: Wed, 21 Dec 2011 12:37:23 +0530
+Subject: [PATCH 09/25] hw/9pfs: Use the correct signed type for different
+ variables
+
+Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+---
+ fsdev/file-op-9p.h  |    2 +-
+ hw/9pfs/virtio-9p.c |   21 +++++++++++----------
+ hw/9pfs/virtio-9p.h |    2 +-
+ trace-events        |    8 ++++----
+ 4 files changed, 17 insertions(+), 16 deletions(-)
+
+diff --git a/fsdev/file-op-9p.h b/fsdev/file-op-9p.h
+index a85ecd3..c823fe0 100644
+--- a/fsdev/file-op-9p.h
++++ b/fsdev/file-op-9p.h
+@@ -74,7 +74,7 @@ typedef struct FsContext
+ } FsContext;
+
+ typedef struct V9fsPath {
+-    int16_t size;
++    uint16_t size;
+     char *data;
+ } V9fsPath;
+
+diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
+index c018916..b3fc3d0 100644
+--- a/hw/9pfs/virtio-9p.c
++++ b/hw/9pfs/virtio-9p.c
+@@ -1694,8 +1694,8 @@ out_nofid:
+     complete_pdu(s, pdu, err);
+ }
+
+-static int v9fs_xattr_read(V9fsState *s, V9fsPDU *pdu,
+-                           V9fsFidState *fidp, int64_t off, int32_t max_count)
++static int v9fs_xattr_read(V9fsState *s, V9fsPDU *pdu, V9fsFidState *fidp,
++                           uint64_t off, uint32_t max_count)
+ {
+     size_t offset = 7;
+     int read_count;
+@@ -1719,7 +1719,7 @@ static int v9fs_xattr_read(V9fsState *s, V9fsPDU *pdu,
+ }
+
+ static int v9fs_do_readdir_with_stat(V9fsPDU *pdu,
+-                                     V9fsFidState *fidp, int32_t max_count)
++                                     V9fsFidState *fidp, uint32_t max_count)
+ {
+     V9fsPath path;
+     V9fsStat v9stat;
+@@ -1814,11 +1814,11 @@ static void v9fs_init_qiov_from_pdu(QEMUIOVector *qiov, V9fsPDU *pdu,
+ static void v9fs_read(void *opaque)
+ {
+     int32_t fid;
+-    int64_t off;
++    uint64_t off;
+     ssize_t err = 0;
+     int32_t count = 0;
+     size_t offset = 7;
+-    int32_t max_count;
++    uint32_t max_count;
+     V9fsFidState *fidp;
+     V9fsPDU *pdu = opaque;
+     V9fsState *s = pdu->s;
+@@ -1962,8 +1962,9 @@ static void v9fs_readdir(void *opaque)
+     V9fsFidState *fidp;
+     ssize_t retval = 0;
+     size_t offset = 7;
+-    int64_t initial_offset;
+-    int32_t count, max_count;
++    uint64_t initial_offset;
++    int32_t count;
++    uint32_t max_count;
+     V9fsPDU *pdu = opaque;
+     V9fsState *s = pdu->s;
+
+@@ -2001,7 +2002,7 @@ out_nofid:
+ }
+
+ static int v9fs_xattr_write(V9fsState *s, V9fsPDU *pdu, V9fsFidState *fidp,
+-                            int64_t off, int32_t count,
++                            uint64_t off, uint32_t count,
+                             struct iovec *sg, int cnt)
+ {
+     int i, to_copy;
+@@ -2048,8 +2049,8 @@ static void v9fs_write(void *opaque)
+ {
+     ssize_t err;
+     int32_t fid;
+-    int64_t off;
+-    int32_t count;
++    uint64_t off;
++    uint32_t count;
+     int32_t len = 0;
+     int32_t total = 0;
+     size_t offset = 7;
+diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
+index 8b612da..19a797b 100644
+--- a/hw/9pfs/virtio-9p.h
++++ b/hw/9pfs/virtio-9p.h
+@@ -156,7 +156,7 @@ typedef struct V9fsFidState V9fsFidState;
+
+ typedef struct V9fsString
+ {
+-    int16_t size;
++    uint16_t size;
+     char *data;
+ } V9fsString;
+
+diff --git a/trace-events b/trace-events
+index 962caca..e417897 100644
+--- a/trace-events
++++ b/trace-events
+@@ -579,11 +579,11 @@ v9fs_lcreate(uint16_t tag, uint8_t id, int32_t dfid, int32_t flags, int32_t mode
+ v9fs_lcreate_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path, int32_t iounit) "tag %d id %d qid={type %d version %d path %"PRId64"} iounit %d"
+ v9fs_fsync(uint16_t tag, uint8_t id, int32_t fid, int datasync) "tag %d id %d fid %d datasync %d"
+ v9fs_clunk(uint16_t tag, uint8_t id, int32_t fid) "tag %d id %d fid %d"
+-v9fs_read(uint16_t tag, uint8_t id, int32_t fid, int64_t off, int32_t max_count) "tag %d id %d fid %d off %"PRId64" max_count %d"
++v9fs_read(uint16_t tag, uint8_t id, int32_t fid, uint64_t off, uint32_t max_count) "tag %d id %d fid %d off %"PRIu64" max_count %u"
+ v9fs_read_return(uint16_t tag, uint8_t id, int32_t count, ssize_t err) "tag %d id %d count %d err %zd"
+-v9fs_readdir(uint16_t tag, uint8_t id, int32_t fid, int64_t offset, int32_t max_count) "tag %d id %d fid %d offset %"PRId64" max_count %d"
+-v9fs_readdir_return(uint16_t tag, uint8_t id, int32_t count, ssize_t retval) "tag %d id %d count %d retval %zd"
+-v9fs_write(uint16_t tag, uint8_t id, int32_t fid, int64_t off, int32_t count, int cnt) "tag %d id %d fid %d off %"PRId64" count %d cnt %d"
++v9fs_readdir(uint16_t tag, uint8_t id, int32_t fid, uint64_t offset, uint32_t max_count) "tag %d id %d fid %d offset %"PRIu64" max_count %u"
++v9fs_readdir_return(uint16_t tag, uint8_t id, uint32_t count, ssize_t retval) "tag %d id %d count %u retval %zd"
++v9fs_write(uint16_t tag, uint8_t id, int32_t fid, uint64_t off, uint32_t count, int cnt) "tag %d id %d fid %d off %"PRIu64" count %u cnt %d"
+ v9fs_write_return(uint16_t tag, uint8_t id, int32_t total, ssize_t err) "tag %d id %d total %d err %zd"
+ v9fs_create(uint16_t tag, uint8_t id, int32_t fid, char* name, int32_t perm, int8_t mode) "tag %d id %d fid %d name %s perm %d mode %d"
+ v9fs_create_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path, int iounit) "tag %d id %d qid={type %d version %d path %"PRId64"} iounit %d"
+-- 
+1.7.7.5
+
diff --git a/0009-spice-qemu-char.c-add-throttling.patch b/0009-spice-qemu-char.c-add-throttling.patch
deleted file mode 100644
index 17bebaa..0000000
--- a/0009-spice-qemu-char.c-add-throttling.patch
+++ /dev/null
@@ -1,133 +0,0 @@
->From a649fba41737329ae13a5b0b4f20798ddf97e2a2 Mon Sep 17 00:00:00 2001
-From: Alon Levy <alevy@redhat.com>
-Date: Tue, 22 Mar 2011 12:27:59 +0200
-Subject: [PATCH 09/28] spice-qemu-char.c: add throttling
-
-BZ: 672191
-
-upstream: not submitted (explained below)
-
-Adds throttling support to spicevmc chardev. Uses a timer to avoid recursing:
-1. spice-server: reds.c:            read_from_vdi_port
-2. qemu:         spice-qemu-char.c: vmc_read
-3.                                  chr_write_unblocked
-                                (calls virtio_serial_throttle_port(port, false))
-4. qemu:         virtio ...
-5. qemu:         spice-qemu-char.c: spice_chr_write
-6. qemu:         spice-qemu-char.c: wakeup (calls into spice-server)
-7. spice-server: ...
-8. qemu:         spice-qemu-char.c: vmc_read
-
-Instead, in vmc_read if we were throttled and we are just about to return
-all the bytes we will set a timer to be triggered immediately to call
-chr_write_unblocked. Then we return after 2 above, and 3 is called from the
-timer callback. This also means we can later remove some ugly recursion protection
-from spice-server.
-
-The other tricky point in this patch is not returning the leftover chunk twice.
-When we throttle, by definition we have data that spice server didn't consume.
-It is being kept by virtio-serial, and by us. The next vmc_read callback needs
-to not return it, but just do unthrottling. Then virtio will give us the remaining
-chunk as usual in spice_chr_write, and we will pass it to spice server in the
-next vmc_read.
-
-This patch relies on Amit's series to expose throttling to chardev's, which
-was not accepted upstream, and will not be accepted upstream until the mainloop
-is reworked to use glib.
----
- spice-qemu-char.c |   39 +++++++++++++++++++++++++++++++++++----
- 1 files changed, 35 insertions(+), 4 deletions(-)
-
-diff --git a/spice-qemu-char.c b/spice-qemu-char.c
-index 95bf6b6..0f72e91 100644
---- a/spice-qemu-char.c
-+++ b/spice-qemu-char.c
-@@ -1,4 +1,6 @@
- #include "config-host.h"
-+#include "qemu-common.h"
-+#include "qemu-timer.h"
- #include "trace.h"
- #include "ui/qemu-spice.h"
- #include <spice.h>
-@@ -25,6 +27,7 @@ typedef struct SpiceCharDriver {
-     uint8_t               *datapos;
-     ssize_t               bufsize, datalen;
-     uint32_t              debug;
-+    QEMUTimer             *unblock_timer;
- } SpiceCharDriver;
- 
- static int vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len)
-@@ -50,6 +53,17 @@ static int vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len)
-     return out;
- }
- 
-+static void spice_chr_unblock(void *opaque)
-+{
-+    SpiceCharDriver *scd = opaque;
-+
-+    if (scd->chr->chr_write_unblocked == NULL) {
-+        dprintf(scd, 1, "%s: backend doesn't support unthrottling.\n", __func__);
-+        return;
-+    }
-+    scd->chr->chr_write_unblocked(scd->chr->handler_opaque);
-+}
-+
- static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len)
- {
-     SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin);
-@@ -61,9 +75,16 @@ static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len)
-         scd->datapos += bytes;
-         scd->datalen -= bytes;
-         assert(scd->datalen >= 0);
--        if (scd->datalen == 0) {
--            scd->datapos = 0;
--        }
-+    }
-+    if (scd->datalen == 0 && scd->chr->write_blocked) {
-+        dprintf(scd, 1, "%s: unthrottling (%d)\n", __func__, bytes);
-+        scd->chr->write_blocked = false;
-+        /*
-+         * set a timer instead of calling scd->chr->chr_write_unblocked directly,
-+         * because that will call back into spice_chr_write (see
-+         * virtio-console.c:chr_write_unblocked), which is unwanted.
-+         */
-+        qemu_mod_timer(scd->unblock_timer, 0);
-     }
-     trace_spice_vmc_read(bytes, len);
-     return bytes;
-@@ -106,6 +127,7 @@ static void vmc_unregister_interface(SpiceCharDriver *scd)
- static int spice_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
- {
-     SpiceCharDriver *s = chr->opaque;
-+    int read_bytes;
- 
-     dprintf(s, 2, "%s: %d\n", __func__, len);
-     vmc_register_interface(s);
-@@ -118,7 +140,15 @@ static int spice_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
-     s->datapos = s->buffer;
-     s->datalen = len;
-     spice_server_char_device_wakeup(&s->sin);
--    return len;
-+    read_bytes = len - s->datalen;
-+    if (read_bytes != len) {
-+        dprintf(s, 1, "%s: throttling: %d < %d (%zd)\n", __func__,
-+                read_bytes, len, s->bufsize);
-+        s->chr->write_blocked = true;
-+        /* We'll get passed in the unconsumed data with the next call */
-+        s->datalen = 0;
-+    }
-+    return read_bytes;
- }
- 
- static void spice_chr_close(struct CharDriverState *chr)
-@@ -196,6 +226,7 @@ int qemu_chr_open_spice(QemuOpts *opts, CharDriverState **_chr)
-     chr->chr_close = spice_chr_close;
-     chr->chr_guest_open = spice_chr_guest_open;
-     chr->chr_guest_close = spice_chr_guest_close;
-+    s->unblock_timer = qemu_new_timer_ms(vm_clock, spice_chr_unblock, s);
- 
-     qemu_chr_generic_open(chr);
- 
--- 
-1.7.5.1
-
diff --git a/0010-spice-qemu-char.c-remove-intermediate-buffer.patch b/0010-spice-qemu-char.c-remove-intermediate-buffer.patch
deleted file mode 100644
index ca23ed9..0000000
--- a/0010-spice-qemu-char.c-remove-intermediate-buffer.patch
+++ /dev/null
@@ -1,71 +0,0 @@
->From 63350d37305a8fc5b6a8fb2fbacfb8a6a91956fd Mon Sep 17 00:00:00 2001
-From: Alon Levy <alevy@redhat.com>
-Date: Tue, 22 Mar 2011 12:28:00 +0200
-Subject: [PATCH 10/28] spice-qemu-char.c: remove intermediate buffer
-
-BZ: 672191
-upstream: not submitted (explained below)
-
-virtio-serial's buffer is valid when it calls us, and we don't
-access it otherwise: vmc_read is only called in response to wakeup,
-or else we set datalen=0 and throttle. Then vmc_read is called back,
-we return 0 (not accessing the buffer) and set the timer to unthrottle.
-
-Also make datalen int and not ssize_t (to fit spice_chr_write signature).
-
-This relied on the previous patch that introduces throttling, which
-can't go upstream right now as explained in that patch.
----
- spice-qemu-char.c |   18 ++++++------------
- 1 files changed, 6 insertions(+), 12 deletions(-)
-
-diff --git a/spice-qemu-char.c b/spice-qemu-char.c
-index 0f72e91..2b8aec4 100644
---- a/spice-qemu-char.c
-+++ b/spice-qemu-char.c
-@@ -23,9 +23,8 @@ typedef struct SpiceCharDriver {
-     SpiceCharDeviceInstance     sin;
-     char                  *subtype;
-     bool                  active;
--    uint8_t               *buffer;
--    uint8_t               *datapos;
--    ssize_t               bufsize, datalen;
-+    const uint8_t         *datapos;
-+    int                   datalen;
-     uint32_t              debug;
-     QEMUTimer             *unblock_timer;
- } SpiceCharDriver;
-@@ -69,7 +68,7 @@ static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len)
-     SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin);
-     int bytes = MIN(len, scd->datalen);
- 
--    dprintf(scd, 2, "%s: %p %d/%d/%zd\n", __func__, scd->datapos, len, bytes, scd->datalen);
-+    dprintf(scd, 2, "%s: %p %d/%d/%d\n", __func__, scd->datapos, len, bytes, scd->datalen);
-     if (bytes > 0) {
-         memcpy(buf, scd->datapos, bytes);
-         scd->datapos += bytes;
-@@ -132,18 +131,13 @@ static int spice_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
-     dprintf(s, 2, "%s: %d\n", __func__, len);
-     vmc_register_interface(s);
-     assert(s->datalen == 0);
--    if (s->bufsize < len) {
--        s->bufsize = len;
--        s->buffer = qemu_realloc(s->buffer, s->bufsize);
--    }
--    memcpy(s->buffer, buf, len);
--    s->datapos = s->buffer;
-+    s->datapos = buf;
-     s->datalen = len;
-     spice_server_char_device_wakeup(&s->sin);
-     read_bytes = len - s->datalen;
-     if (read_bytes != len) {
--        dprintf(s, 1, "%s: throttling: %d < %d (%zd)\n", __func__,
--                read_bytes, len, s->bufsize);
-+        dprintf(s, 1, "%s: throttling: %d < %d\n", __func__,
-+                read_bytes, len);
-         s->chr->write_blocked = true;
-         /* We'll get passed in the unconsumed data with the next call */
-         s->datalen = 0;
--- 
-1.7.5.1
-
diff --git a/0010-target-i386-fix-cmpxchg-instruction-emulation.patch b/0010-target-i386-fix-cmpxchg-instruction-emulation.patch
new file mode 100644
index 0000000..a7276e2
--- /dev/null
+++ b/0010-target-i386-fix-cmpxchg-instruction-emulation.patch
@@ -0,0 +1,54 @@
+From abf80f880410ebbdd01a289c41c87153802fe900 Mon Sep 17 00:00:00 2001
+From: Andreas Gustafsson <gson@gson.org>
+Date: Mon, 12 Dec 2011 00:46:32 +0400
+Subject: [PATCH 10/25] target-i386: fix cmpxchg instruction emulation
+
+When the i386 cmpxchg instruction is executed with a memory operand
+and the comparison result is "unequal", do the memory write before
+changing the accumulator instead of the other way around, because
+otherwise the new accumulator value will incorrectly be used in the
+comparison when the instruction is restarted after a page fault.
+
+This bug was originally reported on 2010-04-25 as
+https://bugs.launchpad.net/qemu/+bug/569760
+
+Signed-off-by: Andreas Gustafsson <gson@gson.org>
+---
+ target-i386/translate.c |   11 +++++++----
+ 1 files changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/target-i386/translate.c b/target-i386/translate.c
+index 1ef8d16..8321bf3 100644
+--- a/target-i386/translate.c
++++ b/target-i386/translate.c
+@@ -4870,20 +4870,23 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
+             tcg_gen_sub_tl(t2, cpu_regs[R_EAX], t0);
+             gen_extu(ot, t2);
+             tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label1);
++            label2 = gen_new_label();
+             if (mod == 3) {
+-                label2 = gen_new_label();
+                 gen_op_mov_reg_v(ot, R_EAX, t0);
+                 tcg_gen_br(label2);
+                 gen_set_label(label1);
+                 gen_op_mov_reg_v(ot, rm, t1);
+-                gen_set_label(label2);
+             } else {
+-                tcg_gen_mov_tl(t1, t0);
++                /* perform no-op store cycle like physical cpu; must be
++                   before changing accumulator to ensure idempotency if
++                   the store faults and the instruction is restarted */
++                gen_op_st_v(ot + s->mem_index, t0, a0);
+                 gen_op_mov_reg_v(ot, R_EAX, t0);
++                tcg_gen_br(label2);
+                 gen_set_label(label1);
+-                /* always store */
+                 gen_op_st_v(ot + s->mem_index, t1, a0);
+             }
++            gen_set_label(label2);
+             tcg_gen_mov_tl(cpu_cc_src, t0);
+             tcg_gen_mov_tl(cpu_cc_dst, t2);
+             s->cc_op = CC_OP_SUBB + ot;
+-- 
+1.7.7.5
+
diff --git a/0011-configure-Enable-build-by-default-PIE-read-only-relo.patch b/0011-configure-Enable-build-by-default-PIE-read-only-relo.patch
new file mode 100644
index 0000000..bd592c7
--- /dev/null
+++ b/0011-configure-Enable-build-by-default-PIE-read-only-relo.patch
@@ -0,0 +1,31 @@
+From 6d450bfbc862d0dab0e8da10ae15698612800726 Mon Sep 17 00:00:00 2001
+From: Brad <brad@comstyle.com>
+Date: Mon, 28 Nov 2011 19:53:49 -0500
+Subject: [PATCH 11/25] configure: Enable build by default PIE / read-only
+ relocation sections on OpenBSD amd64/i386.
+
+Enable build by default PIE / read-only relocation sections for the QEMU
+binaries on OpenBSD amd64/i386.
+
+Signed-off-by: Brad Smith <brad@comstyle.com>
+Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
+---
+ configure |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/configure b/configure
+index ac4840d..b113f60 100755
+--- a/configure
++++ b/configure
+@@ -1116,7 +1116,7 @@ fi
+
+ if test "$pie" = ""; then
+   case "$cpu-$targetos" in
+-    i386-Linux|x86_64-Linux)
++    i386-Linux|x86_64-Linux|i386-OpenBSD|x86_64-OpenBSD)
+       ;;
+     *)
+       pie="no"
+-- 
+1.7.7.5
+
diff --git a/0011-usb-redir-Add-flow-control-support.patch b/0011-usb-redir-Add-flow-control-support.patch
deleted file mode 100644
index ab8de4f..0000000
--- a/0011-usb-redir-Add-flow-control-support.patch
+++ /dev/null
@@ -1,64 +0,0 @@
->From e7903f889f3105efe7e3876925926e8e91919b0f Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Tue, 19 Jul 2011 10:56:19 +0200
-Subject: [PATCH 11/28] usb-redir: Add flow control support
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- usb-redir.c |   28 +++++++++++++++++++++++++++-
- 1 files changed, 27 insertions(+), 1 deletions(-)
-
-diff --git a/usb-redir.c b/usb-redir.c
-index e2b5a2c..6932beb 100644
---- a/usb-redir.c
-+++ b/usb-redir.c
-@@ -224,8 +224,22 @@ static int usbredir_read(void *priv, uint8_t *data, int count)
- static int usbredir_write(void *priv, uint8_t *data, int count)
- {
-     USBRedirDevice *dev = priv;
-+    int r;
- 
--    return qemu_chr_write(dev->cs, data, count);
-+    if (dev->cs->write_blocked) {
-+        return 0;
-+    }
-+
-+    r = qemu_chr_write(dev->cs, data, count);
-+
-+    if (r < 0) {
-+        if (dev->cs->write_blocked) {
-+            return 0;
-+        }
-+        return -1;
-+    }
-+
-+    return r;
- }
- 
- /*
-@@ -782,10 +796,22 @@ static void usbredir_chardev_event(void *opaque, int event)
-     }
- }
- 
-+static void usbredir_chardev_write_unblocked(void *opaque)
-+{
-+    USBRedirDevice *dev = opaque;
-+
-+    if (dev->parser == NULL) {
-+        /* usbredir_open_close_bh hasn't handled the open event yet */
-+        return;
-+    }
-+    usbredirparser_do_write(dev->parser);
-+}
-+
- static const QemuChrHandlers usbredir_chr_handlers = {
-     .fd_can_read = usbredir_chardev_can_read,
-     .fd_read = usbredir_chardev_read,
-     .fd_event = usbredir_chardev_event,
-+    .fd_write_unblocked = usbredir_chardev_write_unblocked,
- };
- 
- /*
--- 
-1.7.5.1
-
diff --git a/0012-cris-Handle-conditional-stores-on-CRISv10.patch b/0012-cris-Handle-conditional-stores-on-CRISv10.patch
new file mode 100644
index 0000000..c824a09
--- /dev/null
+++ b/0012-cris-Handle-conditional-stores-on-CRISv10.patch
@@ -0,0 +1,155 @@
+From 3e8088148bb56b84a739c2ef3c63d89188a1ad8f Mon Sep 17 00:00:00 2001
+From: Stefan Sandstrom <Stefan.Sandstrom@axis.com>
+Date: Mon, 12 Dec 2011 11:38:31 +0100
+Subject: [PATCH 12/25] cris: Handle conditional stores on CRISv10
+
+Signed-off-by: Stefan Sandstrom <Stefan.Sandstrom@axis.com>
+Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
+---
+ target-cris/cpu.h           |    2 +
+ target-cris/helper.c        |    1 +
+ target-cris/translate_v10.c |   72 +++++++++++++++++++++++++++++++++++++++---
+ 3 files changed, 69 insertions(+), 6 deletions(-)
+
+diff --git a/target-cris/cpu.h b/target-cris/cpu.h
+index 8ae0ce3..453afbb 100644
+--- a/target-cris/cpu.h
++++ b/target-cris/cpu.h
+@@ -67,6 +67,8 @@
+ #define Q_FLAG 0x80000000
+ #define M_FLAG 0x40000000
+ #define PFIX_FLAG 0x800      /* CRISv10 Only.  */
++#define F_FLAG_V10 0x400
++#define P_FLAG_V10 0x200
+ #define S_FLAG 0x200
+ #define R_FLAG 0x100
+ #define P_FLAG 0x80
+diff --git a/target-cris/helper.c b/target-cris/helper.c
+index 75f0035..5bc6d81 100644
+--- a/target-cris/helper.c
++++ b/target-cris/helper.c
+@@ -157,6 +157,7 @@ static void do_interruptv10(CPUState *env)
+ 	/* Now that we are in kernel mode, load the handlers address.  */
+ 	env->pc = ldl_code(env->pregs[PR_EBP] + ex_vec * 4);
+ 	env->locked_irq = 1;
++	env->pregs[PR_CCS] |= F_FLAG_V10; /* set F.  */
+
+ 	qemu_log_mask(CPU_LOG_INT, "%s isr=%x vec=%x ccs=%x pid=%d erp=%x\n", 
+ 		      __func__, env->pc, ex_vec, 
+diff --git a/target-cris/translate_v10.c b/target-cris/translate_v10.c
+index 637ac20..95053b6 100644
+--- a/target-cris/translate_v10.c
++++ b/target-cris/translate_v10.c
+@@ -62,6 +62,65 @@ static inline void cris_illegal_insn(DisasContext *dc)
+     t_gen_raise_exception(EXCP_BREAK);
+ }
+
++static void gen_store_v10_conditional(DisasContext *dc, TCGv addr, TCGv val,
++                       unsigned int size, int mem_index)
++{
++    int l1 = gen_new_label();
++    TCGv taddr = tcg_temp_local_new();
++    TCGv tval = tcg_temp_local_new();
++    TCGv t1 = tcg_temp_local_new();
++    dc->postinc = 0;
++    cris_evaluate_flags(dc);
++
++    tcg_gen_mov_tl(taddr, addr);
++    tcg_gen_mov_tl(tval, val);
++
++    /* Store only if F flag isn't set */
++    tcg_gen_andi_tl(t1, cpu_PR[PR_CCS], F_FLAG_V10);
++    tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
++    if (size == 1) {
++        tcg_gen_qemu_st8(tval, taddr, mem_index);
++    } else if (size == 2) {
++        tcg_gen_qemu_st16(tval, taddr, mem_index);
++    } else {
++        tcg_gen_qemu_st32(tval, taddr, mem_index);
++    }
++    gen_set_label(l1);
++    tcg_gen_shri_tl(t1, t1, 1);  /* shift F to P position */
++    tcg_gen_or_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], t1); /*P=F*/
++    tcg_temp_free(t1);
++    tcg_temp_free(tval);
++    tcg_temp_free(taddr);
++}
++
++static void gen_store_v10(DisasContext *dc, TCGv addr, TCGv val,
++                       unsigned int size)
++{
++    int mem_index = cpu_mmu_index(dc->env);
++
++    /* If we get a fault on a delayslot we must keep the jmp state in
++       the cpu-state to be able to re-execute the jmp.  */
++    if (dc->delayed_branch == 1) {
++        cris_store_direct_jmp(dc);
++    }
++
++    /* Conditional writes. We only support the kind were X is known
++       at translation time.  */
++    if (dc->flagx_known && dc->flags_x) {
++        gen_store_v10_conditional(dc, addr, val, size, mem_index);
++        return;
++    }
++
++    if (size == 1) {
++        tcg_gen_qemu_st8(val, addr, mem_index);
++    } else if (size == 2) {
++        tcg_gen_qemu_st16(val, addr, mem_index);
++    } else {
++        tcg_gen_qemu_st32(val, addr, mem_index);
++    }
++}
++
++
+ /* Prefix flag and register are used to handle the more complex
+    addressing modes.  */
+ static void cris_set_prefix(DisasContext *dc)
+@@ -313,7 +372,8 @@ static unsigned int dec10_setclrf(DisasContext *dc)
+     if (set) {
+         tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags);
+     } else {
+-        tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~flags);
++        tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS],
++                        ~(flags|F_FLAG_V10|P_FLAG_V10));
+     }
+
+     dc->flags_uptodate = 1;
+@@ -723,7 +783,7 @@ static unsigned int dec10_ind_move_r_m(DisasContext *dc, unsigned int size)
+     LOG_DIS("move.%d $r%d, [$r%d]\n", dc->size, dc->src, dc->dst);
+     addr = tcg_temp_new();
+     crisv10_prepare_memaddr(dc, addr, size);
+-    gen_store(dc, addr, cpu_R[dc->dst], size);
++    gen_store_v10(dc, addr, cpu_R[dc->dst], size);
+     insn_len += crisv10_post_memaddr(dc, size);
+
+     return insn_len;
+@@ -767,10 +827,10 @@ static unsigned int dec10_ind_move_pr_m(DisasContext *dc)
+         t0 = tcg_temp_new();
+         cris_evaluate_flags(dc);
+         tcg_gen_andi_tl(t0, cpu_PR[PR_CCS], ~PFIX_FLAG);
+-        gen_store(dc, addr, t0, size);
++        gen_store_v10(dc, addr, t0, size);
+         tcg_temp_free(t0);
+     } else {
+-        gen_store(dc, addr, cpu_PR[dc->dst], size);
++        gen_store_v10(dc, addr, cpu_PR[dc->dst], size);
+     }
+     t0 = tcg_temp_new();
+     insn_len += crisv10_post_memaddr(dc, size);
+@@ -793,9 +853,9 @@ static void dec10_movem_r_m(DisasContext *dc)
+     tcg_gen_mov_tl(t0, addr);
+     for (i = dc->dst; i >= 0; i--) {
+         if ((pfix && dc->mode == CRISV10_MODE_AUTOINC) && dc->src == i) {
+-            gen_store(dc, addr, t0, 4);
++            gen_store_v10(dc, addr, t0, 4);
+         } else {
+-            gen_store(dc, addr, cpu_R[i], 4);
++            gen_store_v10(dc, addr, cpu_R[i], 4);
+         }
+         tcg_gen_addi_tl(addr, addr, 4);
+     }
+-- 
+1.7.7.5
+
diff --git a/0012-spice-add-worker-wrapper-functions.patch b/0012-spice-add-worker-wrapper-functions.patch
deleted file mode 100644
index a750ca6..0000000
--- a/0012-spice-add-worker-wrapper-functions.patch
+++ /dev/null
@@ -1,323 +0,0 @@
->From 67d29af45ebb1539eaaa2bfb599350c790306111 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Fri, 17 Jun 2011 10:34:25 +0200
-Subject: [PATCH 12/28] spice: add worker wrapper functions.
-
-Add wrapper functions for all spice worker calls.
-
-Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
----
- hw/qxl-render.c    |    4 +-
- hw/qxl.c           |   32 +++++++++---------
- ui/spice-display.c |   95 ++++++++++++++++++++++++++++++++++++++++++++++++---
- ui/spice-display.h |   22 ++++++++++++
- 4 files changed, 129 insertions(+), 24 deletions(-)
-
-diff --git a/hw/qxl-render.c b/hw/qxl-render.c
-index 1316066..bef5f14 100644
---- a/hw/qxl-render.c
-+++ b/hw/qxl-render.c
-@@ -124,8 +124,8 @@ void qxl_render_update(PCIQXLDevice *qxl)
-     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);
-+    qemu_spice_update_area(&qxl->ssd, 0, &update,
-+                           dirty, ARRAY_SIZE(dirty), 1);
- 
-     for (i = 0; i < ARRAY_SIZE(dirty); i++) {
-         if (qemu_spice_rect_is_empty(dirty+i)) {
-diff --git a/hw/qxl.c b/hw/qxl.c
-index a6fb7f0..5deb776 100644
---- a/hw/qxl.c
-+++ b/hw/qxl.c
-@@ -684,8 +684,8 @@ static void qxl_hard_reset(PCIQXLDevice *d, int loadvm)
-     dprint(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);
-+    qemu_spice_reset_cursor(&d->ssd);
-+    qemu_spice_reset_image_cache(&d->ssd);
-     qxl_reset_surfaces(d);
-     qxl_reset_memslots(d);
- 
-@@ -790,7 +790,7 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta)
-            __FUNCTION__, memslot.slot_id,
-            memslot.virt_start, memslot.virt_end);
- 
--    d->ssd.worker->add_memslot(d->ssd.worker, &memslot);
-+    qemu_spice_add_memslot(&d->ssd, &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;
-@@ -800,14 +800,14 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta)
- static void qxl_del_memslot(PCIQXLDevice *d, uint32_t slot_id)
- {
-     dprint(d, 1, "%s: slot %d\n", __FUNCTION__, slot_id);
--    d->ssd.worker->del_memslot(d->ssd.worker, MEMSLOT_GROUP_HOST, slot_id);
-+    qemu_spice_del_memslot(&d->ssd, MEMSLOT_GROUP_HOST, slot_id);
-     d->guest_slots[slot_id].active = 0;
- }
- 
- static void qxl_reset_memslots(PCIQXLDevice *d)
- {
-     dprint(d, 1, "%s:\n", __FUNCTION__);
--    d->ssd.worker->reset_memslots(d->ssd.worker);
-+    qemu_spice_reset_memslots(&d->ssd);
-     memset(&d->guest_slots, 0, sizeof(d->guest_slots));
- }
- 
-@@ -815,7 +815,7 @@ static void qxl_reset_surfaces(PCIQXLDevice *d)
- {
-     dprint(d, 1, "%s:\n", __FUNCTION__);
-     d->mode = QXL_MODE_UNDEFINED;
--    d->ssd.worker->destroy_surfaces(d->ssd.worker);
-+    qemu_spice_destroy_surfaces(&d->ssd);
-     memset(&d->guest_surfaces.cmds, 0, sizeof(d->guest_surfaces.cmds));
- }
- 
-@@ -869,7 +869,7 @@ static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm)
- 
-     qxl->mode = QXL_MODE_NATIVE;
-     qxl->cmdflags = 0;
--    qxl->ssd.worker->create_primary_surface(qxl->ssd.worker, 0, &surface);
-+    qemu_spice_create_primary_surface(&qxl->ssd, 0, &surface);
- 
-     /* for local rendering */
-     qxl_render_resize(qxl);
-@@ -884,7 +884,7 @@ static void qxl_destroy_primary(PCIQXLDevice *d)
-     dprint(d, 1, "%s\n", __FUNCTION__);
- 
-     d->mode = QXL_MODE_UNDEFINED;
--    d->ssd.worker->destroy_primary_surface(d->ssd.worker, 0);
-+    qemu_spice_destroy_primary_surface(&d->ssd, 0);
- }
- 
- static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
-@@ -956,15 +956,15 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
-     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);
-+        qemu_spice_update_area(&d->ssd, d->ram->update_surface,
-+                               &update, NULL, 0, 0);
-         break;
-     }
-     case QXL_IO_NOTIFY_CMD:
--        d->ssd.worker->wakeup(d->ssd.worker);
-+        qemu_spice_wakeup(&d->ssd);
-         break;
-     case QXL_IO_NOTIFY_CURSOR:
--        d->ssd.worker->wakeup(d->ssd.worker);
-+        qemu_spice_wakeup(&d->ssd);
-         break;
-     case QXL_IO_UPDATE_IRQ:
-         qxl_set_irq(d);
-@@ -978,7 +978,7 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
-             break;
-         }
-         d->oom_running = 1;
--        d->ssd.worker->oom(d->ssd.worker);
-+        qemu_spice_oom(&d->ssd);
-         d->oom_running = 0;
-         break;
-     case QXL_IO_SET_MODE:
-@@ -1016,10 +1016,10 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
-         qxl_destroy_primary(d);
-         break;
-     case QXL_IO_DESTROY_SURFACE_WAIT:
--        d->ssd.worker->destroy_surface_wait(d->ssd.worker, val);
-+        qemu_spice_destroy_surface_wait(&d->ssd, val);
-         break;
-     case QXL_IO_DESTROY_ALL_SURFACES:
--        d->ssd.worker->destroy_surfaces(d->ssd.worker);
-+        qemu_spice_destroy_surfaces(&d->ssd);
-         break;
-     default:
-         fprintf(stderr, "%s: ioport=0x%x, abort()\n", __FUNCTION__, io_port);
-@@ -1424,7 +1424,7 @@ static int qxl_post_load(void *opaque, int version)
-         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_spice_loadvm_commands(&d->ssd, cmds, out);
-         qemu_free(cmds);
- 
-         break;
-diff --git a/ui/spice-display.c b/ui/spice-display.c
-index feeee73..1e6a38f 100644
---- a/ui/spice-display.c
-+++ b/ui/spice-display.c
-@@ -62,6 +62,89 @@ void qemu_spice_rect_union(QXLRect *dest, const QXLRect *r)
-     dest->right = MAX(dest->right, r->right);
- }
- 
-+
-+void qemu_spice_update_area(SimpleSpiceDisplay *ssd, uint32_t surface_id,
-+                            struct QXLRect *area, struct QXLRect *dirty_rects,
-+                            uint32_t num_dirty_rects,
-+                            uint32_t clear_dirty_region)
-+{
-+    ssd->worker->update_area(ssd->worker, surface_id, area, dirty_rects,
-+                             num_dirty_rects, clear_dirty_region);
-+}
-+
-+void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot)
-+{
-+    ssd->worker->add_memslot(ssd->worker, memslot);
-+}
-+
-+void qemu_spice_del_memslot(SimpleSpiceDisplay *ssd, uint32_t gid, uint32_t sid)
-+{
-+    ssd->worker->del_memslot(ssd->worker, gid, sid);
-+}
-+
-+void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id,
-+                                       QXLDevSurfaceCreate *surface)
-+{
-+    ssd->worker->create_primary_surface(ssd->worker, id, surface);
-+}
-+
-+void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id)
-+{
-+    ssd->worker->destroy_primary_surface(ssd->worker, id);
-+}
-+
-+void qemu_spice_destroy_surface_wait(SimpleSpiceDisplay *ssd, uint32_t id)
-+{
-+    ssd->worker->destroy_surface_wait(ssd->worker, id);
-+}
-+
-+void qemu_spice_loadvm_commands(SimpleSpiceDisplay *ssd,
-+                                struct QXLCommandExt *ext, uint32_t count)
-+{
-+    ssd->worker->loadvm_commands(ssd->worker, ext, count);
-+}
-+
-+void qemu_spice_wakeup(SimpleSpiceDisplay *ssd)
-+{
-+    ssd->worker->wakeup(ssd->worker);
-+}
-+
-+void qemu_spice_oom(SimpleSpiceDisplay *ssd)
-+{
-+    ssd->worker->oom(ssd->worker);
-+}
-+
-+void qemu_spice_start(SimpleSpiceDisplay *ssd)
-+{
-+    ssd->worker->start(ssd->worker);
-+}
-+
-+void qemu_spice_stop(SimpleSpiceDisplay *ssd)
-+{
-+    ssd->worker->stop(ssd->worker);
-+}
-+
-+void qemu_spice_reset_memslots(SimpleSpiceDisplay *ssd)
-+{
-+    ssd->worker->reset_memslots(ssd->worker);
-+}
-+
-+void qemu_spice_destroy_surfaces(SimpleSpiceDisplay *ssd)
-+{
-+    ssd->worker->destroy_surfaces(ssd->worker);
-+}
-+
-+void qemu_spice_reset_image_cache(SimpleSpiceDisplay *ssd)
-+{
-+    ssd->worker->reset_image_cache(ssd->worker);
-+}
-+
-+void qemu_spice_reset_cursor(SimpleSpiceDisplay *ssd)
-+{
-+    ssd->worker->reset_cursor(ssd->worker);
-+}
-+
-+
- static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
- {
-     SimpleSpiceUpdate *update;
-@@ -161,7 +244,7 @@ void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd)
-     memset(&memslot, 0, sizeof(memslot));
-     memslot.slot_group_id = MEMSLOT_GROUP_HOST;
-     memslot.virt_end = ~0;
--    ssd->worker->add_memslot(ssd->worker, &memslot);
-+    qemu_spice_add_memslot(ssd, &memslot);
- }
- 
- void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
-@@ -181,14 +264,14 @@ void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
-     surface.mem        = (intptr_t)ssd->buf;
-     surface.group_id   = MEMSLOT_GROUP_HOST;
- 
--    ssd->worker->create_primary_surface(ssd->worker, 0, &surface);
-+    qemu_spice_create_primary_surface(ssd, 0, &surface);
- }
- 
- void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd)
- {
-     dprint(1, "%s:\n", __FUNCTION__);
- 
--    ssd->worker->destroy_primary_surface(ssd->worker, 0);
-+    qemu_spice_destroy_primary_surface(ssd, 0);
- }
- 
- void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason)
-@@ -196,9 +279,9 @@ void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason)
-     SimpleSpiceDisplay *ssd = opaque;
- 
-     if (running) {
--        ssd->worker->start(ssd->worker);
-+        qemu_spice_start(ssd);
-     } else {
--        ssd->worker->stop(ssd->worker);
-+        qemu_spice_stop(ssd);
-     }
-     ssd->running = running;
- }
-@@ -267,7 +350,7 @@ void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd)
- 
-     if (ssd->notify) {
-         ssd->notify = 0;
--        ssd->worker->wakeup(ssd->worker);
-+        qemu_spice_wakeup(ssd);
-         dprint(2, "%s: notify\n", __FUNCTION__);
-     }
- }
-diff --git a/ui/spice-display.h b/ui/spice-display.h
-index 2f95f68..5b06b11 100644
---- a/ui/spice-display.h
-+++ b/ui/spice-display.h
-@@ -80,3 +80,25 @@ 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);
-+
-+void qemu_spice_update_area(SimpleSpiceDisplay *ssd, uint32_t surface_id,
-+                            struct QXLRect *area, struct QXLRect *dirty_rects,
-+                            uint32_t num_dirty_rects,
-+                            uint32_t clear_dirty_region);
-+void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot);
-+void qemu_spice_del_memslot(SimpleSpiceDisplay *ssd, uint32_t gid,
-+                            uint32_t sid);
-+void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id,
-+                                       QXLDevSurfaceCreate *surface);
-+void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id);
-+void qemu_spice_destroy_surface_wait(SimpleSpiceDisplay *ssd, uint32_t id);
-+void qemu_spice_loadvm_commands(SimpleSpiceDisplay *ssd,
-+                                struct QXLCommandExt *ext, uint32_t count);
-+void qemu_spice_wakeup(SimpleSpiceDisplay *ssd);
-+void qemu_spice_oom(SimpleSpiceDisplay *ssd);
-+void qemu_spice_start(SimpleSpiceDisplay *ssd);
-+void qemu_spice_stop(SimpleSpiceDisplay *ssd);
-+void qemu_spice_reset_memslots(SimpleSpiceDisplay *ssd);
-+void qemu_spice_destroy_surfaces(SimpleSpiceDisplay *ssd);
-+void qemu_spice_reset_image_cache(SimpleSpiceDisplay *ssd);
-+void qemu_spice_reset_cursor(SimpleSpiceDisplay *ssd);
--- 
-1.7.5.1
-
diff --git a/0013-pc-add-pc-0.15.patch b/0013-pc-add-pc-0.15.patch
new file mode 100644
index 0000000..f85b065
--- /dev/null
+++ b/0013-pc-add-pc-0.15.patch
@@ -0,0 +1,40 @@
+From a25808dc5baee83f36e0cdab998eb6c0024156fa Mon Sep 17 00:00:00 2001
+From: Anthony Liguori <aliguori@us.ibm.com>
+Date: Sun, 18 Dec 2011 12:59:12 -0600
+Subject: [PATCH 13/25] pc: add pc-0.15
+
+Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
+---
+ hw/pc_piix.c |    9 +++++++++
+ 1 files changed, 9 insertions(+), 0 deletions(-)
+
+diff --git a/hw/pc_piix.c b/hw/pc_piix.c
+index 970f43c..9093a28 100644
+--- a/hw/pc_piix.c
++++ b/hw/pc_piix.c
+@@ -306,6 +306,14 @@ static QEMUMachine pc_machine_v1_0 = {
+     .is_default = 1,
+ };
+
++static QEMUMachine pc_machine_v0_15 = {
++    .name = "pc-0.15",
++    .desc = "Standard PC",
++    .init = pc_init_pci,
++    .max_cpus = 255,
++    .is_default = 1,
++};
++
+ static QEMUMachine pc_machine_v0_14 = {
+     .name = "pc-0.14",
+     .desc = "Standard PC",
+@@ -557,6 +565,7 @@ static QEMUMachine xenfv_machine = {
+ static void pc_machine_init(void)
+ {
+     qemu_register_machine(&pc_machine_v1_0);
++    qemu_register_machine(&pc_machine_v0_15);
+     qemu_register_machine(&pc_machine_v0_14);
+     qemu_register_machine(&pc_machine_v0_13);
+     qemu_register_machine(&pc_machine_v0_12);
+-- 
+1.7.7.5
+
diff --git a/0013-spice-add-qemu_spice_display_init_common.patch b/0013-spice-add-qemu_spice_display_init_common.patch
deleted file mode 100644
index d40d24e..0000000
--- a/0013-spice-add-qemu_spice_display_init_common.patch
+++ /dev/null
@@ -1,84 +0,0 @@
->From c28ee0e7c851fc58ac6ef8f5137fc35cc55b607c Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Fri, 17 Jun 2011 10:42:25 +0200
-Subject: [PATCH 13/28] spice: add qemu_spice_display_init_common
-
-Factor out SimpleSpiceDisplay initialization into
-qemu_spice_display_init_common() and call it from
-both qxl.c (for vga mode) and spice-display.c
-
-Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
----
- hw/qxl.c           |    7 +------
- ui/spice-display.c |   17 +++++++++++------
- ui/spice-display.h |    1 +
- 3 files changed, 13 insertions(+), 12 deletions(-)
-
-diff --git a/hw/qxl.c b/hw/qxl.c
-index 5deb776..2127fa3 100644
---- a/hw/qxl.c
-+++ b/hw/qxl.c
-@@ -1315,12 +1315,7 @@ static int qxl_init_primary(PCIDevice *dev)
- 
-     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;
--    qemu_mutex_init(&qxl->ssd.lock);
--    qxl->ssd.mouse_x = -1;
--    qxl->ssd.mouse_y = -1;
--    qxl->ssd.bufsize = (16 * 1024 * 1024);
--    qxl->ssd.buf = qemu_malloc(qxl->ssd.bufsize);
-+    qemu_spice_display_init_common(&qxl->ssd, vga->ds);
- 
-     qxl0 = qxl;
-     register_displaychangelistener(vga->ds, &display_listener);
-diff --git a/ui/spice-display.c b/ui/spice-display.c
-index 1e6a38f..93e25bf 100644
---- a/ui/spice-display.c
-+++ b/ui/spice-display.c
-@@ -286,6 +286,16 @@ void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason)
-     ssd->running = running;
- }
- 
-+void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd, DisplayState *ds)
-+{
-+    ssd->ds = ds;
-+    qemu_mutex_init(&ssd->lock);
-+    ssd->mouse_x = -1;
-+    ssd->mouse_y = -1;
-+    ssd->bufsize = (16 * 1024 * 1024);
-+    ssd->buf = qemu_malloc(ssd->bufsize);
-+}
-+
- /* display listener callbacks */
- 
- void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
-@@ -499,12 +509,7 @@ static DisplayChangeListener display_listener = {
- void qemu_spice_display_init(DisplayState *ds)
- {
-     assert(sdpy.ds == NULL);
--    sdpy.ds = ds;
--    qemu_mutex_init(&sdpy.lock);
--    sdpy.mouse_x = -1;
--    sdpy.mouse_y = -1;
--    sdpy.bufsize = (16 * 1024 * 1024);
--    sdpy.buf = qemu_malloc(sdpy.bufsize);
-+    qemu_spice_display_init_common(&sdpy, ds);
-     register_displaychangelistener(ds, &display_listener);
- 
-     sdpy.qxl.base.sif = &dpy_interface.base;
-diff --git a/ui/spice-display.h b/ui/spice-display.h
-index 5b06b11..eb7a573 100644
---- a/ui/spice-display.h
-+++ b/ui/spice-display.h
-@@ -75,6 +75,7 @@ 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_init_common(SimpleSpiceDisplay *ssd, DisplayState *ds);
- 
- void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
-                                int x, int y, int w, int h);
--- 
-1.7.5.1
-
diff --git a/0014-pc-fix-event_idx-compatibility-for-virtio-devices.patch b/0014-pc-fix-event_idx-compatibility-for-virtio-devices.patch
new file mode 100644
index 0000000..121ec6c
--- /dev/null
+++ b/0014-pc-fix-event_idx-compatibility-for-virtio-devices.patch
@@ -0,0 +1,87 @@
+From 7e2191ae9898cc957a3d1991aff0e40f2e0f44a4 Mon Sep 17 00:00:00 2001
+From: Anthony Liguori <aliguori@us.ibm.com>
+Date: Sun, 18 Dec 2011 13:07:03 -0600
+Subject: [PATCH 14/25] pc: fix event_idx compatibility for virtio devices
+
+event_idx was introduced in 0.15 and must be disabled for all virtio-pci devices
+(including virtio-balloon-pci).
+
+Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
+---
+ hw/pc_piix.c |   32 ++++++++++++++++++++++++++++++++
+ 1 files changed, 32 insertions(+), 0 deletions(-)
+
+diff --git a/hw/pc_piix.c b/hw/pc_piix.c
+index 9093a28..05000e3 100644
+--- a/hw/pc_piix.c
++++ b/hw/pc_piix.c
+@@ -328,6 +328,22 @@ static QEMUMachine pc_machine_v0_14 = {
+             .driver   = "qxl-vga",
+             .property = "revision",
+             .value    = stringify(2),
++        },{
++            .driver   = "virtio-blk-pci",
++            .property = "event_idx",
++            .value    = "off",
++        },{
++            .driver   = "virtio-serial-pci",
++            .property = "event_idx",
++            .value    = "off",
++        },{
++            .driver   = "virtio-net-pci",
++            .property = "event_idx",
++            .value    = "off",
++        },{
++            .driver   = "virtio-balloon-pci",
++            .property = "event_idx",
++            .value    = "off",
+         },
+         { /* end of list */ }
+     },
+@@ -368,6 +384,10 @@ static QEMUMachine pc_machine_v0_13 = {
+             .property = "event_idx",
+             .value    = "off",
+         },{
++            .driver   = "virtio-balloon-pci",
++            .property = "event_idx",
++            .value    = "off",
++        },{
+             .driver   = "AC97",
+             .property = "use_broken_id",
+             .value    = stringify(1),
+@@ -415,6 +435,10 @@ static QEMUMachine pc_machine_v0_12 = {
+             .property = "event_idx",
+             .value    = "off",
+         },{
++            .driver   = "virtio-balloon-pci",
++            .property = "event_idx",
++            .value    = "off",
++        },{
+             .driver   = "AC97",
+             .property = "use_broken_id",
+             .value    = stringify(1),
+@@ -470,6 +494,10 @@ static QEMUMachine pc_machine_v0_11 = {
+             .property = "event_idx",
+             .value    = "off",
+         },{
++            .driver   = "virtio-balloon-pci",
++            .property = "event_idx",
++            .value    = "off",
++        },{
+             .driver   = "AC97",
+             .property = "use_broken_id",
+             .value    = stringify(1),
+@@ -537,6 +565,10 @@ static QEMUMachine pc_machine_v0_10 = {
+             .property = "event_idx",
+             .value    = "off",
+         },{
++            .driver   = "virtio-balloon-pci",
++            .property = "event_idx",
++            .value    = "off",
++        },{
+             .driver   = "AC97",
+             .property = "use_broken_id",
+             .value    = stringify(1),
+-- 
+1.7.7.5
+
diff --git a/0014-spice-qxl-move-worker-wrappers.patch b/0014-spice-qxl-move-worker-wrappers.patch
deleted file mode 100644
index ef804d6..0000000
--- a/0014-spice-qxl-move-worker-wrappers.patch
+++ /dev/null
@@ -1,294 +0,0 @@
->From 60257c766e7a39134a9db9f4d1111f2b9fea2f86 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Wed, 29 Jun 2011 10:07:52 +0200
-Subject: [PATCH 14/28] spice/qxl: move worker wrappers
-
-Move the wrapper functions which are used by qxl only to qxl.c.
-Rename them from qemu_spice_* to qxl_spice_*.  Also pass in a
-qxl state pointer instead of a SimpleSpiceDisplay pointer.
-
-Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
----
- hw/qxl-render.c    |    4 +-
- hw/qxl.c           |   67 ++++++++++++++++++++++++++++++++++++++++++++-------
- hw/qxl.h           |   13 ++++++++++
- ui/spice-display.c |   46 -----------------------------------
- ui/spice-display.h |   12 ---------
- 5 files changed, 72 insertions(+), 70 deletions(-)
-
-diff --git a/hw/qxl-render.c b/hw/qxl-render.c
-index bef5f14..60b822d 100644
---- a/hw/qxl-render.c
-+++ b/hw/qxl-render.c
-@@ -124,8 +124,8 @@ void qxl_render_update(PCIQXLDevice *qxl)
-     update.bottom = qxl->guest_primary.surface.height;
- 
-     memset(dirty, 0, sizeof(dirty));
--    qemu_spice_update_area(&qxl->ssd, 0, &update,
--                           dirty, ARRAY_SIZE(dirty), 1);
-+    qxl_spice_update_area(qxl, 0, &update,
-+                          dirty, ARRAY_SIZE(dirty), 1);
- 
-     for (i = 0; i < ARRAY_SIZE(dirty); i++) {
-         if (qemu_spice_rect_is_empty(dirty+i)) {
-diff --git a/hw/qxl.c b/hw/qxl.c
-index 2127fa3..803a364 100644
---- a/hw/qxl.c
-+++ b/hw/qxl.c
-@@ -125,6 +125,53 @@ static void qxl_reset_memslots(PCIQXLDevice *d);
- static void qxl_reset_surfaces(PCIQXLDevice *d);
- static void qxl_ring_set_dirty(PCIQXLDevice *qxl);
- 
-+
-+void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
-+                           struct QXLRect *area, struct QXLRect *dirty_rects,
-+                           uint32_t num_dirty_rects,
-+                           uint32_t clear_dirty_region)
-+{
-+    qxl->ssd.worker->update_area(qxl->ssd.worker, surface_id, area, dirty_rects,
-+                             num_dirty_rects, clear_dirty_region);
-+}
-+
-+void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id)
-+{
-+    qxl->ssd.worker->destroy_surface_wait(qxl->ssd.worker, id);
-+}
-+
-+void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
-+                               uint32_t count)
-+{
-+    qxl->ssd.worker->loadvm_commands(qxl->ssd.worker, ext, count);
-+}
-+
-+void qxl_spice_oom(PCIQXLDevice *qxl)
-+{
-+    qxl->ssd.worker->oom(qxl->ssd.worker);
-+}
-+
-+void qxl_spice_reset_memslots(PCIQXLDevice *qxl)
-+{
-+    qxl->ssd.worker->reset_memslots(qxl->ssd.worker);
-+}
-+
-+void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl)
-+{
-+    qxl->ssd.worker->destroy_surfaces(qxl->ssd.worker);
-+}
-+
-+void qxl_spice_reset_image_cache(PCIQXLDevice *qxl)
-+{
-+    qxl->ssd.worker->reset_image_cache(qxl->ssd.worker);
-+}
-+
-+void qxl_spice_reset_cursor(PCIQXLDevice *qxl)
-+{
-+    qxl->ssd.worker->reset_cursor(qxl->ssd.worker);
-+}
-+
-+
- static inline uint32_t msb_mask(uint32_t val)
- {
-     uint32_t mask;
-@@ -684,8 +731,8 @@ static void qxl_hard_reset(PCIQXLDevice *d, int loadvm)
-     dprint(d, 1, "%s: start%s\n", __FUNCTION__,
-            loadvm ? " (loadvm)" : "");
- 
--    qemu_spice_reset_cursor(&d->ssd);
--    qemu_spice_reset_image_cache(&d->ssd);
-+    qxl_spice_reset_cursor(d);
-+    qxl_spice_reset_image_cache(d);
-     qxl_reset_surfaces(d);
-     qxl_reset_memslots(d);
- 
-@@ -807,7 +854,7 @@ static void qxl_del_memslot(PCIQXLDevice *d, uint32_t slot_id)
- static void qxl_reset_memslots(PCIQXLDevice *d)
- {
-     dprint(d, 1, "%s:\n", __FUNCTION__);
--    qemu_spice_reset_memslots(&d->ssd);
-+    qxl_spice_reset_memslots(d);
-     memset(&d->guest_slots, 0, sizeof(d->guest_slots));
- }
- 
-@@ -815,7 +862,7 @@ static void qxl_reset_surfaces(PCIQXLDevice *d)
- {
-     dprint(d, 1, "%s:\n", __FUNCTION__);
-     d->mode = QXL_MODE_UNDEFINED;
--    qemu_spice_destroy_surfaces(&d->ssd);
-+    qxl_spice_destroy_surfaces(d);
-     memset(&d->guest_surfaces.cmds, 0, sizeof(d->guest_surfaces.cmds));
- }
- 
-@@ -956,8 +1003,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_spice_update_area(&d->ssd, d->ram->update_surface,
--                               &update, NULL, 0, 0);
-+        qxl_spice_update_area(d, d->ram->update_surface,
-+                              &update, NULL, 0, 0);
-         break;
-     }
-     case QXL_IO_NOTIFY_CMD:
-@@ -978,7 +1025,7 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
-             break;
-         }
-         d->oom_running = 1;
--        qemu_spice_oom(&d->ssd);
-+        qxl_spice_oom(d);
-         d->oom_running = 0;
-         break;
-     case QXL_IO_SET_MODE:
-@@ -1016,10 +1063,10 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
-         qxl_destroy_primary(d);
-         break;
-     case QXL_IO_DESTROY_SURFACE_WAIT:
--        qemu_spice_destroy_surface_wait(&d->ssd, val);
-+        qxl_spice_destroy_surface_wait(d, val);
-         break;
-     case QXL_IO_DESTROY_ALL_SURFACES:
--        qemu_spice_destroy_surfaces(&d->ssd);
-+        qxl_spice_destroy_surfaces(d);
-         break;
-     default:
-         fprintf(stderr, "%s: ioport=0x%x, abort()\n", __FUNCTION__, io_port);
-@@ -1419,7 +1466,7 @@ static int qxl_post_load(void *opaque, int version)
-         cmds[out].cmd.type = QXL_CMD_CURSOR;
-         cmds[out].group_id = MEMSLOT_GROUP_GUEST;
-         out++;
--        qemu_spice_loadvm_commands(&d->ssd, cmds, out);
-+        qxl_spice_loadvm_commands(d, cmds, out);
-         qemu_free(cmds);
- 
-         break;
-diff --git a/hw/qxl.h b/hw/qxl.h
-index f6c450d..e62b9d0 100644
---- a/hw/qxl.h
-+++ b/hw/qxl.h
-@@ -98,6 +98,19 @@ typedef struct PCIQXLDevice {
- /* qxl.c */
- void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id);
- 
-+void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
-+                           struct QXLRect *area, struct QXLRect *dirty_rects,
-+                           uint32_t num_dirty_rects,
-+                           uint32_t clear_dirty_region);
-+void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id);
-+void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
-+                               uint32_t count);
-+void qxl_spice_oom(PCIQXLDevice *qxl);
-+void qxl_spice_reset_memslots(PCIQXLDevice *qxl);
-+void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl);
-+void qxl_spice_reset_image_cache(PCIQXLDevice *qxl);
-+void qxl_spice_reset_cursor(PCIQXLDevice *qxl);
-+
- /* 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);
-diff --git a/ui/spice-display.c b/ui/spice-display.c
-index 93e25bf..af10ae8 100644
---- a/ui/spice-display.c
-+++ b/ui/spice-display.c
-@@ -63,15 +63,6 @@ void qemu_spice_rect_union(QXLRect *dest, const QXLRect *r)
- }
- 
- 
--void qemu_spice_update_area(SimpleSpiceDisplay *ssd, uint32_t surface_id,
--                            struct QXLRect *area, struct QXLRect *dirty_rects,
--                            uint32_t num_dirty_rects,
--                            uint32_t clear_dirty_region)
--{
--    ssd->worker->update_area(ssd->worker, surface_id, area, dirty_rects,
--                             num_dirty_rects, clear_dirty_region);
--}
--
- void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot)
- {
-     ssd->worker->add_memslot(ssd->worker, memslot);
-@@ -93,27 +84,11 @@ void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id)
-     ssd->worker->destroy_primary_surface(ssd->worker, id);
- }
- 
--void qemu_spice_destroy_surface_wait(SimpleSpiceDisplay *ssd, uint32_t id)
--{
--    ssd->worker->destroy_surface_wait(ssd->worker, id);
--}
--
--void qemu_spice_loadvm_commands(SimpleSpiceDisplay *ssd,
--                                struct QXLCommandExt *ext, uint32_t count)
--{
--    ssd->worker->loadvm_commands(ssd->worker, ext, count);
--}
--
- void qemu_spice_wakeup(SimpleSpiceDisplay *ssd)
- {
-     ssd->worker->wakeup(ssd->worker);
- }
- 
--void qemu_spice_oom(SimpleSpiceDisplay *ssd)
--{
--    ssd->worker->oom(ssd->worker);
--}
--
- void qemu_spice_start(SimpleSpiceDisplay *ssd)
- {
-     ssd->worker->start(ssd->worker);
-@@ -124,27 +99,6 @@ void qemu_spice_stop(SimpleSpiceDisplay *ssd)
-     ssd->worker->stop(ssd->worker);
- }
- 
--void qemu_spice_reset_memslots(SimpleSpiceDisplay *ssd)
--{
--    ssd->worker->reset_memslots(ssd->worker);
--}
--
--void qemu_spice_destroy_surfaces(SimpleSpiceDisplay *ssd)
--{
--    ssd->worker->destroy_surfaces(ssd->worker);
--}
--
--void qemu_spice_reset_image_cache(SimpleSpiceDisplay *ssd)
--{
--    ssd->worker->reset_image_cache(ssd->worker);
--}
--
--void qemu_spice_reset_cursor(SimpleSpiceDisplay *ssd)
--{
--    ssd->worker->reset_cursor(ssd->worker);
--}
--
--
- static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
- {
-     SimpleSpiceUpdate *update;
-diff --git a/ui/spice-display.h b/ui/spice-display.h
-index eb7a573..abe99c7 100644
---- a/ui/spice-display.h
-+++ b/ui/spice-display.h
-@@ -82,24 +82,12 @@ void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
- void qemu_spice_display_resize(SimpleSpiceDisplay *ssd);
- void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd);
- 
--void qemu_spice_update_area(SimpleSpiceDisplay *ssd, uint32_t surface_id,
--                            struct QXLRect *area, struct QXLRect *dirty_rects,
--                            uint32_t num_dirty_rects,
--                            uint32_t clear_dirty_region);
- void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot);
- void qemu_spice_del_memslot(SimpleSpiceDisplay *ssd, uint32_t gid,
-                             uint32_t sid);
- void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id,
-                                        QXLDevSurfaceCreate *surface);
- void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id);
--void qemu_spice_destroy_surface_wait(SimpleSpiceDisplay *ssd, uint32_t id);
--void qemu_spice_loadvm_commands(SimpleSpiceDisplay *ssd,
--                                struct QXLCommandExt *ext, uint32_t count);
- void qemu_spice_wakeup(SimpleSpiceDisplay *ssd);
--void qemu_spice_oom(SimpleSpiceDisplay *ssd);
- void qemu_spice_start(SimpleSpiceDisplay *ssd);
- void qemu_spice_stop(SimpleSpiceDisplay *ssd);
--void qemu_spice_reset_memslots(SimpleSpiceDisplay *ssd);
--void qemu_spice_destroy_surfaces(SimpleSpiceDisplay *ssd);
--void qemu_spice_reset_image_cache(SimpleSpiceDisplay *ssd);
--void qemu_spice_reset_cursor(SimpleSpiceDisplay *ssd);
--- 
-1.7.5.1
-
diff --git a/0015-Fix-parse-of-usb-device-description-with-multiple-co.patch b/0015-Fix-parse-of-usb-device-description-with-multiple-co.patch
new file mode 100644
index 0000000..efc5119
--- /dev/null
+++ b/0015-Fix-parse-of-usb-device-description-with-multiple-co.patch
@@ -0,0 +1,56 @@
+From 9b81fbdbb0cc930aacec343c6ab37adfd60c9e76 Mon Sep 17 00:00:00 2001
+From: "Cao,Bing Bu" <mars@linux.vnet.ibm.com>
+Date: Tue, 13 Dec 2011 09:22:20 +0800
+Subject: [PATCH 15/25] Fix parse of usb device description with multiple
+ configurations
+
+Changed From V1:
+Use DPRINTF instead of fprintf,because it is not an error.
+
+When testing ipod on QEMU by He Jie Xu<xuhj@linux.vnet.ibm.com>,qemu made a assertion.
+We found that the ipod with 2 configurations,and the usb-linux did not parse the descriptor correctly.
+The descr_len returned is the total length of the all configurations,not one configuration.
+The older version will through the other configurations instead of skip,continue parsing the descriptor of interfaces/endpoints in other configurations,then went wrong.
+
+This patch will put the configuration descriptor parse in loop outside and dispel the other configurations not requested.
+
+Signed-off-by: Cao,Bing Bu <mars@linux.vnet.ibm.com>
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+---
+ usb-linux.c |   19 +++++++++++--------
+ 1 files changed, 11 insertions(+), 8 deletions(-)
+
+diff --git a/usb-linux.c b/usb-linux.c
+index ab4c693..ed14bb1 100644
+--- a/usb-linux.c
++++ b/usb-linux.c
+@@ -1141,15 +1141,18 @@ static int usb_linux_update_endp_table(USBHostDevice *s)
+     length = s->descr_len - 18;
+     i = 0;
+
+-    if (descriptors[i + 1] != USB_DT_CONFIG ||
+-        descriptors[i + 5] != s->configuration) {
+-        fprintf(stderr, "invalid descriptor data - configuration %d\n",
+-                s->configuration);
+-        return 1;
+-    }
+-    i += descriptors[i];
+-
+     while (i < length) {
++        if (descriptors[i + 1] != USB_DT_CONFIG) {
++            fprintf(stderr, "invalid descriptor data\n");
++            return 1;
++        } else if (descriptors[i + 5] != s->configuration) {
++            DPRINTF("not requested configuration %d\n", s->configuration);
++            i += (descriptors[i + 3] << 8) + descriptors[i + 2];
++            continue;
++        }
++
++        i += descriptors[i];
++
+         if (descriptors[i + 1] != USB_DT_INTERFACE ||
+             (descriptors[i + 1] == USB_DT_INTERFACE &&
+              descriptors[i + 4] == 0)) {
+-- 
+1.7.7.5
+
diff --git a/0015-qxl-fix-surface-tracking-locking.patch b/0015-qxl-fix-surface-tracking-locking.patch
deleted file mode 100644
index c5bd1ee..0000000
--- a/0015-qxl-fix-surface-tracking-locking.patch
+++ /dev/null
@@ -1,92 +0,0 @@
->From b2b956cfda5fb144d9faa10b7c5894833feb7d30 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Wed, 29 Jun 2011 10:24:05 +0200
-Subject: [PATCH 15/28] qxl: fix surface tracking & locking
-
-Surface tracking needs proper locking since it is used from vcpu and spice
-worker threads, add it.  Also reset the surface counter when zapping all
-surfaces.
-
-Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
----
- hw/qxl.c |   13 ++++++++++++-
- hw/qxl.h |    2 ++
- 2 files changed, 14 insertions(+), 1 deletions(-)
-
-diff --git a/hw/qxl.c b/hw/qxl.c
-index 803a364..416bd48 100644
---- a/hw/qxl.c
-+++ b/hw/qxl.c
-@@ -137,7 +137,12 @@ void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
- 
- void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id)
- {
-+    qemu_mutex_lock(&qxl->track_lock);
-+    PANIC_ON(id >= NUM_SURFACES);
-     qxl->ssd.worker->destroy_surface_wait(qxl->ssd.worker, id);
-+    qxl->guest_surfaces.cmds[id] = 0;
-+    qxl->guest_surfaces.count--;
-+    qemu_mutex_unlock(&qxl->track_lock);
- }
- 
- void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
-@@ -158,7 +163,11 @@ void qxl_spice_reset_memslots(PCIQXLDevice *qxl)
- 
- void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl)
- {
-+    qemu_mutex_lock(&qxl->track_lock);
-     qxl->ssd.worker->destroy_surfaces(qxl->ssd.worker);
-+    memset(&qxl->guest_surfaces.cmds, 0, sizeof(qxl->guest_surfaces.cmds));
-+    qxl->guest_surfaces.count = 0;
-+    qemu_mutex_unlock(&qxl->track_lock);
- }
- 
- void qxl_spice_reset_image_cache(PCIQXLDevice *qxl)
-@@ -317,6 +326,7 @@ static void qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext)
-         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);
-+        qemu_mutex_lock(&qxl->track_lock);
-         if (cmd->type == QXL_SURFACE_CMD_CREATE) {
-             qxl->guest_surfaces.cmds[id] = ext->cmd.data;
-             qxl->guest_surfaces.count++;
-@@ -327,6 +337,7 @@ static void qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext)
-             qxl->guest_surfaces.cmds[id] = 0;
-             qxl->guest_surfaces.count--;
-         }
-+        qemu_mutex_unlock(&qxl->track_lock);
-         break;
-     }
-     case QXL_CMD_CURSOR:
-@@ -863,7 +874,6 @@ static void qxl_reset_surfaces(PCIQXLDevice *d)
-     dprint(d, 1, "%s:\n", __FUNCTION__);
-     d->mode = QXL_MODE_UNDEFINED;
-     qxl_spice_destroy_surfaces(d);
--    memset(&d->guest_surfaces.cmds, 0, sizeof(d->guest_surfaces.cmds));
- }
- 
- /* called from spice server thread context only */
-@@ -1283,6 +1293,7 @@ static int qxl_init_common(PCIQXLDevice *qxl)
-     qxl->generation = 1;
-     qxl->num_memslots = NUM_MEMSLOTS;
-     qxl->num_surfaces = NUM_SURFACES;
-+    qemu_mutex_init(&qxl->track_lock);
- 
-     switch (qxl->revision) {
-     case 1: /* spice 0.4 -- qxl-1 */
-diff --git a/hw/qxl.h b/hw/qxl.h
-index e62b9d0..5d0e85e 100644
---- a/hw/qxl.h
-+++ b/hw/qxl.h
-@@ -55,6 +55,8 @@ typedef struct PCIQXLDevice {
-     } guest_surfaces;
-     QXLPHYSICAL        guest_cursor;
- 
-+    QemuMutex          track_lock;
-+
-     /* thread signaling */
-     pthread_t          main;
-     int                pipe[2];
--- 
-1.7.5.1
-
diff --git a/0016-qxl-add-io_port_to_string.patch b/0016-qxl-add-io_port_to_string.patch
deleted file mode 100644
index a47328c..0000000
--- a/0016-qxl-add-io_port_to_string.patch
+++ /dev/null
@@ -1,71 +0,0 @@
->From 31c995f6ee18ff2e2b45dbdcf1d57f777d1e0ef9 Mon Sep 17 00:00:00 2001
-From: Alon Levy <alevy@redhat.com>
-Date: Fri, 17 Jun 2011 14:42:09 +0200
-Subject: [PATCH 16/28] qxl: add io_port_to_string
-
-Signed-off-by: Alon Levy <alevy@redhat.com>
----
- hw/qxl.c |   40 +++++++++++++++++++++++++++++++++++++++-
- 1 files changed, 39 insertions(+), 1 deletions(-)
-
-diff --git a/hw/qxl.c b/hw/qxl.c
-index 416bd48..6e66021 100644
---- a/hw/qxl.c
-+++ b/hw/qxl.c
-@@ -409,6 +409,43 @@ static const char *qxl_mode_to_string(int mode)
-     return "INVALID";
- }
- 
-+static const char *io_port_to_string(uint32_t io_port)
-+{
-+    if (io_port >= QXL_IO_RANGE_SIZE) {
-+        return "out of range";
-+    }
-+    static const char *io_port_to_string[QXL_IO_RANGE_SIZE + 1] = {
-+        [QXL_IO_NOTIFY_CMD]             = "QXL_IO_NOTIFY_CMD",
-+        [QXL_IO_NOTIFY_CURSOR]          = "QXL_IO_NOTIFY_CURSOR",
-+        [QXL_IO_UPDATE_AREA]            = "QXL_IO_UPDATE_AREA",
-+        [QXL_IO_UPDATE_IRQ]             = "QXL_IO_UPDATE_IRQ",
-+        [QXL_IO_NOTIFY_OOM]             = "QXL_IO_NOTIFY_OOM",
-+        [QXL_IO_RESET]                  = "QXL_IO_RESET",
-+        [QXL_IO_SET_MODE]               = "QXL_IO_SET_MODE",
-+        [QXL_IO_LOG]                    = "QXL_IO_LOG",
-+        [QXL_IO_MEMSLOT_ADD]            = "QXL_IO_MEMSLOT_ADD",
-+        [QXL_IO_MEMSLOT_DEL]            = "QXL_IO_MEMSLOT_DEL",
-+        [QXL_IO_DETACH_PRIMARY]         = "QXL_IO_DETACH_PRIMARY",
-+        [QXL_IO_ATTACH_PRIMARY]         = "QXL_IO_ATTACH_PRIMARY",
-+        [QXL_IO_CREATE_PRIMARY]         = "QXL_IO_CREATE_PRIMARY",
-+        [QXL_IO_DESTROY_PRIMARY]        = "QXL_IO_DESTROY_PRIMARY",
-+        [QXL_IO_DESTROY_SURFACE_WAIT]   = "QXL_IO_DESTROY_SURFACE_WAIT",
-+        [QXL_IO_DESTROY_ALL_SURFACES]   = "QXL_IO_DESTROY_ALL_SURFACES",
-+#if SPICE_INTERFACE_QXL_MINOR >= 1
-+        [QXL_IO_UPDATE_AREA_ASYNC]      = "QXL_IO_UPDATE_AREA_ASYNC",
-+        [QXL_IO_MEMSLOT_ADD_ASYNC]      = "QXL_IO_MEMSLOT_ADD_ASYNC",
-+        [QXL_IO_CREATE_PRIMARY_ASYNC]   = "QXL_IO_CREATE_PRIMARY_ASYNC",
-+        [QXL_IO_DESTROY_PRIMARY_ASYNC]  = "QXL_IO_DESTROY_PRIMARY_ASYNC",
-+        [QXL_IO_DESTROY_SURFACE_ASYNC]  = "QXL_IO_DESTROY_SURFACE_ASYNC",
-+        [QXL_IO_DESTROY_ALL_SURFACES_ASYNC]
-+                                        = "QXL_IO_DESTROY_ALL_SURFACES_ASYNC",
-+        [QXL_IO_FLUSH_SURFACES_ASYNC]   = "QXL_IO_FLUSH_SURFACES_ASYNC",
-+        [QXL_IO_FLUSH_RELEASE]          = "QXL_IO_FLUSH_RELEASE",
-+#endif
-+    };
-+    return io_port_to_string[io_port];
-+}
-+
- /* called from spice server thread context only */
- static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
- {
-@@ -1005,7 +1042,8 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
-     default:
-         if (d->mode == QXL_MODE_NATIVE || d->mode == QXL_MODE_COMPAT)
-             break;
--        dprint(d, 1, "%s: unexpected port 0x%x in vga mode\n", __FUNCTION__, io_port);
-+        dprint(d, 1, "%s: unexpected port 0x%x (%s) in vga mode\n",
-+            __func__, io_port, io_port_to_string(io_port));
-         return;
-     }
- 
--- 
-1.7.5.1
-
diff --git a/0016-usb-storage-cancel-I-O-on-reset.patch b/0016-usb-storage-cancel-I-O-on-reset.patch
new file mode 100644
index 0000000..5fdd63d
--- /dev/null
+++ b/0016-usb-storage-cancel-I-O-on-reset.patch
@@ -0,0 +1,40 @@
+From f63d074313c5df917535587b50802ece7beb6e45 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Wed, 4 Jan 2012 18:13:54 +0100
+Subject: [PATCH 16/25] usb-storage: cancel I/O on reset
+
+When resetting the usb-storage device we'll have to carefully cancel
+and clear any requests which might be in flight, otherwise we'll confuse
+the state machine.
+
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+---
+ hw/usb-msd.c |   12 ++++++++++++
+ 1 files changed, 12 insertions(+), 0 deletions(-)
+
+diff --git a/hw/usb-msd.c b/hw/usb-msd.c
+index 4c06950..3147131 100644
+--- a/hw/usb-msd.c
++++ b/hw/usb-msd.c
+@@ -278,6 +278,18 @@ static void usb_msd_handle_reset(USBDevice *dev)
+     MSDState *s = (MSDState *)dev;
+
+     DPRINTF("Reset\n");
++    if (s->req) {
++        scsi_req_cancel(s->req);
++    }
++    assert(s->req == NULL);
++
++    if (s->packet) {
++        USBPacket *p = s->packet;
++        s->packet = NULL;
++        p->result = USB_RET_STALL;
++        usb_packet_complete(dev, p);
++    }
++
+     s->mode = USB_MSDM_CBW;
+ }
+
+-- 
+1.7.7.5
+
diff --git a/0017-qxl-error-handling-fixes-and-cleanups.patch b/0017-qxl-error-handling-fixes-and-cleanups.patch
deleted file mode 100644
index 39a81b7..0000000
--- a/0017-qxl-error-handling-fixes-and-cleanups.patch
+++ /dev/null
@@ -1,110 +0,0 @@
->From 4b61f7ca2ed63deb1d35c17150b53a1661f395f7 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Thu, 30 Jun 2011 10:41:36 +0200
-Subject: [PATCH 17/28] qxl: error handling fixes and cleanups.
-
-Add qxl_guest_bug() function which is supposed to be called in case
-sanity checks of guest requests fail.  It raises an error IRQ and
-logs a message in case guest debugging is enabled.
-
-Make PANIC_ON() abort instead of exit.  That macro should be used
-for qemu bugs only, any guest-triggerable stuff should use the new
-qxl_guest_bug() function instead.
-
-Convert a few easy cases from PANIC_ON() to qxl_guest_bug() to
-show intended usage.
-
-Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
----
- hw/qxl.c |   34 ++++++++++++++++++++++++++++++----
- hw/qxl.h |    3 ++-
- 2 files changed, 32 insertions(+), 5 deletions(-)
-
-diff --git a/hw/qxl.c b/hw/qxl.c
-index 6e66021..28c8b5d 100644
---- a/hw/qxl.c
-+++ b/hw/qxl.c
-@@ -125,6 +125,16 @@ static void qxl_reset_memslots(PCIQXLDevice *d);
- static void qxl_reset_surfaces(PCIQXLDevice *d);
- static void qxl_ring_set_dirty(PCIQXLDevice *qxl);
- 
-+void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg)
-+{
-+#if SPICE_INTERFACE_QXL_MINOR >= 1
-+    qxl_send_events(qxl, QXL_INTERRUPT_ERROR);
-+#endif
-+    if (qxl->guestdebug) {
-+        fprintf(stderr, "qxl-%d: guest bug: %s\n", qxl->id, msg);
-+    }
-+}
-+
- 
- void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
-                            struct QXLRect *area, struct QXLRect *dirty_rects,
-@@ -1091,22 +1101,38 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
-         qxl_hard_reset(d, 0);
-         break;
-     case QXL_IO_MEMSLOT_ADD:
--        PANIC_ON(val >= NUM_MEMSLOTS);
--        PANIC_ON(d->guest_slots[val].active);
-+        if (val >= NUM_MEMSLOTS) {
-+            qxl_guest_bug(d, "QXL_IO_MEMSLOT_ADD: val out of range");
-+            break;
-+        }
-+        if (d->guest_slots[val].active) {
-+            qxl_guest_bug(d, "QXL_IO_MEMSLOT_ADD: memory slot already active");
-+            break;
-+        }
-         d->guest_slots[val].slot = d->ram->mem_slot;
-         qxl_add_memslot(d, val, 0);
-         break;
-     case QXL_IO_MEMSLOT_DEL:
-+        if (val >= NUM_MEMSLOTS) {
-+            qxl_guest_bug(d, "QXL_IO_MEMSLOT_DEL: val out of range");
-+            break;
-+        }
-         qxl_del_memslot(d, val);
-         break;
-     case QXL_IO_CREATE_PRIMARY:
--        PANIC_ON(val != 0);
-+        if (val != 0) {
-+            qxl_guest_bug(d, "QXL_IO_CREATE_PRIMARY: val != 0");
-+            break;
-+        }
-         dprint(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);
-+        if (val != 0) {
-+            qxl_guest_bug(d, "QXL_IO_DESTROY_PRIMARY: val != 0");
-+            break;
-+        }
-         dprint(d, 1, "QXL_IO_DESTROY_PRIMARY (%s)\n", qxl_mode_to_string(d->mode));
-         qxl_destroy_primary(d);
-         break;
-diff --git a/hw/qxl.h b/hw/qxl.h
-index 5d0e85e..5db9aae 100644
---- a/hw/qxl.h
-+++ b/hw/qxl.h
-@@ -86,7 +86,7 @@ typedef struct PCIQXLDevice {
- 
- #define PANIC_ON(x) if ((x)) {                         \
-     printf("%s: PANIC %s failed\n", __FUNCTION__, #x); \
--    exit(-1);                                          \
-+    abort();                                           \
- }
- 
- #define dprint(_qxl, _level, _fmt, ...)                                 \
-@@ -99,6 +99,7 @@ typedef struct PCIQXLDevice {
- 
- /* qxl.c */
- void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id);
-+void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg);
- 
- void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
-                            struct QXLRect *area, struct QXLRect *dirty_rects,
--- 
-1.7.5.1
-
diff --git a/0017-usb-host-properly-release-port-on-unplug-exit.patch b/0017-usb-host-properly-release-port-on-unplug-exit.patch
new file mode 100644
index 0000000..5804510
--- /dev/null
+++ b/0017-usb-host-properly-release-port-on-unplug-exit.patch
@@ -0,0 +1,111 @@
+From c936f649d4a6b87cabe809170874f6b560cc0524 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Thu, 5 Jan 2012 15:49:18 +0100
+Subject: [PATCH 17/25] usb-host: properly release port on unplug & exit
+
+Factor out port release into a separate function.  Call release function
+in exit notifier too.  Add explicit call the USBDEVFS_RELEASE_PORT
+ioctl, just closing the hub file handle seems not to be enougth.  Make
+sure we release the port before resetting the device, otherwise host
+drivers will not re-attach.
+
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+---
+ usb-linux.c |   28 ++++++++++++++++++++--------
+ 1 files changed, 20 insertions(+), 8 deletions(-)
+
+diff --git a/usb-linux.c b/usb-linux.c
+index ed14bb1..749ce71 100644
+--- a/usb-linux.c
++++ b/usb-linux.c
+@@ -116,6 +116,7 @@ typedef struct USBHostDevice {
+     USBDevice dev;
+     int       fd;
+     int       hub_fd;
++    int       hub_port;
+
+     uint8_t   descr[8192];
+     int       descr_len;
+@@ -434,7 +435,7 @@ static int usb_host_claim_port(USBHostDevice *s)
+ {
+ #ifdef USBDEVFS_CLAIM_PORT
+     char *h, hub_name[64], line[1024];
+-    int hub_addr, portnr, ret;
++    int hub_addr, ret;
+
+     snprintf(hub_name, sizeof(hub_name), "%d-%s",
+              s->match.bus_num, s->match.port);
+@@ -442,13 +443,13 @@ static int usb_host_claim_port(USBHostDevice *s)
+     /* try strip off last ".$portnr" to get hub */
+     h = strrchr(hub_name, '.');
+     if (h != NULL) {
+-        portnr = atoi(h+1);
++        s->hub_port = atoi(h+1);
+         *h = '\0';
+     } else {
+         /* no dot in there -> it is the root hub */
+         snprintf(hub_name, sizeof(hub_name), "usb%d",
+                  s->match.bus_num);
+-        portnr = atoi(s->match.port);
++        s->hub_port = atoi(s->match.port);
+     }
+
+     if (!usb_host_read_file(line, sizeof(line), "devnum",
+@@ -469,20 +470,32 @@ static int usb_host_claim_port(USBHostDevice *s)
+         return -1;
+     }
+
+-    ret = ioctl(s->hub_fd, USBDEVFS_CLAIM_PORT, &portnr);
++    ret = ioctl(s->hub_fd, USBDEVFS_CLAIM_PORT, &s->hub_port);
+     if (ret < 0) {
+         close(s->hub_fd);
+         s->hub_fd = -1;
+         return -1;
+     }
+
+-    trace_usb_host_claim_port(s->match.bus_num, hub_addr, portnr);
++    trace_usb_host_claim_port(s->match.bus_num, hub_addr, s->hub_port);
+     return 0;
+ #else
+     return -1;
+ #endif
+ }
+
++static void usb_host_release_port(USBHostDevice *s)
++{
++    if (s->hub_fd == -1) {
++        return;
++    }
++#ifdef USBDEVFS_RELEASE_PORT
++    ioctl(s->hub_fd, USBDEVFS_RELEASE_PORT, &s->hub_port);
++#endif
++    close(s->hub_fd);
++    s->hub_fd = -1;
++}
++
+ static int usb_host_disconnect_ifaces(USBHostDevice *dev, int nb_interfaces)
+ {
+     /* earlier Linux 2.4 do not support that */
+@@ -635,10 +648,8 @@ static void usb_host_handle_destroy(USBDevice *dev)
+ {
+     USBHostDevice *s = (USBHostDevice *)dev;
+
++    usb_host_release_port(s);
+     usb_host_close(s);
+-    if (s->hub_fd != -1) {
+-        close(s->hub_fd);
+-    }
+     QTAILQ_REMOVE(&hostdevs, s, next);
+     qemu_remove_exit_notifier(&s->exit);
+ }
+@@ -1402,6 +1413,7 @@ static void usb_host_exit_notifier(struct Notifier *n, void *data)
+ {
+     USBHostDevice *s = container_of(n, USBHostDevice, exit);
+
++    usb_host_release_port(s);
+     if (s->fd != -1) {
+         usb_host_do_reset(s);;
+     }
+-- 
+1.7.7.5
+
diff --git a/0018-qxl-make-qxl_guest_bug-take-variable-arguments.patch b/0018-qxl-make-qxl_guest_bug-take-variable-arguments.patch
deleted file mode 100644
index b7b311f..0000000
--- a/0018-qxl-make-qxl_guest_bug-take-variable-arguments.patch
+++ /dev/null
@@ -1,52 +0,0 @@
->From 5c0219c6cef769a5748705d489376ea618486a17 Mon Sep 17 00:00:00 2001
-From: Alon Levy <alevy@redhat.com>
-Date: Wed, 6 Jul 2011 13:40:29 +0200
-Subject: [PATCH 18/28] qxl: make qxl_guest_bug take variable arguments
-
-Signed-off-by: Alon Levy <alevy@redhat.com>
----
- hw/qxl.c |    9 +++++++--
- hw/qxl.h |    2 +-
- 2 files changed, 8 insertions(+), 3 deletions(-)
-
-diff --git a/hw/qxl.c b/hw/qxl.c
-index 28c8b5d..c50eaf9 100644
---- a/hw/qxl.c
-+++ b/hw/qxl.c
-@@ -125,13 +125,18 @@ static void qxl_reset_memslots(PCIQXLDevice *d);
- static void qxl_reset_surfaces(PCIQXLDevice *d);
- static void qxl_ring_set_dirty(PCIQXLDevice *qxl);
- 
--void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg)
-+void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg, ...)
- {
- #if SPICE_INTERFACE_QXL_MINOR >= 1
-     qxl_send_events(qxl, QXL_INTERRUPT_ERROR);
- #endif
-     if (qxl->guestdebug) {
--        fprintf(stderr, "qxl-%d: guest bug: %s\n", qxl->id, msg);
-+        va_list ap;
-+        va_start(ap, msg);
-+        fprintf(stderr, "qxl-%d: guest bug: ", qxl->id);
-+        vfprintf(stderr, msg, ap);
-+        fprintf(stderr, "\n");
-+        va_end(ap);
-     }
- }
- 
-diff --git a/hw/qxl.h b/hw/qxl.h
-index 5db9aae..32ca5a0 100644
---- a/hw/qxl.h
-+++ b/hw/qxl.h
-@@ -99,7 +99,7 @@ typedef struct PCIQXLDevice {
- 
- /* qxl.c */
- void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id);
--void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg);
-+void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg, ...);
- 
- void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
-                            struct QXLRect *area, struct QXLRect *dirty_rects,
--- 
-1.7.5.1
-
diff --git a/0018-usb-ohci-td.cbp-incorrectly-updated-near-page-end.patch b/0018-usb-ohci-td.cbp-incorrectly-updated-near-page-end.patch
new file mode 100644
index 0000000..bba083e
--- /dev/null
+++ b/0018-usb-ohci-td.cbp-incorrectly-updated-near-page-end.patch
@@ -0,0 +1,40 @@
+From 23201c64a789cf948fedcea221a4b6e197fcd628 Mon Sep 17 00:00:00 2001
+From: Andriy Gapon <avg@FreeBSD.org>
+Date: Thu, 22 Dec 2011 11:34:30 +0200
+Subject: [PATCH 18/25] usb-ohci: td.cbp incorrectly updated near page end
+
+The current code that updates the cbp value after a transfer looks like this:
+td.cbp += ret;
+if ((td.cbp & 0xfff) + ret > 0xfff) {
+	<handle page overflow>
+because the 'ret' value is effectively added twice the check may fire too early
+when the overflow hasn't happened yet.
+
+Below is one of the possible changes that correct the behavior:
+
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+---
+ hw/usb-ohci.c |    6 +++---
+ 1 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
+index c2981c5..c27014a 100644
+--- a/hw/usb-ohci.c
++++ b/hw/usb-ohci.c
+@@ -1025,10 +1025,10 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
+         if (ret == len) {
+             td.cbp = 0;
+         } else {
+-            td.cbp += ret;
+             if ((td.cbp & 0xfff) + ret > 0xfff) {
+-                td.cbp &= 0xfff;
+-                td.cbp |= td.be & ~0xfff;
++                td.cbp = (td.be & ~0xfff) + ((td.cbp + ret) & 0xfff);
++            } else {
++                td.cbp += ret;
+             }
+         }
+         td.flags |= OHCI_TD_T1;
+-- 
+1.7.7.5
+
diff --git a/0019-qxl-only-disallow-specific-io-s-in-vga-mode.patch b/0019-qxl-only-disallow-specific-io-s-in-vga-mode.patch
deleted file mode 100644
index 258a7c3..0000000
--- a/0019-qxl-only-disallow-specific-io-s-in-vga-mode.patch
+++ /dev/null
@@ -1,31 +0,0 @@
->From e8f481961a5fd3ad92a55dbabcccf09b037d86c9 Mon Sep 17 00:00:00 2001
-From: Alon Levy <alevy@redhat.com>
-Date: Wed, 29 Jun 2011 11:53:21 +0200
-Subject: [PATCH 19/28] qxl: only disallow specific io's in vga mode
-
-Since the driver is still in operation even after moving to UNDEFINED, i.e.
-by destroying primary in any way.
-
-Signed-off-by: Alon Levy <alevy@redhat.com>
----
- hw/qxl.c |    3 ++-
- 1 files changed, 2 insertions(+), 1 deletions(-)
-
-diff --git a/hw/qxl.c b/hw/qxl.c
-index c50eaf9..23e3240 100644
---- a/hw/qxl.c
-+++ b/hw/qxl.c
-@@ -1055,8 +1055,9 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
-     case QXL_IO_LOG:
-         break;
-     default:
--        if (d->mode == QXL_MODE_NATIVE || d->mode == QXL_MODE_COMPAT)
-+        if (d->mode != QXL_MODE_VGA) {
-             break;
-+        }
-         dprint(d, 1, "%s: unexpected port 0x%x (%s) in vga mode\n",
-             __func__, io_port, io_port_to_string(io_port));
-         return;
--- 
-1.7.5.1
-
diff --git a/0019-target-sh4-ignore-ocbp-and-ocbwb-instructions.patch b/0019-target-sh4-ignore-ocbp-and-ocbwb-instructions.patch
new file mode 100644
index 0000000..d3a4197
--- /dev/null
+++ b/0019-target-sh4-ignore-ocbp-and-ocbwb-instructions.patch
@@ -0,0 +1,47 @@
+From 37769d27270eff15d878a1c7df23407fc5f09b7f Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien@aurel32.net>
+Date: Sat, 7 Jan 2012 15:20:12 +0100
+Subject: [PATCH 19/25] target-sh4: ignore ocbp and ocbwb instructions
+
+ocbp and ocbwb controls the writeback of a cache line to memory. They
+are supposed to do nothing in case of a cache miss. Given QEMU only
+partially emulate caches, it is safe to ignore these instructions.
+
+This fixes a kernel oops when trying to access an rtl8139 NIC with
+recent versions.
+
+Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
+(cherry picked from commit 0cdb95549fedc73e13c147ab9dcabcc303426a07)
+---
+ target-sh4/translate.c |   14 +++-----------
+ 1 files changed, 3 insertions(+), 11 deletions(-)
+
+diff --git a/target-sh4/translate.c b/target-sh4/translate.c
+index bad3577..e04a6e0 100644
+--- a/target-sh4/translate.c
++++ b/target-sh4/translate.c
+@@ -1652,18 +1652,10 @@ static void _decode_opc(DisasContext * ctx)
+ 	}
+ 	return;
+     case 0x00a3:		/* ocbp @Rn */
+-	{
+-	    TCGv dummy = tcg_temp_new();
+-	    tcg_gen_qemu_ld32s(dummy, REG(B11_8), ctx->memidx);
+-	    tcg_temp_free(dummy);
+-	}
+-	return;
+     case 0x00b3:		/* ocbwb @Rn */
+-	{
+-	    TCGv dummy = tcg_temp_new();
+-	    tcg_gen_qemu_ld32s(dummy, REG(B11_8), ctx->memidx);
+-	    tcg_temp_free(dummy);
+-	}
++        /* These instructions are supposed to do nothing in case of
++           a cache miss. Given that we only partially emulate caches
++           it is safe to simply ignore them. */
+ 	return;
+     case 0x0083:		/* pref @Rn */
+ 	return;
+-- 
+1.7.7.5
+
diff --git a/0020-PPC-Fix-linker-scripts-on-ppc-hosts.patch b/0020-PPC-Fix-linker-scripts-on-ppc-hosts.patch
new file mode 100644
index 0000000..f6ce35a
--- /dev/null
+++ b/0020-PPC-Fix-linker-scripts-on-ppc-hosts.patch
@@ -0,0 +1,74 @@
+From fbcf305e5adc310e6383d4ec5e844f3f8d072116 Mon Sep 17 00:00:00 2001
+From: Alexander Graf <agraf@suse.de>
+Date: Mon, 12 Dec 2011 22:36:01 +0100
+Subject: [PATCH 20/25] PPC: Fix linker scripts on ppc hosts
+
+When compiling qemu statically with multilib on PPC, we hit the
+same issue that commit 845f2c2812d9ed24b36c02a3d06ee83aeafe8b49
+is fixing. Do the same here.
+
+Signed-off-by: Alexander Graf <agraf@suse.de>
+Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
+(cherry picked from commit 665a04ae1cbfa8004a38cf0fe99ba799c978a1fe)
+---
+ ppc.ld   |   16 ++++++++++++++--
+ ppc64.ld |   16 ++++++++++++++--
+ 2 files changed, 28 insertions(+), 4 deletions(-)
+
+diff --git a/ppc.ld b/ppc.ld
+index 69aa3f2..2a0dcad 100644
+--- a/ppc.ld
++++ b/ppc.ld
+@@ -49,8 +49,20 @@ SECTIONS
+   .rela.sbss2     : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) }
+   .rel.bss        : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
+   .rela.bss       : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
+-  .rel.plt        : { *(.rel.plt) }
+-  .rela.plt       : { *(.rela.plt) }
++  .rel.plt      :
++  {
++    *(.rel.plt)
++    PROVIDE (__rel_iplt_start = .);
++    *(.rel.iplt)
++    PROVIDE (__rel_iplt_end = .);
++  }
++  .rela.plt       :
++  {
++    *(.rela.plt)
++    PROVIDE (__rela_iplt_start = .);
++    *(.rela.iplt)
++    PROVIDE (__rela_iplt_end = .);
++  }
+   .init           :
+   {
+     KEEP (*(.init))
+diff --git a/ppc64.ld b/ppc64.ld
+index 0a7c0dd..e2dafa0 100644
+--- a/ppc64.ld
++++ b/ppc64.ld
+@@ -54,8 +54,20 @@ SECTIONS
+       *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*)
+       *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
+     }
+-  .rel.plt        : { *(.rel.plt) }
+-  .rela.plt       : { *(.rela.plt) }
++  .rel.plt      :
++  {
++    *(.rel.plt)
++    PROVIDE (__rel_iplt_start = .);
++    *(.rel.iplt)
++    PROVIDE (__rel_iplt_end = .);
++  }
++  .rela.plt       :
++  {
++    *(.rela.plt)
++    PROVIDE (__rela_iplt_start = .);
++    *(.rela.iplt)
++    PROVIDE (__rela_iplt_end = .);
++  }
+   .rela.tocbss	  : { *(.rela.tocbss) }
+   .init           :
+   {
+-- 
+1.7.7.5
+
diff --git a/0020-qxl-async-io-support-using-new-spice-api.patch b/0020-qxl-async-io-support-using-new-spice-api.patch
deleted file mode 100644
index 68ed72c..0000000
--- a/0020-qxl-async-io-support-using-new-spice-api.patch
+++ /dev/null
@@ -1,659 +0,0 @@
->From a1950cb3afb36a78df3ac9a545d99baf7cc93ca2 Mon Sep 17 00:00:00 2001
-From: Alon Levy <alevy@redhat.com>
-Date: Thu, 23 Jun 2011 20:02:18 +0200
-Subject: [PATCH 20/28] qxl: async io support using new spice api
-
-Some of the QXL port i/o commands are waiting for the spice server to
-complete certain actions.  Add async versions for these commands, so we
-don't block the vcpu while the spice server processses the command.
-Instead the qxl device will raise an IRQ when done.
-
-The async command processing relies on an added QXLInterface::async_complete
-and added QXLWorker::*_async additions, in spice server qxl >= 3.1
-
-Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
-Signed-off-by: Alon Levy     <alevy@redhat.com>
----
- hw/qxl-render.c    |    2 +-
- hw/qxl.c           |  240 ++++++++++++++++++++++++++++++++++++++++++++--------
- hw/qxl.h           |   16 +++-
- ui/spice-display.c |   47 ++++++++--
- ui/spice-display.h |   23 +++++-
- 5 files changed, 274 insertions(+), 54 deletions(-)
-
-diff --git a/hw/qxl-render.c b/hw/qxl-render.c
-index 60b822d..643ff2d 100644
---- a/hw/qxl-render.c
-+++ b/hw/qxl-render.c
-@@ -125,7 +125,7 @@ void qxl_render_update(PCIQXLDevice *qxl)
- 
-     memset(dirty, 0, sizeof(dirty));
-     qxl_spice_update_area(qxl, 0, &update,
--                          dirty, ARRAY_SIZE(dirty), 1);
-+                          dirty, ARRAY_SIZE(dirty), 1, QXL_SYNC);
- 
-     for (i = 0; i < ARRAY_SIZE(dirty); i++) {
-         if (qemu_spice_rect_is_empty(dirty+i)) {
-diff --git a/hw/qxl.c b/hw/qxl.c
-index 23e3240..d3109e4 100644
---- a/hw/qxl.c
-+++ b/hw/qxl.c
-@@ -120,7 +120,7 @@ static QXLMode qxl_modes[] = {
- static PCIQXLDevice *qxl0;
- 
- static void qxl_send_events(PCIQXLDevice *d, uint32_t events);
--static void qxl_destroy_primary(PCIQXLDevice *d);
-+static int qxl_destroy_primary(PCIQXLDevice *d, qxl_async_io async);
- static void qxl_reset_memslots(PCIQXLDevice *d);
- static void qxl_reset_surfaces(PCIQXLDevice *d);
- static void qxl_ring_set_dirty(PCIQXLDevice *qxl);
-@@ -144,22 +144,47 @@ void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg, ...)
- void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
-                            struct QXLRect *area, struct QXLRect *dirty_rects,
-                            uint32_t num_dirty_rects,
--                           uint32_t clear_dirty_region)
-+                           uint32_t clear_dirty_region,
-+                           qxl_async_io async)
- {
--    qxl->ssd.worker->update_area(qxl->ssd.worker, surface_id, area, dirty_rects,
--                             num_dirty_rects, clear_dirty_region);
-+    if (async == QXL_SYNC) {
-+        qxl->ssd.worker->update_area(qxl->ssd.worker, surface_id, area,
-+                        dirty_rects, num_dirty_rects, clear_dirty_region);
-+    } else {
-+#if SPICE_INTERFACE_QXL_MINOR >= 1
-+        spice_qxl_update_area_async(&qxl->ssd.qxl, surface_id, area,
-+                                    clear_dirty_region, 0);
-+#else
-+        abort();
-+#endif
-+    }
- }
- 
--void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id)
-+static void qxl_spice_destroy_surface_wait_complete(PCIQXLDevice *qxl,
-+                                                    uint32_t id)
- {
-     qemu_mutex_lock(&qxl->track_lock);
--    PANIC_ON(id >= NUM_SURFACES);
--    qxl->ssd.worker->destroy_surface_wait(qxl->ssd.worker, id);
-     qxl->guest_surfaces.cmds[id] = 0;
-     qxl->guest_surfaces.count--;
-     qemu_mutex_unlock(&qxl->track_lock);
- }
- 
-+static void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id,
-+                                           qxl_async_io async)
-+{
-+    if (async) {
-+#if SPICE_INTERFACE_QXL_MINOR < 1
-+        abort();
-+#else
-+        spice_qxl_destroy_surface_async(&qxl->ssd.qxl, id,
-+                                        (uint64_t)id);
-+#endif
-+    } else {
-+        qxl->ssd.worker->destroy_surface_wait(qxl->ssd.worker, id);
-+        qxl_spice_destroy_surface_wait_complete(qxl, id);
-+    }
-+}
-+
- void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
-                                uint32_t count)
- {
-@@ -176,15 +201,28 @@ void qxl_spice_reset_memslots(PCIQXLDevice *qxl)
-     qxl->ssd.worker->reset_memslots(qxl->ssd.worker);
- }
- 
--void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl)
-+static void qxl_spice_destroy_surfaces_complete(PCIQXLDevice *qxl)
- {
-     qemu_mutex_lock(&qxl->track_lock);
--    qxl->ssd.worker->destroy_surfaces(qxl->ssd.worker);
-     memset(&qxl->guest_surfaces.cmds, 0, sizeof(qxl->guest_surfaces.cmds));
-     qxl->guest_surfaces.count = 0;
-     qemu_mutex_unlock(&qxl->track_lock);
- }
- 
-+static void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl, qxl_async_io async)
-+{
-+    if (async) {
-+#if SPICE_INTERFACE_QXL_MINOR < 1
-+        abort();
-+#else
-+        spice_qxl_destroy_surfaces_async(&qxl->ssd.qxl, 0);
-+#endif
-+    } else {
-+        qxl->ssd.worker->destroy_surfaces(qxl->ssd.worker);
-+        qxl_spice_destroy_surfaces_complete(qxl);
-+    }
-+}
-+
- void qxl_spice_reset_image_cache(PCIQXLDevice *qxl)
- {
-     qxl->ssd.worker->reset_image_cache(qxl->ssd.worker);
-@@ -689,6 +727,38 @@ static int interface_flush_resources(QXLInstance *sin)
-     return ret;
- }
- 
-+static void qxl_create_guest_primary_complete(PCIQXLDevice *d);
-+
-+#if SPICE_INTERFACE_QXL_MINOR >= 1
-+
-+/* called from spice server thread context only */
-+static void interface_async_complete(QXLInstance *sin, uint64_t cookie)
-+{
-+    PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
-+    uint32_t current_async;
-+
-+    qemu_mutex_lock(&qxl->async_lock);
-+    current_async = qxl->current_async;
-+    qxl->current_async = QXL_UNDEFINED_IO;
-+    qemu_mutex_unlock(&qxl->async_lock);
-+
-+    dprint(qxl, 2, "async_complete: %d (%ld) done\n", current_async, cookie);
-+    switch (current_async) {
-+    case QXL_IO_CREATE_PRIMARY_ASYNC:
-+        qxl_create_guest_primary_complete(qxl);
-+        break;
-+    case QXL_IO_DESTROY_ALL_SURFACES_ASYNC:
-+        qxl_spice_destroy_surfaces_complete(qxl);
-+        break;
-+    case QXL_IO_DESTROY_SURFACE_ASYNC:
-+        qxl_spice_destroy_surface_wait_complete(qxl, (uint32_t)cookie);
-+        break;
-+    }
-+    qxl_send_events(qxl, QXL_INTERRUPT_IO_CMD);
-+}
-+
-+#endif
-+
- static const QXLInterface qxl_interface = {
-     .base.type               = SPICE_INTERFACE_QXL,
-     .base.description        = "qxl gpu",
-@@ -708,6 +778,9 @@ static const QXLInterface qxl_interface = {
-     .req_cursor_notification = interface_req_cursor_notification,
-     .notify_update           = interface_notify_update,
-     .flush_resources         = interface_flush_resources,
-+#if SPICE_INTERFACE_QXL_MINOR >= 1
-+    .async_complete          = interface_async_complete,
-+#endif
- };
- 
- static void qxl_enter_vga_mode(PCIQXLDevice *d)
-@@ -727,7 +800,7 @@ static void qxl_exit_vga_mode(PCIQXLDevice *d)
-         return;
-     }
-     dprint(d, 1, "%s\n", __FUNCTION__);
--    qxl_destroy_primary(d);
-+    qxl_destroy_primary(d, QXL_SYNC);
- }
- 
- static void qxl_set_irq(PCIQXLDevice *d)
-@@ -824,13 +897,14 @@ static void qxl_vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
- 
-     if (qxl->mode != QXL_MODE_VGA) {
-         dprint(qxl, 1, "%s\n", __FUNCTION__);
--        qxl_destroy_primary(qxl);
-+        qxl_destroy_primary(qxl, QXL_SYNC);
-         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 void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
-+                            qxl_async_io async)
- {
-     static const int regions[] = {
-         QXL_RAM_RANGE_INDEX,
-@@ -900,7 +974,7 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta)
-            __FUNCTION__, memslot.slot_id,
-            memslot.virt_start, memslot.virt_end);
- 
--    qemu_spice_add_memslot(&d->ssd, &memslot);
-+    qemu_spice_add_memslot(&d->ssd, &memslot, async);
-     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;
-@@ -925,7 +999,7 @@ static void qxl_reset_surfaces(PCIQXLDevice *d)
- {
-     dprint(d, 1, "%s:\n", __FUNCTION__);
-     d->mode = QXL_MODE_UNDEFINED;
--    qxl_spice_destroy_surfaces(d);
-+    qxl_spice_destroy_surfaces(d, QXL_SYNC);
- }
- 
- /* called from spice server thread context only */
-@@ -950,7 +1024,14 @@ void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id)
-     }
- }
- 
--static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm)
-+static void qxl_create_guest_primary_complete(PCIQXLDevice *qxl)
-+{
-+    /* for local rendering */
-+    qxl_render_resize(qxl);
-+}
-+
-+static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm,
-+                                     qxl_async_io async)
- {
-     QXLDevSurfaceCreate surface;
-     QXLSurfaceCreate *sc = &qxl->guest_primary.surface;
-@@ -978,22 +1059,26 @@ static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm)
- 
-     qxl->mode = QXL_MODE_NATIVE;
-     qxl->cmdflags = 0;
--    qemu_spice_create_primary_surface(&qxl->ssd, 0, &surface);
-+    qemu_spice_create_primary_surface(&qxl->ssd, 0, &surface, async);
- 
--    /* for local rendering */
--    qxl_render_resize(qxl);
-+    if (async == QXL_SYNC) {
-+        qxl_create_guest_primary_complete(qxl);
-+    }
- }
- 
--static void qxl_destroy_primary(PCIQXLDevice *d)
-+/* return 1 if surface destoy was initiated (in QXL_ASYNC case) or
-+ * done (in QXL_SYNC case), 0 otherwise. */
-+static int qxl_destroy_primary(PCIQXLDevice *d, qxl_async_io async)
- {
-     if (d->mode == QXL_MODE_UNDEFINED) {
--        return;
-+        return 0;
-     }
- 
-     dprint(d, 1, "%s\n", __FUNCTION__);
- 
-     d->mode = QXL_MODE_UNDEFINED;
--    qemu_spice_destroy_primary_surface(&d->ssd, 0);
-+    qemu_spice_destroy_primary_surface(&d->ssd, 0, async);
-+    return 1;
- }
- 
- static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
-@@ -1023,10 +1108,10 @@ static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
-     }
- 
-     d->guest_slots[0].slot = slot;
--    qxl_add_memslot(d, 0, devmem);
-+    qxl_add_memslot(d, 0, devmem, QXL_SYNC);
- 
-     d->guest_primary.surface = surface;
--    qxl_create_guest_primary(d, 0);
-+    qxl_create_guest_primary(d, 0, QXL_SYNC);
- 
-     d->mode = QXL_MODE_COMPAT;
-     d->cmdflags = QXL_COMMAND_FLAG_COMPAT;
-@@ -1044,6 +1129,10 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
- {
-     PCIQXLDevice *d = opaque;
-     uint32_t io_port = addr - d->io_base;
-+    qxl_async_io async = QXL_SYNC;
-+#if SPICE_INTERFACE_QXL_MINOR >= 1
-+    uint32_t orig_io_port = io_port;
-+#endif
- 
-     switch (io_port) {
-     case QXL_IO_RESET:
-@@ -1053,6 +1142,10 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
-     case QXL_IO_CREATE_PRIMARY:
-     case QXL_IO_UPDATE_IRQ:
-     case QXL_IO_LOG:
-+#if SPICE_INTERFACE_QXL_MINOR >= 1
-+    case QXL_IO_MEMSLOT_ADD_ASYNC:
-+    case QXL_IO_CREATE_PRIMARY_ASYNC:
-+#endif
-         break;
-     default:
-         if (d->mode != QXL_MODE_VGA) {
-@@ -1060,15 +1153,61 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
-         }
-         dprint(d, 1, "%s: unexpected port 0x%x (%s) in vga mode\n",
-             __func__, io_port, io_port_to_string(io_port));
-+#if SPICE_INTERFACE_QXL_MINOR >= 1
-+        /* be nice to buggy guest drivers */
-+        if (io_port >= QXL_IO_UPDATE_AREA_ASYNC &&
-+            io_port <= QXL_IO_DESTROY_ALL_SURFACES_ASYNC) {
-+            qxl_send_events(d, QXL_INTERRUPT_IO_CMD);
-+        }
-+#endif
-         return;
-     }
- 
-+#if SPICE_INTERFACE_QXL_MINOR >= 1
-+    /* we change the io_port to avoid ifdeffery in the main switch */
-+    orig_io_port = io_port;
-+    switch (io_port) {
-+    case QXL_IO_UPDATE_AREA_ASYNC:
-+        io_port = QXL_IO_UPDATE_AREA;
-+        goto async_common;
-+    case QXL_IO_MEMSLOT_ADD_ASYNC:
-+        io_port = QXL_IO_MEMSLOT_ADD;
-+        goto async_common;
-+    case QXL_IO_CREATE_PRIMARY_ASYNC:
-+        io_port = QXL_IO_CREATE_PRIMARY;
-+        goto async_common;
-+    case QXL_IO_DESTROY_PRIMARY_ASYNC:
-+        io_port = QXL_IO_DESTROY_PRIMARY;
-+        goto async_common;
-+    case QXL_IO_DESTROY_SURFACE_ASYNC:
-+        io_port = QXL_IO_DESTROY_SURFACE_WAIT;
-+        goto async_common;
-+    case QXL_IO_DESTROY_ALL_SURFACES_ASYNC:
-+        io_port = QXL_IO_DESTROY_ALL_SURFACES;
-+async_common:
-+        async = QXL_ASYNC;
-+        qemu_mutex_lock(&d->async_lock);
-+        if (d->current_async != QXL_UNDEFINED_IO) {
-+            qxl_guest_bug(d, "%d async started before last (%d) complete",
-+                io_port, d->current_async);
-+            qemu_mutex_unlock(&d->async_lock);
-+            return;
-+        }
-+        d->current_async = orig_io_port;
-+        qemu_mutex_unlock(&d->async_lock);
-+        dprint(d, 2, "start async %d (%d)\n", io_port, val);
-+        break;
-+    default:
-+        break;
-+    }
-+#endif
-+
-     switch (io_port) {
-     case QXL_IO_UPDATE_AREA:
-     {
-         QXLRect update = d->ram->update_area;
-         qxl_spice_update_area(d, d->ram->update_surface,
--                              &update, NULL, 0, 0);
-+                              &update, NULL, 0, 0, async);
-         break;
-     }
-     case QXL_IO_NOTIFY_CMD:
-@@ -1116,7 +1255,7 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
-             break;
-         }
-         d->guest_slots[val].slot = d->ram->mem_slot;
--        qxl_add_memslot(d, val, 0);
-+        qxl_add_memslot(d, val, 0, async);
-         break;
-     case QXL_IO_MEMSLOT_DEL:
-         if (val >= NUM_MEMSLOTS) {
-@@ -1127,31 +1266,56 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
-         break;
-     case QXL_IO_CREATE_PRIMARY:
-         if (val != 0) {
--            qxl_guest_bug(d, "QXL_IO_CREATE_PRIMARY: val != 0");
--            break;
-+            qxl_guest_bug(d, "QXL_IO_CREATE_PRIMARY (async=%d): val != 0",
-+                          async);
-+            goto cancel_async;
-         }
--        dprint(d, 1, "QXL_IO_CREATE_PRIMARY\n");
-+        dprint(d, 1, "QXL_IO_CREATE_PRIMARY async=%d\n", async);
-         d->guest_primary.surface = d->ram->create_surface;
--        qxl_create_guest_primary(d, 0);
-+        qxl_create_guest_primary(d, 0, async);
-         break;
-     case QXL_IO_DESTROY_PRIMARY:
-         if (val != 0) {
--            qxl_guest_bug(d, "QXL_IO_DESTROY_PRIMARY: val != 0");
--            break;
-+            qxl_guest_bug(d, "QXL_IO_DESTROY_PRIMARY (async=%d): val != 0",
-+                          async);
-+            goto cancel_async;
-+        }
-+        dprint(d, 1, "QXL_IO_DESTROY_PRIMARY (async=%d) (%s)\n", async,
-+               qxl_mode_to_string(d->mode));
-+        if (!qxl_destroy_primary(d, async)) {
-+            dprint(d, 1, "QXL_IO_DESTROY_PRIMARY_ASYNC in %s, ignored\n",
-+                    qxl_mode_to_string(d->mode));
-+            goto cancel_async;
-         }
--        dprint(d, 1, "QXL_IO_DESTROY_PRIMARY (%s)\n", qxl_mode_to_string(d->mode));
--        qxl_destroy_primary(d);
-         break;
-     case QXL_IO_DESTROY_SURFACE_WAIT:
--        qxl_spice_destroy_surface_wait(d, val);
-+        if (val >= NUM_SURFACES) {
-+            qxl_guest_bug(d, "QXL_IO_DESTROY_SURFACE (async=%d):"
-+                             "%d >= NUM_SURFACES", async, val);
-+            goto cancel_async;
-+        }
-+        qxl_spice_destroy_surface_wait(d, val, async);
-         break;
-     case QXL_IO_DESTROY_ALL_SURFACES:
--        qxl_spice_destroy_surfaces(d);
-+        d->mode = QXL_MODE_UNDEFINED;
-+        qxl_spice_destroy_surfaces(d, async);
-         break;
-     default:
-         fprintf(stderr, "%s: ioport=0x%x, abort()\n", __FUNCTION__, io_port);
-         abort();
-     }
-+    return;
-+cancel_async:
-+#if SPICE_INTERFACE_QXL_MINOR >= 1
-+    if (async) {
-+        qxl_send_events(d, QXL_INTERRUPT_IO_CMD);
-+        qemu_mutex_lock(&d->async_lock);
-+        d->current_async = QXL_UNDEFINED_IO;
-+        qemu_mutex_unlock(&d->async_lock);
-+    }
-+#else
-+    return;
-+#endif
- }
- 
- static uint32_t ioport_read(void *opaque, uint32_t addr)
-@@ -1364,6 +1528,8 @@ static int qxl_init_common(PCIQXLDevice *qxl)
-     qxl->num_memslots = NUM_MEMSLOTS;
-     qxl->num_surfaces = NUM_SURFACES;
-     qemu_mutex_init(&qxl->track_lock);
-+    qemu_mutex_init(&qxl->async_lock);
-+    qxl->current_async = QXL_UNDEFINED_IO;
- 
-     switch (qxl->revision) {
-     case 1: /* spice 0.4 -- qxl-1 */
-@@ -1528,9 +1694,9 @@ static int qxl_post_load(void *opaque, int version)
-             if (!d->guest_slots[i].active) {
-                 continue;
-             }
--            qxl_add_memslot(d, i, 0);
-+            qxl_add_memslot(d, i, 0, QXL_SYNC);
-         }
--        qxl_create_guest_primary(d, 1);
-+        qxl_create_guest_primary(d, 1, QXL_SYNC);
- 
-         /* replay surface-create and cursor-set commands */
-         cmds = qemu_mallocz(sizeof(QXLCommandExt) * (NUM_SURFACES + 1));
-diff --git a/hw/qxl.h b/hw/qxl.h
-index 32ca5a0..1046205 100644
---- a/hw/qxl.h
-+++ b/hw/qxl.h
-@@ -15,6 +15,8 @@ enum qxl_mode {
-     QXL_MODE_NATIVE,
- };
- 
-+#define QXL_UNDEFINED_IO UINT32_MAX
-+
- typedef struct PCIQXLDevice {
-     PCIDevice          pci;
-     SimpleSpiceDisplay ssd;
-@@ -30,6 +32,9 @@ typedef struct PCIQXLDevice {
-     int32_t            num_memslots;
-     int32_t            num_surfaces;
- 
-+    uint32_t           current_async;
-+    QemuMutex          async_lock;
-+
-     struct guest_slots {
-         QXLMemSlot     slot;
-         void           *ptr;
-@@ -104,13 +109,12 @@ void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg, ...);
- void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
-                            struct QXLRect *area, struct QXLRect *dirty_rects,
-                            uint32_t num_dirty_rects,
--                           uint32_t clear_dirty_region);
--void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id);
-+                           uint32_t clear_dirty_region,
-+                           qxl_async_io async);
- void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
-                                uint32_t count);
- void qxl_spice_oom(PCIQXLDevice *qxl);
- void qxl_spice_reset_memslots(PCIQXLDevice *qxl);
--void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl);
- void qxl_spice_reset_image_cache(PCIQXLDevice *qxl);
- void qxl_spice_reset_cursor(PCIQXLDevice *qxl);
- 
-@@ -122,3 +126,9 @@ 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);
-+#if SPICE_INTERFACE_QXL_MINOR >= 1
-+void qxl_spice_update_area_async(PCIQXLDevice *qxl, uint32_t surface_id,
-+                                 struct QXLRect *area,
-+                                 uint32_t clear_dirty_region,
-+                                 int is_vga);
-+#endif
-diff --git a/ui/spice-display.c b/ui/spice-display.c
-index af10ae8..683d454 100644
---- a/ui/spice-display.c
-+++ b/ui/spice-display.c
-@@ -62,10 +62,18 @@ void qemu_spice_rect_union(QXLRect *dest, const QXLRect *r)
-     dest->right = MAX(dest->right, r->right);
- }
- 
--
--void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot)
--{
--    ssd->worker->add_memslot(ssd->worker, memslot);
-+void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot,
-+                            qxl_async_io async)
-+{
-+    if (async != QXL_SYNC) {
-+#if SPICE_INTERFACE_QXL_MINOR >= 1
-+        spice_qxl_add_memslot_async(&ssd->qxl, memslot, 0);
-+#else
-+        abort();
-+#endif
-+    } else {
-+        ssd->worker->add_memslot(ssd->worker, memslot);
-+    }
- }
- 
- void qemu_spice_del_memslot(SimpleSpiceDisplay *ssd, uint32_t gid, uint32_t sid)
-@@ -74,14 +82,33 @@ void qemu_spice_del_memslot(SimpleSpiceDisplay *ssd, uint32_t gid, uint32_t sid)
- }
- 
- void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id,
--                                       QXLDevSurfaceCreate *surface)
--{
--    ssd->worker->create_primary_surface(ssd->worker, id, surface);
-+                                       QXLDevSurfaceCreate *surface,
-+                                       qxl_async_io async)
-+{
-+    if (async != QXL_SYNC) {
-+#if SPICE_INTERFACE_QXL_MINOR >= 1
-+        spice_qxl_create_primary_surface_async(&ssd->qxl, id, surface, 0);
-+#else
-+        abort();
-+#endif
-+    } else {
-+        ssd->worker->create_primary_surface(ssd->worker, id, surface);
-+    }
- }
- 
--void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id)
-+
-+void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd,
-+                                        uint32_t id, qxl_async_io async)
- {
--    ssd->worker->destroy_primary_surface(ssd->worker, id);
-+    if (async != QXL_SYNC) {
-+#if SPICE_INTERFACE_QXL_MINOR >= 1
-+        spice_qxl_destroy_primary_surface_async(&ssd->qxl, id, 0);
-+#else
-+        abort();
-+#endif
-+    } else {
-+        ssd->worker->destroy_primary_surface(ssd->worker, id);
-+    }
- }
- 
- void qemu_spice_wakeup(SimpleSpiceDisplay *ssd)
-@@ -198,7 +225,7 @@ void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd)
-     memset(&memslot, 0, sizeof(memslot));
-     memslot.slot_group_id = MEMSLOT_GROUP_HOST;
-     memslot.virt_end = ~0;
--    qemu_spice_add_memslot(ssd, &memslot);
-+    qemu_spice_add_memslot(ssd, &memslot, QXL_SYNC);
- }
- 
- void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
-@@ -218,14 +245,14 @@ void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
-     surface.mem        = (intptr_t)ssd->buf;
-     surface.group_id   = MEMSLOT_GROUP_HOST;
- 
--    qemu_spice_create_primary_surface(ssd, 0, &surface);
-+    qemu_spice_create_primary_surface(ssd, 0, &surface, QXL_SYNC);
- }
- 
- void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd)
- {
-     dprint(1, "%s:\n", __FUNCTION__);
- 
--    qemu_spice_destroy_primary_surface(ssd, 0);
-+    qemu_spice_destroy_primary_surface(ssd, 0, QXL_SYNC);
- }
- 
- void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason)
-diff --git a/ui/spice-display.h b/ui/spice-display.h
-index abe99c7..1388641 100644
---- a/ui/spice-display.h
-+++ b/ui/spice-display.h
-@@ -33,6 +33,20 @@
- 
- #define NUM_SURFACES 1024
- 
-+/*
-+ * Internal enum to differenciate between options for
-+ * io calls that have a sync (old) version and an _async (new)
-+ * version:
-+ *  QXL_SYNC: use the old version
-+ *  QXL_ASYNC: use the new version and make sure there are no two
-+ *   happening at the same time. This is used for guest initiated
-+ *   calls
-+ */
-+typedef enum qxl_async_io {
-+    QXL_SYNC,
-+    QXL_ASYNC,
-+} qxl_async_io;
-+
- typedef struct SimpleSpiceDisplay SimpleSpiceDisplay;
- typedef struct SimpleSpiceUpdate SimpleSpiceUpdate;
- 
-@@ -82,12 +96,15 @@ void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
- void qemu_spice_display_resize(SimpleSpiceDisplay *ssd);
- void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd);
- 
--void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot);
-+void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot,
-+                            qxl_async_io async);
- void qemu_spice_del_memslot(SimpleSpiceDisplay *ssd, uint32_t gid,
-                             uint32_t sid);
- void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id,
--                                       QXLDevSurfaceCreate *surface);
--void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id);
-+                                       QXLDevSurfaceCreate *surface,
-+                                       qxl_async_io async);
-+void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd,
-+                                        uint32_t id, qxl_async_io async);
- void qemu_spice_wakeup(SimpleSpiceDisplay *ssd);
- void qemu_spice_start(SimpleSpiceDisplay *ssd);
- void qemu_spice_stop(SimpleSpiceDisplay *ssd);
--- 
-1.7.5.1
-
diff --git a/0021-qiov-prevent-double-free-or-use-after-free.patch b/0021-qiov-prevent-double-free-or-use-after-free.patch
new file mode 100644
index 0000000..08e0e84
--- /dev/null
+++ b/0021-qiov-prevent-double-free-or-use-after-free.patch
@@ -0,0 +1,34 @@
+From 6061f16a8a119a46e61f2ddbabdb58f83e8857f7 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Fri, 25 Nov 2011 12:06:22 +0100
+Subject: [PATCH 21/25] qiov: prevent double free or use-after-free
+
+qemu_iovec_destroy does not clear the QEMUIOVector fully, and the data
+could thus be used after free or freed again.  While I do not know any
+example in the tree, I observed this using virtio-scsi (and SCSI
+scatter/gather) when canceling DMA requests.
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+---
+ cutils.c |    3 +++
+ 1 files changed, 3 insertions(+), 0 deletions(-)
+
+diff --git a/cutils.c b/cutils.c
+index 6db6304..24b3fe3 100644
+--- a/cutils.c
++++ b/cutils.c
+@@ -217,7 +217,10 @@ void qemu_iovec_destroy(QEMUIOVector *qiov)
+ {
+     assert(qiov->nalloc != -1);
+
++    qemu_iovec_reset(qiov);
+     g_free(qiov->iov);
++    qiov->nalloc = 0;
++    qiov->iov = NULL;
+ }
+
+ void qemu_iovec_reset(QEMUIOVector *qiov)
+-- 
+1.7.7.5
+
diff --git a/0021-qxl-add-QXL_IO_FLUSH_-SURFACES-RELEASE-for-guest-S3-.patch b/0021-qxl-add-QXL_IO_FLUSH_-SURFACES-RELEASE-for-guest-S3-.patch
deleted file mode 100644
index 41b88a3..0000000
--- a/0021-qxl-add-QXL_IO_FLUSH_-SURFACES-RELEASE-for-guest-S3-.patch
+++ /dev/null
@@ -1,77 +0,0 @@
->From fed782e33714e6a44bca9a8c3ab8b017393e8089 Mon Sep 17 00:00:00 2001
-From: Alon Levy <alevy@redhat.com>
-Date: Sun, 5 Jun 2011 11:01:48 +0300
-Subject: [PATCH 21/28] qxl: add QXL_IO_FLUSH_{SURFACES,RELEASE} for guest
- S3&S4 support
-
-Add two new IOs.
- QXL_IO_FLUSH_SURFACES - equivalent to update area for all surfaces, used
-  to reduce vmexits from NumSurfaces to 1 on guest S3, S4 and resolution change (windows
-  driver implementation is such that this is done on each of those occasions).
- QXL_IO_FLUSH_RELEASE - used to ensure anything on last_release is put on the release ring
-  for the client to free.
-
-Signed-off-by: Yonit Halperin <yhalperi@redhat.com>
-Signed-off-by: Alon Levy <alevy@redhat.com>
----
- hw/qxl.c |   30 ++++++++++++++++++++++++++++++
- 1 files changed, 30 insertions(+), 0 deletions(-)
-
-diff --git a/hw/qxl.c b/hw/qxl.c
-index d3109e4..847a9b8 100644
---- a/hw/qxl.c
-+++ b/hw/qxl.c
-@@ -185,6 +185,13 @@ static void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id,
-     }
- }
- 
-+#if SPICE_INTERFACE_QXL_MINOR >= 1
-+static void qxl_spice_flush_surfaces_async(PCIQXLDevice *qxl)
-+{
-+    spice_qxl_flush_surfaces_async(&qxl->ssd.qxl, 0);
-+}
-+#endif
-+
- void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
-                                uint32_t count)
- {
-@@ -1184,6 +1191,8 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
-         goto async_common;
-     case QXL_IO_DESTROY_ALL_SURFACES_ASYNC:
-         io_port = QXL_IO_DESTROY_ALL_SURFACES;
-+        goto async_common;
-+    case QXL_IO_FLUSH_SURFACES_ASYNC:
- async_common:
-         async = QXL_ASYNC;
-         qemu_mutex_lock(&d->async_lock);
-@@ -1296,6 +1305,27 @@ async_common:
-         }
-         qxl_spice_destroy_surface_wait(d, val, async);
-         break;
-+#if SPICE_INTERFACE_QXL_MINOR >= 1
-+    case QXL_IO_FLUSH_RELEASE: {
-+        QXLReleaseRing *ring = &d->ram->release_ring;
-+        if (ring->prod - ring->cons + 1 == ring->num_items) {
-+            fprintf(stderr,
-+                "ERROR: no flush, full release ring [p%d,%dc]\n",
-+                ring->prod, ring->cons);
-+        }
-+        qxl_push_free_res(d, 1 /* flush */);
-+        dprint(d, 1, "QXL_IO_FLUSH_RELEASE exit (%s, s#=%d, res#=%d,%p)\n",
-+            qxl_mode_to_string(d->mode), d->guest_surfaces.count,
-+            d->num_free_res, d->last_release);
-+        break;
-+    }
-+    case QXL_IO_FLUSH_SURFACES_ASYNC:
-+        dprint(d, 1, "QXL_IO_FLUSH_SURFACES_ASYNC (%d) (%s, s#=%d, res#=%d)\n",
-+               val, qxl_mode_to_string(d->mode), d->guest_surfaces.count,
-+               d->num_free_res);
-+        qxl_spice_flush_surfaces_async(d);
-+        break;
-+#endif
-     case QXL_IO_DESTROY_ALL_SURFACES:
-         d->mode = QXL_MODE_UNDEFINED;
-         qxl_spice_destroy_surfaces(d, async);
--- 
-1.7.5.1
-
diff --git a/0022-coroutine-switch-per-thread-free-pool-to-a-global-po.patch b/0022-coroutine-switch-per-thread-free-pool-to-a-global-po.patch
new file mode 100644
index 0000000..eebdfaa
--- /dev/null
+++ b/0022-coroutine-switch-per-thread-free-pool-to-a-global-po.patch
@@ -0,0 +1,115 @@
+From fe5c13ebf1161d0f324229cfb36cb5fb87ec6248 Mon Sep 17 00:00:00 2001
+From: Avi Kivity <avi@redhat.com>
+Date: Mon, 5 Dec 2011 19:20:12 +0200
+Subject: [PATCH 22/25] coroutine: switch per-thread free pool to a global
+ pool
+
+ucontext-based coroutines use a free pool to reduce allocations and
+deallocations of coroutine objects.  The pool is per-thread, presumably
+to improve locality.  However, as coroutines are usually allocated in
+a vcpu thread and freed in the I/O thread, the pool accounting gets
+screwed up and we end allocating and freeing a coroutine for every I/O
+request.  This is expensive since large objects are allocated via the
+kernel, and are not cached by the C runtime.
+
+Fix by switching to a global pool.  This is safe since we're protected
+by the global mutex.
+
+Signed-off-by: Avi Kivity <avi@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+---
+ coroutine-ucontext.c |   30 ++++++++++++++++--------------
+ 1 files changed, 16 insertions(+), 14 deletions(-)
+
+diff --git a/coroutine-ucontext.c b/coroutine-ucontext.c
+index 2b8d3e9..3d01075 100644
+--- a/coroutine-ucontext.c
++++ b/coroutine-ucontext.c
+@@ -35,6 +35,10 @@ enum {
+     POOL_MAX_SIZE = 64,
+ };
+
++/** Free list to speed up creation */
++static QLIST_HEAD(, Coroutine) pool = QLIST_HEAD_INITIALIZER(pool);
++static unsigned int pool_size;
++
+ typedef struct {
+     Coroutine base;
+     void *stack;
+@@ -48,10 +52,6 @@ typedef struct {
+     /** Currently executing coroutine */
+     Coroutine *current;
+
+-    /** Free list to speed up creation */
+-    QLIST_HEAD(, Coroutine) pool;
+-    unsigned int pool_size;
+-
+     /** The default coroutine */
+     CoroutineUContext leader;
+ } CoroutineThreadState;
+@@ -75,7 +75,6 @@ static CoroutineThreadState *coroutine_get_thread_state(void)
+     if (!s) {
+         s = g_malloc0(sizeof(*s));
+         s->current = &s->leader.base;
+-        QLIST_INIT(&s->pool);
+         pthread_setspecific(thread_state_key, s);
+     }
+     return s;
+@@ -84,14 +83,19 @@ static CoroutineThreadState *coroutine_get_thread_state(void)
+ static void qemu_coroutine_thread_cleanup(void *opaque)
+ {
+     CoroutineThreadState *s = opaque;
++
++    g_free(s);
++}
++
++static void __attribute__((destructor)) coroutine_cleanup(void)
++{
+     Coroutine *co;
+     Coroutine *tmp;
+
+-    QLIST_FOREACH_SAFE(co, &s->pool, pool_next, tmp) {
++    QLIST_FOREACH_SAFE(co, &pool, pool_next, tmp) {
+         g_free(DO_UPCAST(CoroutineUContext, base, co)->stack);
+         g_free(co);
+     }
+-    g_free(s);
+ }
+
+ static void __attribute__((constructor)) coroutine_init(void)
+@@ -169,13 +173,12 @@ static Coroutine *coroutine_new(void)
+
+ Coroutine *qemu_coroutine_new(void)
+ {
+-    CoroutineThreadState *s = coroutine_get_thread_state();
+     Coroutine *co;
+
+-    co = QLIST_FIRST(&s->pool);
++    co = QLIST_FIRST(&pool);
+     if (co) {
+         QLIST_REMOVE(co, pool_next);
+-        s->pool_size--;
++        pool_size--;
+     } else {
+         co = coroutine_new();
+     }
+@@ -184,13 +187,12 @@ Coroutine *qemu_coroutine_new(void)
+
+ void qemu_coroutine_delete(Coroutine *co_)
+ {
+-    CoroutineThreadState *s = coroutine_get_thread_state();
+     CoroutineUContext *co = DO_UPCAST(CoroutineUContext, base, co_);
+
+-    if (s->pool_size < POOL_MAX_SIZE) {
+-        QLIST_INSERT_HEAD(&s->pool, &co->base, pool_next);
++    if (pool_size < POOL_MAX_SIZE) {
++        QLIST_INSERT_HEAD(&pool, &co->base, pool_next);
+         co->base.caller = NULL;
+-        s->pool_size++;
++        pool_size++;
+         return;
+     }
+
+-- 
+1.7.7.5
+
diff --git a/0022-qxl-bump-pci-rev.patch b/0022-qxl-bump-pci-rev.patch
deleted file mode 100644
index 17ebfc1..0000000
--- a/0022-qxl-bump-pci-rev.patch
+++ /dev/null
@@ -1,90 +0,0 @@
->From 81c99528614b45f2b8407418f7e2b5742559ac19 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Wed, 29 Jun 2011 15:51:24 +0200
-Subject: [PATCH 22/28] qxl: bump pci rev
-
-Inform guest drivers about the new features I/O commands we have
-now (async commands, S3 support) if building with newer spice, i.e.
-if SPICE_INTERFACE_QXL_MINOR >= 1.
-
-sneaked in some 81+ column line spliting.
-
-Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
-Signed-off-by: Alon Levy <alevy@redhat.com>
----
- hw/qxl.c |   25 ++++++++++++++++++-------
- hw/qxl.h |    6 ++++++
- 2 files changed, 24 insertions(+), 7 deletions(-)
-
-diff --git a/hw/qxl.c b/hw/qxl.c
-index 847a9b8..b684608 100644
---- a/hw/qxl.c
-+++ b/hw/qxl.c
-@@ -1566,9 +1566,14 @@ static int qxl_init_common(PCIQXLDevice *qxl)
-         pci_device_rev = QXL_REVISION_STABLE_V04;
-         break;
-     case 2: /* spice 0.6 -- qxl-2 */
--    default:
-         pci_device_rev = QXL_REVISION_STABLE_V06;
-         break;
-+#if SPICE_INTERFACE_QXL_MINOR >= 1
-+    case 3: /* qxl-3 */
-+#endif
-+    default:
-+        pci_device_rev = QXL_DEFAULT_REVISION;
-+        break;
-     }
- 
-     pci_set_byte(&config[PCI_REVISION_ID], pci_device_rev);
-@@ -1830,9 +1835,12 @@ static PCIDeviceInfo qxl_info_primary = {
-     .device_id    = QXL_DEVICE_ID_STABLE,
-     .class_id     = PCI_CLASS_DISPLAY_VGA,
-     .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, 2),
-+        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,
-+                           QXL_DEFAULT_REVISION),
-         DEFINE_PROP_UINT32("debug", PCIQXLDevice, debug, 0),
-         DEFINE_PROP_UINT32("guestdebug", PCIQXLDevice, guestdebug, 0),
-         DEFINE_PROP_UINT32("cmdlog", PCIQXLDevice, cmdlog, 0),
-@@ -1851,9 +1859,12 @@ static PCIDeviceInfo qxl_info_secondary = {
-     .device_id    = QXL_DEVICE_ID_STABLE,
-     .class_id     = PCI_CLASS_DISPLAY_OTHER,
-     .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, 2),
-+        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,
-+                           QXL_DEFAULT_REVISION),
-         DEFINE_PROP_UINT32("debug", PCIQXLDevice, debug, 0),
-         DEFINE_PROP_UINT32("guestdebug", PCIQXLDevice, guestdebug, 0),
-         DEFINE_PROP_UINT32("cmdlog", PCIQXLDevice, cmdlog, 0),
-diff --git a/hw/qxl.h b/hw/qxl.h
-index 1046205..4bcf7e1 100644
---- a/hw/qxl.h
-+++ b/hw/qxl.h
-@@ -102,6 +102,12 @@ typedef struct PCIQXLDevice {
-         }                                                               \
-     } while (0)
- 
-+#if SPICE_INTERFACE_QXL_MINOR >= 1
-+#define QXL_DEFAULT_REVISION QXL_REVISION_STABLE_V10
-+#else
-+#define QXL_DEFAULT_REVISION QXL_REVISION_STABLE_V06
-+#endif
-+
- /* qxl.c */
- void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id);
- void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg, ...);
--- 
-1.7.5.1
-
diff --git a/0023-qemu-img-rebase-Fix-for-undersized-backing-files.patch b/0023-qemu-img-rebase-Fix-for-undersized-backing-files.patch
new file mode 100644
index 0000000..413ebd0
--- /dev/null
+++ b/0023-qemu-img-rebase-Fix-for-undersized-backing-files.patch
@@ -0,0 +1,86 @@
+From 5bb37d151b026759ee35f04212b11b4d625c7431 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Wed, 7 Dec 2011 12:42:10 +0100
+Subject: [PATCH 23/25] qemu-img rebase: Fix for undersized backing files
+
+Backing files may be smaller than the corresponding COW file. When
+reading directly from the backing file, qemu-img rebase must consider
+this and assume zero sectors after the end of backing files.
+
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
+---
+ qemu-img.c |   42 +++++++++++++++++++++++++++++++++---------
+ 1 files changed, 33 insertions(+), 9 deletions(-)
+
+diff --git a/qemu-img.c b/qemu-img.c
+index 8bdae66..01cc0d3 100644
+--- a/qemu-img.c
++++ b/qemu-img.c
+@@ -1420,6 +1420,8 @@ static int img_rebase(int argc, char **argv)
+      */
+     if (!unsafe) {
+         uint64_t num_sectors;
++        uint64_t old_backing_num_sectors;
++        uint64_t new_backing_num_sectors;
+         uint64_t sector;
+         int n;
+         uint8_t * buf_old;
+@@ -1430,6 +1432,8 @@ static int img_rebase(int argc, char **argv)
+         buf_new = qemu_blockalign(bs, IO_BUF_SIZE);
+
+         bdrv_get_geometry(bs, &num_sectors);
++        bdrv_get_geometry(bs_old_backing, &old_backing_num_sectors);
++        bdrv_get_geometry(bs_new_backing, &new_backing_num_sectors);
+
+         local_progress = (float)100 /
+             (num_sectors / MIN(num_sectors, IO_BUF_SIZE / 512));
+@@ -1448,16 +1452,36 @@ static int img_rebase(int argc, char **argv)
+                 continue;
+             }
+
+-            /* Read old and new backing file */
+-            ret = bdrv_read(bs_old_backing, sector, buf_old, n);
+-            if (ret < 0) {
+-                error_report("error while reading from old backing file");
+-                goto out;
++            /*
++             * Read old and new backing file and take into consideration that
++             * backing files may be smaller than the COW image.
++             */
++            if (sector >= old_backing_num_sectors) {
++                memset(buf_old, 0, n * BDRV_SECTOR_SIZE);
++            } else {
++                if (sector + n > old_backing_num_sectors) {
++                    n = old_backing_num_sectors - sector;
++                }
++
++                ret = bdrv_read(bs_old_backing, sector, buf_old, n);
++                if (ret < 0) {
++                    error_report("error while reading from old backing file");
++                    goto out;
++                }
+             }
+-            ret = bdrv_read(bs_new_backing, sector, buf_new, n);
+-            if (ret < 0) {
+-                error_report("error while reading from new backing file");
+-                goto out;
++
++            if (sector >= new_backing_num_sectors) {
++                memset(buf_new, 0, n * BDRV_SECTOR_SIZE);
++            } else {
++                if (sector + n > new_backing_num_sectors) {
++                    n = new_backing_num_sectors - sector;
++                }
++
++                ret = bdrv_read(bs_new_backing, sector, buf_new, n);
++                if (ret < 0) {
++                    error_report("error while reading from new backing file");
++                    goto out;
++                }
+             }
+
+             /* If they differ, we need to write to the COW file */
+-- 
+1.7.7.5
+
diff --git a/0023-virtio-serial-bus-replay-guest_open-on-migration.patch b/0023-virtio-serial-bus-replay-guest_open-on-migration.patch
deleted file mode 100644
index 5abb114..0000000
--- a/0023-virtio-serial-bus-replay-guest_open-on-migration.patch
+++ /dev/null
@@ -1,50 +0,0 @@
->From ab57ac80b3e681a61ed34c84c36df673e6f9be33 Mon Sep 17 00:00:00 2001
-From: Alon Levy <alevy@redhat.com>
-Date: Thu, 28 Jul 2011 15:08:48 +0300
-Subject: [PATCH 23/28] virtio-serial-bus: replay guest_open on migration
-
-When migrating a host with with a spice agent running the mouse becomes
-non operational after the migration. This is rhbz #725965.
-
-The problem is that after migration spice doesn't know the guest agent is open.
-Spice is just a char dev here. And a chardev cannot query it's device, the
-device has to let the chardev know when it is open. Right now after migration
-the chardev which is recreated is in it's default state, which assumes the
-guest is disconnected.
-
-Char devices carry no information across migration, but the virtio-serial does
-already carry the guest_connected state. This patch passes that bit to the
-chardev.
-
-Signed-off-by: Alon Levy <alevy@redhat.com>
----
- hw/virtio-serial-bus.c |    6 ++++++
- 1 files changed, 6 insertions(+), 0 deletions(-)
-
-diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
-index c5eb931..4a6d932 100644
---- a/hw/virtio-serial-bus.c
-+++ b/hw/virtio-serial-bus.c
-@@ -618,6 +618,7 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id)
-     for (i = 0; i < nr_active_ports; i++) {
-         uint32_t id;
-         bool host_connected;
-+        VirtIOSerialPortInfo *info;
- 
-         id = qemu_get_be32(f);
-         port = find_port_by_id(s, id);
-@@ -626,6 +627,11 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id)
-         }
- 
-         port->guest_connected = qemu_get_byte(f);
-+        info = DO_UPCAST(VirtIOSerialPortInfo, qdev, port->dev.info);
-+        if (port->guest_connected && info->guest_open) {
-+            /* replay guest open */
-+            info->guest_open(port);
-+        }
-         host_connected = qemu_get_byte(f);
-         if (host_connected != port->host_connected) {
-             /*
--- 
-1.7.5.1
-
diff --git a/0024-Documentation-Add-qemu-img-t-parameter-in-man-page.patch b/0024-Documentation-Add-qemu-img-t-parameter-in-man-page.patch
new file mode 100644
index 0000000..6df771d
--- /dev/null
+++ b/0024-Documentation-Add-qemu-img-t-parameter-in-man-page.patch
@@ -0,0 +1,82 @@
+From 8afe984ef7aa25cb2f8af51da021fdc8a242884d Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Wed, 7 Dec 2011 13:57:13 +0100
+Subject: [PATCH 24/25] Documentation: Add qemu-img -t parameter in man page
+
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
+---
+ qemu-img-cmds.hx |    6 +++---
+ qemu-img.texi    |   10 +++++++---
+ 2 files changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
+index 4be00a5..49dce7c 100644
+--- a/qemu-img-cmds.hx
++++ b/qemu-img-cmds.hx
+@@ -24,13 +24,13 @@ ETEXI
+ DEF("commit", img_commit,
+     "commit [-f fmt] [-t cache] filename")
+ STEXI
+-@item commit [-f @var{fmt}] @var{filename}
++@item commit [-f @var{fmt}] [-t @var{cache}] @var{filename}
+ ETEXI
+
+ DEF("convert", img_convert,
+     "convert [-c] [-p] [-f fmt] [-t cache] [-O output_fmt] [-o options] [-s snapshot_name] [-S sparse_size] filename [filename2 [...]] output_filename")
+ STEXI
+-@item convert [-c] [-p] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
++@item convert [-c] [-p] [-f @var{fmt}] [-t @var{cache}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
+ ETEXI
+
+ DEF("info", img_info,
+@@ -48,7 +48,7 @@ ETEXI
+ DEF("rebase", img_rebase,
+     "rebase [-f fmt] [-t cache] [-p] [-u] -b backing_file [-F backing_fmt] filename")
+ STEXI
+-@item rebase [-f @var{fmt}] [-p] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename}
++@item rebase [-f @var{fmt}] [-t @var{cache}] [-p] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename}
+ ETEXI
+
+ DEF("resize", img_resize,
+diff --git a/qemu-img.texi b/qemu-img.texi
+index 70fa321..b2ca3a5 100644
+--- a/qemu-img.texi
++++ b/qemu-img.texi
+@@ -45,6 +45,10 @@ indicates the consecutive number of bytes that must contain only zeros
+ for qemu-img to create a sparse image during conversion. This value is rounded
+ down to the nearest 512 bytes. You may use the common size suffixes like
+ @code{k} for kilobytes.
++@item -t @var{cache}
++specifies the cache mode that should be used with the (destination) file. See
++the documentation of the emulator's @code{-drive cache=...} option for allowed
++values.
+ @end table
+
+ Parameters to snapshot subcommand:
+@@ -87,11 +91,11 @@ this case. @var{backing_file} will never be modified unless you use the
+ The size can also be specified using the @var{size} option with @code{-o},
+ it doesn't need to be specified separately in this case.
+
+-@item commit [-f @var{fmt}] @var{filename}
++@item commit [-f @var{fmt}] [-t @var{cache}] @var{filename}
+
+ Commit the changes recorded in @var{filename} in its base image.
+
+-@item convert [-c] [-p] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
++@item convert [-c] [-p] [-f @var{fmt}] [-t @var{cache}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
+
+ Convert the disk image @var{filename} or a snapshot @var{snapshot_name} to disk image @var{output_filename}
+ using format @var{output_fmt}. It can be optionally compressed (@code{-c}
+@@ -121,7 +125,7 @@ they are displayed too.
+
+ List, apply, create or delete snapshots in image @var{filename}.
+
+-@item rebase [-f @var{fmt}] [-p] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename}
++@item rebase [-f @var{fmt}] [-t @var{cache}] [-p] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename}
+
+ Changes the backing file of an image. Only the formats @code{qcow2} and
+ @code{qed} support changing the backing file.
+-- 
+1.7.7.5
+
diff --git a/0024-qemu-char-make-qemu_chr_event-public.patch b/0024-qemu-char-make-qemu_chr_event-public.patch
deleted file mode 100644
index 2294597..0000000
--- a/0024-qemu-char-make-qemu_chr_event-public.patch
+++ /dev/null
@@ -1,42 +0,0 @@
->From c86147be45fe6cc38efa932f9587774d626a881b Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Thu, 11 Aug 2011 12:16:11 +0200
-Subject: [PATCH 24/28] qemu-char: make qemu_chr_event public
-
-Make qemu_chr_event public so that it can be used by chardev code
-which lives outside of qemu-char.c
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- qemu-char.c |    2 +-
- qemu-char.h |    1 +
- 2 files changed, 2 insertions(+), 1 deletions(-)
-
-diff --git a/qemu-char.c b/qemu-char.c
-index 8d39500..5d5a6d5 100644
---- a/qemu-char.c
-+++ b/qemu-char.c
-@@ -119,7 +119,7 @@ static void char_write_unblocked(void *opaque)
-     chr->chr_write_unblocked(chr->handler_opaque);
- }
- 
--static void qemu_chr_event(CharDriverState *s, int event)
-+void qemu_chr_event(CharDriverState *s, int event)
- {
-     /* Keep track if the char device is open */
-     switch (event) {
-diff --git a/qemu-char.h b/qemu-char.h
-index 68e7b5b..77ad62d 100644
---- a/qemu-char.h
-+++ b/qemu-char.h
-@@ -107,6 +107,7 @@ int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg);
- void qemu_chr_generic_open(CharDriverState *s);
- int qemu_chr_can_read(CharDriverState *s);
- void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len);
-+void qemu_chr_event(CharDriverState *s, int event);
- int qemu_chr_get_msgfd(CharDriverState *s);
- void qemu_chr_accept_input(CharDriverState *s);
- int qemu_chr_add_client(CharDriverState *s, int fd);
--- 
-1.7.5.1
-
diff --git a/0025-rbd-always-set-out-parameter-in-qemu_rbd_snap_list.patch b/0025-rbd-always-set-out-parameter-in-qemu_rbd_snap_list.patch
new file mode 100644
index 0000000..fb7010d
--- /dev/null
+++ b/0025-rbd-always-set-out-parameter-in-qemu_rbd_snap_list.patch
@@ -0,0 +1,39 @@
+From e47c212cb5af148ab6d9dcf49bc0e054fe9c2e1d Mon Sep 17 00:00:00 2001
+From: Josh Durgin <josh.durgin@dreamhost.com>
+Date: Tue, 6 Dec 2011 17:05:10 -0800
+Subject: [PATCH 25/25] rbd: always set out parameter in qemu_rbd_snap_list
+
+The caller expects psn_tab to be NULL when there are no snapshots or
+an error occurs. This results in calling g_free on an invalid address.
+
+Reported-by: Oliver Francke <Oliver@filoo.de>
+Signed-off-by: Josh Durgin <josh.durgin@dreamhost.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+---
+ block/rbd.c |    3 ++-
+ 1 files changed, 2 insertions(+), 1 deletions(-)
+
+diff --git a/block/rbd.c b/block/rbd.c
+index 9088c52..54a6961 100644
+--- a/block/rbd.c
++++ b/block/rbd.c
+@@ -808,7 +808,7 @@ static int qemu_rbd_snap_list(BlockDriverState *bs,
+     } while (snap_count == -ERANGE);
+
+     if (snap_count <= 0) {
+-        return snap_count;
++        goto done;
+     }
+
+     sn_tab = g_malloc0(snap_count * sizeof(QEMUSnapshotInfo));
+@@ -827,6 +827,7 @@ static int qemu_rbd_snap_list(BlockDriverState *bs,
+     }
+     rbd_snap_list_end(snaps);
+
++ done:
+     *psn_tab = sn_tab;
+     return snap_count;
+ }
+-- 
+1.7.7.5
+
diff --git a/0025-spice-qemu-char-Generate-chardev-open-close-events.patch b/0025-spice-qemu-char-Generate-chardev-open-close-events.patch
deleted file mode 100644
index 7b4b41b..0000000
--- a/0025-spice-qemu-char-Generate-chardev-open-close-events.patch
+++ /dev/null
@@ -1,79 +0,0 @@
->From d98187ff877341b5db5ca7f9d50b238d5936052b Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Thu, 21 Jul 2011 15:36:40 +0200
-Subject: [PATCH 25/28] spice-qemu-char: Generate chardev open/close events
-
-Define a state callback and make that generate chardev open/close events when
-called by the spice-server.
-
-Note that for all but the newest spice-server versions (which have a fix for
-this) the code ignores these events for a spicevmc with a subtype of vdagent,
-this subtype specific knowledge is undesirable, but unavoidable for now, see:
-http://lists.freedesktop.org/archives/spice-devel/2011-July/004837.html
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- spice-qemu-char.c |   35 ++++++++++++++++++++++++++++++++++-
- 1 files changed, 34 insertions(+), 1 deletions(-)
-
-diff --git a/spice-qemu-char.c b/spice-qemu-char.c
-index 2b8aec4..d55e74a 100644
---- a/spice-qemu-char.c
-+++ b/spice-qemu-char.c
-@@ -89,11 +89,39 @@ static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len)
-     return bytes;
- }
- 
-+static void vmc_state(SpiceCharDeviceInstance *sin, int connected)
-+{
-+    SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin);
-+
-+#if SPICE_SERVER_VERSION < 0x000901
-+    /*
-+     * spice-server calls the state callback for the agent channel when the
-+     * spice client connects / disconnects. Given that not the client but
-+     * the server is doing the parsing of the messages this is wrong as the
-+     * server is still listening. Worse, this causes the parser in the server
-+     * to go out of sync, so we ignore state calls for subtype vdagent
-+     * spicevmc chardevs. For the full story see:
-+     * http://lists.freedesktop.org/archives/spice-devel/2011-July/004837.html
-+     */
-+    if (strcmp(sin->subtype, "vdagent") == 0) {
-+        return;
-+    }
-+#endif
-+
-+    if ((scd->chr->opened && connected) ||
-+        (!scd->chr->opened && !connected)) {
-+        return;
-+    }
-+
-+    qemu_chr_event(scd->chr, connected ? CHR_EVENT_OPENED : CHR_EVENT_CLOSED);
-+}
-+
- 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,
-+    .state              = vmc_state,
-     .write              = vmc_write,
-     .read               = vmc_read,
- };
-@@ -222,7 +250,12 @@ int qemu_chr_open_spice(QemuOpts *opts, CharDriverState **_chr)
-     chr->chr_guest_close = spice_chr_guest_close;
-     s->unblock_timer = qemu_new_timer_ms(vm_clock, spice_chr_unblock, s);
- 
--    qemu_chr_generic_open(chr);
-+#if SPICE_SERVER_VERSION < 0x000901
-+    /* See comment in vmc_state() */
-+    if (strcmp(subtype, "vdagent") == 0) {
-+        qemu_chr_generic_open(chr);
-+    }
-+#endif
- 
-     *_chr = chr;
-     return 0;
--- 
-1.7.5.1
-
diff --git a/0026-usb-redir-Call-qemu_chr_guest_open-close.patch b/0026-usb-redir-Call-qemu_chr_guest_open-close.patch
deleted file mode 100644
index 8bb4dbf..0000000
--- a/0026-usb-redir-Call-qemu_chr_guest_open-close.patch
+++ /dev/null
@@ -1,37 +0,0 @@
->From c8a865625b713ffc1cff6ff97fc3e4c01aeeb0f7 Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Thu, 21 Jul 2011 16:28:06 +0200
-Subject: [PATCH 26/28] usb-redir: Call qemu_chr_guest_open/close
-
-To let the chardev now we're ready start receiving data. This is necessary
-with the spicevmc chardev to get it registered with the spice-server.
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- usb-redir.c |    3 +++
- 1 files changed, 3 insertions(+), 0 deletions(-)
-
-diff --git a/usb-redir.c b/usb-redir.c
-index 6932beb..9ce2c8b 100644
---- a/usb-redir.c
-+++ b/usb-redir.c
-@@ -839,6 +839,8 @@ static int usbredir_initfn(USBDevice *udev)
-     /* We'll do the attach once we receive the speed from the usb-host */
-     udev->auto_attach = 0;
- 
-+    /* Let the other side know we are ready */
-+    qemu_chr_guest_open(dev->cs);
-     qemu_chr_add_handlers(dev->cs, &usbredir_chr_handlers, dev);
- 
-     return 0;
-@@ -861,6 +863,7 @@ static void usbredir_handle_destroy(USBDevice *udev)
- {
-     USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
- 
-+    qemu_chr_guest_close(dev->cs);
-     qemu_chr_close(dev->cs);
-     /* Note must be done after qemu_chr_close, as that causes a close event */
-     qemu_bh_delete(dev->open_close_bh);
--- 
-1.7.5.1
-
diff --git a/0027-usb-redir-Device-disconnect-re-connect-robustness-fi.patch b/0027-usb-redir-Device-disconnect-re-connect-robustness-fi.patch
deleted file mode 100644
index baf9f81..0000000
--- a/0027-usb-redir-Device-disconnect-re-connect-robustness-fi.patch
+++ /dev/null
@@ -1,88 +0,0 @@
->From a6fba82709859fc91e676ce53079eb250bb55750 Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Thu, 4 Aug 2011 14:41:07 +0200
-Subject: [PATCH 27/28] usb-redir: Device disconnect + re-connect robustness
- fixes
-
-These fixes mainly target the other side sending some (error status)
-packets after a disconnect packet. In some cases these would get queued
-up and then reported to the controller when a new device gets connected.
-
-* Fully reset device state on disconnect
-* Don't allow a connect message when already connected
-* Ignore iso and interrupt status messages when disconnected
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- usb-redir.c |   22 +++++++++++++++++++++-
- 1 files changed, 21 insertions(+), 1 deletions(-)
-
-diff --git a/usb-redir.c b/usb-redir.c
-index 9ce2c8b..6d8f986 100644
---- a/usb-redir.c
-+++ b/usb-redir.c
-@@ -905,6 +905,11 @@ static void usbredir_device_connect(void *priv,
- {
-     USBRedirDevice *dev = priv;
- 
-+    if (qemu_timer_pending(dev->attach_timer) || dev->dev.attached) {
-+        ERROR("Received device connect while already connected\n");
-+        return;
-+    }
-+
-     switch (device_connect->speed) {
-     case usb_redir_speed_low:
-         DPRINTF("attaching low speed device\n");
-@@ -933,19 +938,26 @@ static void usbredir_device_connect(void *priv,
- static void usbredir_device_disconnect(void *priv)
- {
-     USBRedirDevice *dev = priv;
-+    int i;
- 
-     /* Stop any pending attaches */
-     qemu_del_timer(dev->attach_timer);
- 
-     if (dev->dev.attached) {
-         usb_device_detach(&dev->dev);
--        usbredir_cleanup_device_queues(dev);
-         /*
-          * Delay next usb device attach to give the guest a chance to see
-          * see the detach / attach in case of quick close / open succession
-          */
-         dev->next_attach_time = qemu_get_clock_ms(vm_clock) + 200;
-     }
-+
-+    /* Reset state so that the next dev connected starts with a clean slate */
-+    usbredir_cleanup_device_queues(dev);
-+    memset(dev->endpoint, 0, sizeof(dev->endpoint));
-+    for (i = 0; i < MAX_ENDPOINTS; i++) {
-+        QTAILQ_INIT(&dev->endpoint[i].bufpq);
-+    }
- }
- 
- static void usbredir_interface_info(void *priv,
-@@ -1037,6 +1049,10 @@ static void usbredir_iso_stream_status(void *priv, uint32_t id,
-     DPRINTF("iso status %d ep %02X id %u\n", iso_stream_status->status,
-             ep, id);
- 
-+    if (!dev->dev.attached) {
-+        return;
-+    }
-+
-     dev->endpoint[EP2I(ep)].iso_error = iso_stream_status->status;
-     if (iso_stream_status->status == usb_redir_stall) {
-         DPRINTF("iso stream stopped by peer ep %02X\n", ep);
-@@ -1054,6 +1070,10 @@ static void usbredir_interrupt_receiving_status(void *priv, uint32_t id,
-     DPRINTF("interrupt recv status %d ep %02X id %u\n",
-             interrupt_receiving_status->status, ep, id);
- 
-+    if (!dev->dev.attached) {
-+        return;
-+    }
-+
-     dev->endpoint[EP2I(ep)].interrupt_error =
-         interrupt_receiving_status->status;
-     if (interrupt_receiving_status->status == usb_redir_stall) {
--- 
-1.7.5.1
-
diff --git a/0028-usb-redir-Don-t-try-to-write-to-the-chardev-after-a-.patch b/0028-usb-redir-Don-t-try-to-write-to-the-chardev-after-a-.patch
deleted file mode 100644
index 18e5064..0000000
--- a/0028-usb-redir-Don-t-try-to-write-to-the-chardev-after-a-.patch
+++ /dev/null
@@ -1,32 +0,0 @@
->From 7e49ff036892fade86c7734118ee0c6da5cbad09 Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Thu, 11 Aug 2011 12:11:16 +0200
-Subject: [PATCH 28/28] usb-redir: Don't try to write to the chardev after a
- close event
-
-Sicne we handle close async in a bh, do_write and thus write can get
-called after receiving a close event. This patch adds a check to
-the usb-redir write callback to not do a qemu_chr_write on a closed
-chardev.
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- usb-redir.c |    2 +-
- 1 files changed, 1 insertions(+), 1 deletions(-)
-
-diff --git a/usb-redir.c b/usb-redir.c
-index 6d8f986..732ddab 100644
---- a/usb-redir.c
-+++ b/usb-redir.c
-@@ -226,7 +226,7 @@ static int usbredir_write(void *priv, uint8_t *data, int count)
-     USBRedirDevice *dev = priv;
-     int r;
- 
--    if (dev->cs->write_blocked) {
-+    if (!dev->cs->opened || dev->cs->write_blocked) {
-         return 0;
-     }
- 
--- 
-1.7.5.1
-
diff --git a/Fix_save-restore_of_in-kernel_i8259.patch b/Fix_save-restore_of_in-kernel_i8259.patch
new file mode 100644
index 0000000..15c772f
--- /dev/null
+++ b/Fix_save-restore_of_in-kernel_i8259.patch
@@ -0,0 +1,87 @@
+As the qemu-kvm version of the i8259 contains KVM bits, it still has to
+be compiled per target. This unbreaks migration of the i8259.
+
+Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
+---
+
+Not sure if anyone bothers (no one should actually use qemu-kvm for
+targets != x86), but let's avoid needless breakages of other targets
+requiring the i8259.
+
+ Makefile.objs   |    2 +-
+ Makefile.target |    8 ++++----
+ hw/i8259.c      |    2 --
+ 3 files changed, 5 insertions(+), 7 deletions(-)
+
+diff --git a/Makefile.objs b/Makefile.objs
+index 13afd19..77237e1 100644
+--- a/Makefile.objs
++++ b/Makefile.objs
+@@ -223,7 +223,7 @@ hw-obj-$(CONFIG_APPLESMC) += applesmc.o
+ hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o ccid-card-passthru.o
+ hw-obj-$(CONFIG_SMARTCARD_NSS) += ccid-card-emulated.o
+ hw-obj-$(CONFIG_USB_REDIR) += usb-redir.o
+-hw-obj-$(CONFIG_I8259) += i8259.o
++# hw-obj-$(CONFIG_I8259) += i8259.o
+ 
+ # PPC devices
+ hw-obj-$(CONFIG_PREP_PCI) += prep_pci.o
+diff --git a/Makefile.target b/Makefile.target
+index 0b610ad..29eaa68 100644
+--- a/Makefile.target
++++ b/Makefile.target
+@@ -236,7 +236,7 @@ obj-$(CONFIG_IVSHMEM) += ivshmem.o
+ 
+ # Hardware support
+ obj-i386-y += vga.o
+-obj-i386-y += mc146818rtc.o pc.o
++obj-i386-y += mc146818rtc.o pc.o i8259.o
+ obj-i386-y += cirrus_vga.o sga.o apic.o ioapic.o piix_pci.o
+ obj-i386-y += vmport.o
+ obj-i386-y += device-hotplug.o pci-hotplug.o smbios.o wdt_ib700.o
+@@ -255,7 +255,7 @@ obj-i386-$(CONFIG_KVM_DEVICE_ASSIGNMENT) += device-assignment.o
+ obj-ppc-y = ppc.o ppc_booke.o
+ obj-ppc-y += vga.o
+ # PREP target
+-obj-ppc-y += mc146818rtc.o
++obj-ppc-y += mc146818rtc.o i8259.o
+ obj-ppc-y += ppc_prep.o
+ # OldWorld PowerMac
+ obj-ppc-y += ppc_oldworld.o
+@@ -311,7 +311,7 @@ obj-mips-y += acpi.o acpi_piix4.o
+ obj-mips-y += mips_addr.o mips_timer.o mips_int.o
+ obj-mips-y += vga.o
+ obj-mips-y += jazz_led.o
+-obj-mips-y += gt64xxx.o mc146818rtc.o
++obj-mips-y += gt64xxx.o mc146818rtc.o i8259.o
+ obj-mips-y += cirrus_vga.o
+ obj-mips-$(CONFIG_FULONG) += bonito.o vt82c686.o mips_fulong2e.o
+ 
+@@ -392,7 +392,7 @@ obj-m68k-y += m68k-semi.o dummy_m68k.o
+ 
+ obj-s390x-y = s390-virtio-bus.o s390-virtio.o
+ 
+-obj-alpha-y = mc146818rtc.o
++obj-alpha-y = mc146818rtc.o i8259.o
+ obj-alpha-y += vga.o cirrus_vga.o
+ obj-alpha-y += alpha_pci.o alpha_dp264.o alpha_typhoon.o
+ 
+diff --git a/hw/i8259.c b/hw/i8259.c
+index fa63e83..a9ea9c9 100644
+--- a/hw/i8259.c
++++ b/hw/i8259.c
+@@ -697,8 +697,6 @@ static int kvm_kernel_pic_load_from_user(PicState *s)
+     return 0;
+ }
+ 
+-extern void apic_set_irq_delivered(void);
+-
+ static void kvm_i8259_set_irq(void *opaque, int irq, int level)
+ {
+     int pic_ret;
+-- 
+1.7.3.4
+--
+To unsubscribe from this list: send the line "unsubscribe kvm" in
+the body of a message to majordomo@vger.kernel.org
+More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff --git a/sources b/sources
index fcf95cc..c8f2676 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-8800a7d6b3aa4a168ea7f78dc66c0320  qemu-kvm-0.15.1.tar.gz
+00a825db46a70ba8ef9fc95da9cc7c1e  qemu-kvm-1.0.tar.gz
diff --git a/virtio-blk_refuse_SG_IO_requests_with_scsi_off.patch b/virtio-blk_refuse_SG_IO_requests_with_scsi_off.patch
new file mode 100644
index 0000000..277e740
--- /dev/null
+++ b/virtio-blk_refuse_SG_IO_requests_with_scsi_off.patch
@@ -0,0 +1,111 @@
+From qemu-stable-bounces+jmforbes=linuxtx.org@nongnu.org  Wed Jan 11 03:51:20 2012
+Return-Path: <qemu-stable-bounces+jmforbes=linuxtx.org@nongnu.org>
+Received: from citysiren.linuxtx.org (localhost [127.0.0.1])
+	by citysiren.linuxtx.org (8.14.4/8.14.4) with ESMTP id q0B9pIjw017454
+	for <jmfmail@localhost>; Wed, 11 Jan 2012 03:51:20 -0600
+Delivered-To: jmforbes@linuxtx.org
+Received: from gmail-pop.l.google.com [74.125.81.108]
+	by citysiren.linuxtx.org with POP3 (fetchmail-6.3.20)
+	for <jmfmail@localhost> (single-drop); Wed, 11 Jan 2012 03:51:20 -0600 (CST)
+Received: by 10.180.102.100 with SMTP id fn4cs34060wib;
+        Wed, 11 Jan 2012 01:48:56 -0800 (PST)
+Received: by 10.224.182.2 with SMTP id ca2mr28967033qab.57.1326275334564;
+        Wed, 11 Jan 2012 01:48:54 -0800 (PST)
+Received: from lists.gnu.org (lists.gnu.org. [140.186.70.17])
+        by mx.google.com with ESMTPS id gc3si782557qab.44.2012.01.11.01.48.54
+        (version=TLSv1/SSLv3 cipher=OTHER);
+        Wed, 11 Jan 2012 01:48:54 -0800 (PST)
+Received-SPF: pass (google.com: domain of qemu-stable-bounces+jmforbes=linuxtx.org@nongnu.org designates 140.186.70.17 as permitted sender) client-ip=140.186.70.17;
+Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-stable-bounces+jmforbes=linuxtx.org@nongnu.org designates 140.186.70.17 as permitted sender) smtp.mail=qemu-stable-bounces+jmforbes=linuxtx.org@nongnu.org
+Received: from localhost ([::1]:48473 helo=lists.gnu.org)
+	by lists.gnu.org with esmtp (Exim 4.71)
+	(envelope-from <qemu-stable-bounces+jmforbes=linuxtx.org@nongnu.org>)
+	id 1Rkund-0003iT-UQ
+	for jmforbes@linuxtx.org; Wed, 11 Jan 2012 04:48:53 -0500
+Received: from eggs.gnu.org ([140.186.70.92]:40037)
+	by lists.gnu.org with esmtp (Exim 4.71)
+	(envelope-from <pbonzini@redhat.com>) id 1RkunV-0003fY-Vl
+	for qemu-stable@nongnu.org; Wed, 11 Jan 2012 04:48:53 -0500
+Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71)
+	(envelope-from <pbonzini@redhat.com>) id 1RkunQ-0004zL-Nl
+	for qemu-stable@nongnu.org; Wed, 11 Jan 2012 04:48:45 -0500
+Received: from mx1.redhat.com ([209.132.183.28]:23781)
+	by eggs.gnu.org with esmtp (Exim 4.71)
+	(envelope-from <pbonzini@redhat.com>) id 1RkunQ-0004vY-3c
+	for qemu-stable@nongnu.org; Wed, 11 Jan 2012 04:48:40 -0500
+Received: from int-mx11.intmail.prod.int.phx2.redhat.com
+	(int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24])
+	by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q0B9mcYI005348
+	(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK)
+	for <qemu-stable@nongnu.org>; Wed, 11 Jan 2012 04:48:38 -0500
+Received: from yakj.usersys.redhat.com (ovpn-112-23.ams2.redhat.com
+	[10.36.112.23])
+	by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP
+	id q0B9magG031084
+	for <qemu-stable@nongnu.org>; Wed, 11 Jan 2012 04:48:37 -0500
+From: Paolo Bonzini <pbonzini@redhat.com>
+To: qemu-stable@nongnu.org
+Date: Wed, 11 Jan 2012 10:48:33 +0100
+Message-Id: <1326275313-15635-1-git-send-email-pbonzini@redhat.com>
+X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24
+X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3)
+X-Received-From: 209.132.183.28
+Subject: [Qemu-stable] [PATCH] virtio-blk: refuse SG_IO requests with
+	scsi=off
+X-BeenThere: qemu-stable@nongnu.org
+X-Mailman-Version: 2.1.14
+Precedence: list
+List-Id: <qemu-stable.nongnu.org>
+List-Unsubscribe: <https://lists.nongnu.org/mailman/options/qemu-stable>,
+	<mailto:qemu-stable-request@nongnu.org?subject=unsubscribe>
+List-Archive: <http://lists.nongnu.org/archive/html/qemu-stable>
+List-Post: <mailto:qemu-stable@nongnu.org>
+List-Help: <mailto:qemu-stable-request@nongnu.org?subject=help>
+List-Subscribe: <https://lists.nongnu.org/mailman/listinfo/qemu-stable>,
+	<mailto:qemu-stable-request@nongnu.org?subject=subscribe>
+Errors-To: qemu-stable-bounces+jmforbes=linuxtx.org@nongnu.org
+Sender: qemu-stable-bounces+jmforbes=linuxtx.org@nongnu.org
+X-UID: 32                                                 
+Status: RO
+Content-Length: 1003
+Lines: 38
+
+QEMU does have a "scsi" option (to be used like -device
+virtio-blk-pci,drive=foo,scsi=off).  However, it only
+masks the feature bit, and does not reject the command
+if a malicious guest disregards the feature bits and
+issues a request.
+
+Without this patch, using scsi=off does not protect you
+from CVE-2011-4127.
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+---
+ hw/virtio-blk.c |    6 ++++++
+ 1 files changed, 6 insertions(+), 0 deletions(-)
+
+diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
+index b70d116..6cd3164 100644
+--- a/hw/virtio-blk.c
++++ b/hw/virtio-blk.c
+@@ -153,6 +153,12 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
+     int status;
+     int i;
+ 
++    if ((req->dev->vdev.guest_features & (1 << VIRTIO_BLK_F_SCSI)) == 0) {
++        virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP);
++        g_free(req);
++        return;
++    }
++
+     /*
+      * We require at least one output segment each for the virtio_blk_outhdr
+      * and the SCSI command block.
+-- 
+1.7.7.1
+
+
+
+
+
+