diff --git a/.gitignore b/.gitignore
index a119815..8938ae8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,3 +24,4 @@ qemu-kvm-0.13.0-25fdf4a.tar.gz
 /qemu-1.5.2.tar.bz2
 /qemu-1.6.0.tar.bz2
 /qemu-1.6.1.tar.bz2
+/qemu-1.7.0-rc1.tar.bz2
diff --git a/0001-Fix-migration-from-qemu-kvm.patch b/0001-Fix-migration-from-qemu-kvm.patch
deleted file mode 100644
index a263329..0000000
--- a/0001-Fix-migration-from-qemu-kvm.patch
+++ /dev/null
@@ -1,212 +0,0 @@
-From 2196426a9b081cb99f4bdefb854aaa206bdd0392 Mon Sep 17 00:00:00 2001
-From: Cole Robinson <crobinso@redhat.com>
-Date: Fri, 16 Aug 2013 12:14:51 -0400
-Subject: [PATCH] Fix migration from qemu-kvm
-
-Details are in the code comments for each change. Just lumped this together
-to ease patch maintenance.
-
-Everything except the video memory bits can likely be dropped by Fedora 21
-time frame. Need to figure out if there's anything to upstream for the
-video memory bits.
----
- hw/acpi/piix4.c         |  8 ++++++-
- hw/display/qxl.c        |  9 ++++----
- hw/i386/pc_piix.c       | 61 +++++++++++++++++++++++++++++++++++++++++++++----
- hw/timer/i8254_common.c |  7 +++++-
- 4 files changed, 74 insertions(+), 11 deletions(-)
-
-diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
-index 3aaf18c..6fbe57c 100644
---- a/hw/acpi/piix4.c
-+++ b/hw/acpi/piix4.c
-@@ -289,7 +289,13 @@ static int acpi_load_old(QEMUFile *f, void *opaque, int version_id)
- static const VMStateDescription vmstate_acpi = {
-     .name = "piix4_pm",
-     .version_id = 3,
--    .minimum_version_id = 3,
-+    /*
-+     * qemu-kvm 1.2 uses qemu.git version 3 format, but advertised as 2.
-+     * This allows incoming migration from qemu-kvm, but breaks incoming
-+     * migration from qemu < 1.3.
-+     */
-+    //minimum_version_id = 3,
-+    .minimum_version_id = 2,
-     .minimum_version_id_old = 1,
-     .load_state_old = acpi_load_old,
-     .post_load = vmstate_acpi_post_load,
-diff --git a/hw/display/qxl.c b/hw/display/qxl.c
-index c537057..7ef3eff 100644
---- a/hw/display/qxl.c
-+++ b/hw/display/qxl.c
-@@ -307,16 +307,14 @@ static inline uint32_t msb_mask(uint32_t val)
-     return mask;
- }
- 
--static ram_addr_t qxl_rom_size(void)
-+static void check_qxl_rom_size(PCIQXLDevice *d)
- {
-     uint32_t required_rom_size = sizeof(QXLRom) + sizeof(QXLModes) +
-                                  sizeof(qxl_modes);
--    uint32_t rom_size = 8192; /* two pages */
- 
-     required_rom_size = MAX(required_rom_size, TARGET_PAGE_SIZE);
-     required_rom_size = msb_mask(required_rom_size * 2 - 1);
--    assert(required_rom_size <= rom_size);
--    return rom_size;
-+    assert(required_rom_size <= d->rom_size);
- }
- 
- static void init_qxl_rom(PCIQXLDevice *d)
-@@ -1981,7 +1979,7 @@ static int qxl_init_common(PCIQXLDevice *qxl)
-     pci_set_byte(&config[PCI_REVISION_ID], pci_device_rev);
-     pci_set_byte(&config[PCI_INTERRUPT_PIN], 1);
- 
--    qxl->rom_size = qxl_rom_size();
-+    check_qxl_rom_size(qxl);
-     memory_region_init_ram(&qxl->rom_bar, OBJECT(qxl), "qxl.vrom",
-                            qxl->rom_size);
-     vmstate_register_ram(&qxl->rom_bar, &qxl->pci.qdev);
-@@ -2309,6 +2307,7 @@ static Property qxl_properties[] = {
-         DEFINE_PROP_UINT32("vram64_size_mb", PCIQXLDevice, vram_size_mb, -1),
-         DEFINE_PROP_UINT32("vgamem_mb", PCIQXLDevice, vgamem_size_mb, 16),
-         DEFINE_PROP_INT32("surfaces", PCIQXLDevice, ssd.num_surfaces, 1024),
-+        DEFINE_PROP_UINT32("rom_size", PCIQXLDevice, rom_size, 8192),
-         DEFINE_PROP_END_OF_LIST(),
- };
- 
-diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
-index 3df2ff9..28216ee 100644
---- a/hw/i386/pc_piix.c
-+++ b/hw/i386/pc_piix.c
-@@ -377,6 +377,24 @@ static QEMUMachine pc_i440fx_machine_v1_4 = {
-     DEFAULT_MACHINE_OPTIONS,
- };
- 
-+/*
-+ * Commit 038c1879a00153b14bce113315b693e8c2944fa9 changed the qxl rom
-+ * size to 8192, which fixes incoming migration from qemu 1.0. However
-+ * from qemu 1.2 and 1.3 had rom size 16384, so incoming migration
-+ * from those versions is now broken.
-+ *
-+ * Add a rom_size compat property. 1.2 and 1.3 get 16384, everything
-+ * else is 8192.
-+ *
-+ * This isn't actually fool proof, since rom_size can be dependent on
-+ * the version of spice qemu is built against:
-+ *
-+ * https://lists.gnu.org/archive/html/qemu-devel/2013-02/msg03154.html
-+ *
-+ * However these sizes match what native Fedora packages get, so it's
-+ * good enough for now.
-+ */
-+
- #define PC_COMPAT_1_3 \
- 	PC_COMPAT_1_4, \
-         {\
-@@ -395,8 +413,17 @@ static QEMUMachine pc_i440fx_machine_v1_4 = {
-             .driver   = "e1000",\
-             .property = "autonegotiation",\
-             .value    = "off",\
-+        },{ \
-+            .driver   = "qxl", \
-+            .property = "rom_size", \
-+            .value    = stringify(16384), \
-+        },{\
-+            .driver   = "qxl-vga", \
-+            .property = "rom_size", \
-+            .value    = stringify(16384), \
-         }
- 
-+
- static QEMUMachine pc_machine_v1_3 = {
-     .name = "pc-1.3",
-     .desc = "Standard PC",
-@@ -409,6 +436,19 @@ static QEMUMachine pc_machine_v1_3 = {
-     DEFAULT_MACHINE_OPTIONS,
- };
- 
-+
-+/*
-+ * https://lists.gnu.org/archive/html/qemu-devel/2013-01/msg02540.html
-+ *
-+ * qemu-kvm defaulted to vgamem=16MB since at least 0.15, while qemu used
-+ * 8MB. For qemu 1.2, the default was changed to 16MB for all devices
-+ * except cirrus.
-+ *
-+ * Make sure cirrus uses 16MB for <= pc-1.2 (the qemu-kvm merge),
-+ * and 16MB always for all others. This will break incoming qemu
-+ * migration for qemu < 1.3.
-+ */
-+
- #define PC_COMPAT_1_2 \
-         PC_COMPAT_1_3,\
-         {\
-@@ -432,6 +472,10 @@ static QEMUMachine pc_machine_v1_3 = {
-             .property = "revision",\
-             .value    = stringify(3),\
-         },{\
-+            .driver   = "cirrus-vga",\
-+            .property = "vgamem_mb",\
-+            .value    = stringify(16),\
-+        },{\
-             .driver   = "VGA",\
-             .property = "mmio",\
-             .value    = "off",\
-@@ -462,25 +506,34 @@ static QEMUMachine pc_machine_v1_2 = {
-         },{\
-             .driver   = "VGA",\
-             .property = "vgamem_mb",\
--            .value    = stringify(8),\
-+            .value    = stringify(16),\
-         },{\
-             .driver   = "vmware-svga",\
-             .property = "vgamem_mb",\
--            .value    = stringify(8),\
-+            .value    = stringify(16),\
-         },{\
-             .driver   = "qxl-vga",\
-             .property = "vgamem_mb",\
--            .value    = stringify(8),\
-+            .value    = stringify(16),\
-         },{\
-             .driver   = "qxl",\
-             .property = "vgamem_mb",\
--            .value    = stringify(8),\
-+            .value    = stringify(16),\
-         },{\
-             .driver   = "virtio-blk-pci",\
-             .property = "config-wce",\
-             .value    = "off",\
-+        },{ \
-+            .driver   = "qxl", \
-+            .property = "rom_size", \
-+            .value    = stringify(8192), \
-+        },{\
-+            .driver   = "qxl-vga", \
-+            .property = "rom_size", \
-+            .value    = stringify(8192), \
-         }
- 
-+
- static QEMUMachine pc_machine_v1_1 = {
-     .name = "pc-1.1",
-     .desc = "Standard PC",
-diff --git a/hw/timer/i8254_common.c b/hw/timer/i8254_common.c
-index 4e5bf0b..cbc00a0 100644
---- a/hw/timer/i8254_common.c
-+++ b/hw/timer/i8254_common.c
-@@ -267,7 +267,12 @@ static const VMStateDescription vmstate_pit_common = {
-     .pre_save = pit_dispatch_pre_save,
-     .post_load = pit_dispatch_post_load,
-     .fields = (VMStateField[]) {
--        VMSTATE_UINT32_V(channels[0].irq_disabled, PITCommonState, 3),
-+        /* qemu-kvm version_id=2 had 'flags' here which is equivalent
-+         * This fixes incoming migration from qemu-kvm 1.0, but breaks
-+         * incoming migration from qemu < 1.1
-+         */
-+        //VMSTATE_UINT32_V(channels[0].irq_disabled, PITCommonState, 3),
-+        VMSTATE_UINT32(channels[0].irq_disabled, PITCommonState),
-         VMSTATE_STRUCT_ARRAY(channels, PITCommonState, 3, 2,
-                              vmstate_pit_channel, PITChannelState),
-         VMSTATE_INT64(channels[0].next_transition_time,
diff --git a/0001-pci-do-not-export-pci_bus_reset.patch b/0001-pci-do-not-export-pci_bus_reset.patch
new file mode 100644
index 0000000..dc5ffbf
--- /dev/null
+++ b/0001-pci-do-not-export-pci_bus_reset.patch
@@ -0,0 +1,72 @@
+From 68c3010699db0e83c7bb2ac469527d6a7a36dfa4 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Thu, 2 May 2013 11:38:37 +0200
+Subject: [PATCH] pci: do not export pci_bus_reset
+
+qbus_reset_all can be used instead.  There is no semantic change
+because pcibus_reset returns 1 and takes care of the device
+tree traversal.
+
+This will be necessary once the traversal is done always in
+qbus_reset_all *before* invoking pcibus_reset itself.
+
+Tested-by: Claudio Bley <cbley@av-test.de>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+---
+ hw/pci/pci.c         | 8 ++------
+ hw/pci/pci_bridge.c  | 2 +-
+ include/hw/pci/pci.h | 1 -
+ 3 files changed, 3 insertions(+), 8 deletions(-)
+
+diff --git a/hw/pci/pci.c b/hw/pci/pci.c
+index ed32059..ab73b4c 100644
+--- a/hw/pci/pci.c
++++ b/hw/pci/pci.c
+@@ -210,8 +210,9 @@ void pci_device_reset(PCIDevice *dev)
+  * Trigger pci bus reset under a given bus.
+  * To be called on RST# assert.
+  */
+-void pci_bus_reset(PCIBus *bus)
++static int pcibus_reset(BusState *qbus)
+ {
++    PCIBus *bus = DO_UPCAST(PCIBus, qbus, qbus);
+     int i;
+ 
+     for (i = 0; i < bus->nirq; i++) {
+@@ -222,11 +223,6 @@ void pci_bus_reset(PCIBus *bus)
+             pci_device_reset(bus->devices[i]);
+         }
+     }
+-}
+-
+-static int pcibus_reset(BusState *qbus)
+-{
+-    pci_bus_reset(DO_UPCAST(PCIBus, qbus, qbus));
+ 
+     /* topology traverse is done by pci_bus_reset().
+        Tell qbus/qdev walker not to traverse the tree */
+diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c
+index 290abab..41d8755 100644
+--- a/hw/pci/pci_bridge.c
++++ b/hw/pci/pci_bridge.c
+@@ -268,7 +268,7 @@ void pci_bridge_write_config(PCIDevice *d,
+     newctl = pci_get_word(d->config + PCI_BRIDGE_CONTROL);
+     if (~oldctl & newctl & PCI_BRIDGE_CTL_BUS_RESET) {
+         /* Trigger hot reset on 0->1 transition. */
+-        pci_bus_reset(&s->sec_bus);
++        qbus_reset_all(&s->sec_bus.qbus);
+     }
+ }
+ 
+diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
+index b783e68..754b82d 100644
+--- a/include/hw/pci/pci.h
++++ b/include/hw/pci/pci.h
+@@ -373,7 +373,6 @@ void pci_bus_fire_intx_routing_notifier(PCIBus *bus);
+ void pci_device_set_intx_routing_notifier(PCIDevice *dev,
+                                           PCIINTxRoutingNotifier notifier);
+ void pci_device_reset(PCIDevice *dev);
+-void pci_bus_reset(PCIBus *bus);
+ 
+ PCIDevice *pci_nic_init(NICInfo *nd, PCIBus *rootbus,
+                         const char *default_model,
diff --git a/0002-isapc-disable-kvmvapic.patch b/0002-isapc-disable-kvmvapic.patch
deleted file mode 100644
index 4adf992..0000000
--- a/0002-isapc-disable-kvmvapic.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 85a924af30f31a4f701ee6f18d84dd27aa02f47b Mon Sep 17 00:00:00 2001
-From: Paolo Bonzini <pbonzini@redhat.com>
-Date: Tue, 13 Aug 2013 00:02:18 +0200
-Subject: [PATCH] isapc: disable kvmvapic
-
-vapic requires the VAPIC ROM to be mapped into RAM.  This is not
-possible without PAM hardware.  This fixes a segmentation fault
-running with -M isapc.
-
-Cc: qemu-stable@nongnu.org
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-
-(crobinso: s/kvmvapic/vapic/g)
-
-Signed-off-by: Cole Robinson <crobinso@redhat.com>
----
- hw/i386/pc_piix.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
-diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
-index 28216ee..2f2cb4d 100644
---- a/hw/i386/pc_piix.c
-+++ b/hw/i386/pc_piix.c
-@@ -795,7 +795,11 @@ static QEMUMachine isapc_machine = {
-     .init = pc_init_isa,
-     .max_cpus = 1,
-     .compat_props = (GlobalProperty[]) {
--        { /* end of list */ }
-+        {
-+            .driver   = "apic-common",
-+            .property = "vapic",
-+            .value    = "off",
-+        },
-     },
-     DEFAULT_MACHINE_OPTIONS,
- };
diff --git a/0002-qdev-allow-both-pre-and-post-order-vists-in-qdev-wal.patch b/0002-qdev-allow-both-pre-and-post-order-vists-in-qdev-wal.patch
new file mode 100644
index 0000000..eeeb7f8
--- /dev/null
+++ b/0002-qdev-allow-both-pre-and-post-order-vists-in-qdev-wal.patch
@@ -0,0 +1,141 @@
+From ea25537789eb25313d6b4baee7c00d36b1dcdf17 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Thu, 2 May 2013 11:38:38 +0200
+Subject: [PATCH] qdev: allow both pre- and post-order vists in qdev walking
+ functions
+
+Resetting should be done in post-order, not pre-order.  However,
+qdev_walk_children and qbus_walk_children do not allow this.  Fix
+it by adding two extra arguments to the functions.
+
+Tested-by: Claudio Bley <cbley@av-test.de>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+---
+ hw/core/qdev.c         | 45 +++++++++++++++++++++++++++++++++------------
+ include/hw/qdev-core.h | 13 +++++++++----
+ 2 files changed, 42 insertions(+), 16 deletions(-)
+
+diff --git a/hw/core/qdev.c b/hw/core/qdev.c
+index e374a93..5ddf1aa 100644
+--- a/hw/core/qdev.c
++++ b/hw/core/qdev.c
+@@ -240,12 +240,12 @@ static int qbus_reset_one(BusState *bus, void *opaque)
+ 
+ void qdev_reset_all(DeviceState *dev)
+ {
+-    qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
++    qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL, NULL, NULL);
+ }
+ 
+ void qbus_reset_all(BusState *bus)
+ {
+-    qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
++    qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL, NULL, NULL);
+ }
+ 
+ void qbus_reset_all_fn(void *opaque)
+@@ -337,49 +337,70 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
+     return NULL;
+ }
+ 
+-int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
+-                       qbus_walkerfn *busfn, void *opaque)
++int qbus_walk_children(BusState *bus,
++                       qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
++                       qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
++                       void *opaque)
+ {
+     BusChild *kid;
+     int err;
+ 
+-    if (busfn) {
+-        err = busfn(bus, opaque);
++    if (pre_busfn) {
++        err = pre_busfn(bus, opaque);
+         if (err) {
+             return err;
+         }
+     }
+ 
+     QTAILQ_FOREACH(kid, &bus->children, sibling) {
+-        err = qdev_walk_children(kid->child, devfn, busfn, opaque);
++        err = qdev_walk_children(kid->child,
++                                 pre_devfn, pre_busfn,
++                                 post_devfn, post_busfn, opaque);
+         if (err < 0) {
+             return err;
+         }
+     }
+ 
++    if (post_busfn) {
++        err = post_busfn(bus, opaque);
++        if (err) {
++            return err;
++        }
++    }
++
+     return 0;
+ }
+ 
+-int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
+-                       qbus_walkerfn *busfn, void *opaque)
++int qdev_walk_children(DeviceState *dev,
++                       qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
++                       qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
++                       void *opaque)
+ {
+     BusState *bus;
+     int err;
+ 
+-    if (devfn) {
+-        err = devfn(dev, opaque);
++    if (pre_devfn) {
++        err = pre_devfn(dev, opaque);
+         if (err) {
+             return err;
+         }
+     }
+ 
+     QLIST_FOREACH(bus, &dev->child_bus, sibling) {
+-        err = qbus_walk_children(bus, devfn, busfn, opaque);
++        err = qbus_walk_children(bus, pre_devfn, pre_busfn,
++                                 post_devfn, post_busfn, opaque);
+         if (err < 0) {
+             return err;
+         }
+     }
+ 
++    if (post_devfn) {
++        err = post_devfn(dev, opaque);
++        if (err) {
++            return err;
++        }
++    }
++
+     return 0;
+ }
+ 
+diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
+index f2043a6..ecf5cb3 100644
+--- a/include/hw/qdev-core.h
++++ b/include/hw/qdev-core.h
+@@ -253,10 +253,15 @@ BusState *qbus_create(const char *typename, DeviceState *parent, const char *nam
+ /* Returns > 0 if either devfn or busfn skip walk somewhere in cursion,
+  *         < 0 if either devfn or busfn terminate walk somewhere in cursion,
+  *           0 otherwise. */
+-int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
+-                       qbus_walkerfn *busfn, void *opaque);
+-int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
+-                       qbus_walkerfn *busfn, void *opaque);
++int qbus_walk_children(BusState *bus,
++                       qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
++                       qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
++                       void *opaque);
++int qdev_walk_children(DeviceState *dev,
++                       qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
++                       qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
++                       void *opaque);
++
+ void qdev_reset_all(DeviceState *dev);
+ 
+ /**
diff --git a/0003-pci-do-not-export-pci_bus_reset.patch b/0003-pci-do-not-export-pci_bus_reset.patch
deleted file mode 100644
index 21c6cef..0000000
--- a/0003-pci-do-not-export-pci_bus_reset.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From 07873f45017c04994496d8dc3f7acb60358bba49 Mon Sep 17 00:00:00 2001
-From: Paolo Bonzini <pbonzini@redhat.com>
-Date: Thu, 2 May 2013 11:38:37 +0200
-Subject: [PATCH] pci: do not export pci_bus_reset
-
-qbus_reset_all can be used instead.  There is no semantic change
-because pcibus_reset returns 1 and takes care of the device
-tree traversal.
-
-This will be necessary once the traversal is done always in
-qbus_reset_all *before* invoking pcibus_reset itself.
-
-Tested-by: Claudio Bley <cbley@av-test.de>
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
----
- hw/pci/pci.c         | 8 ++------
- hw/pci/pci_bridge.c  | 2 +-
- include/hw/pci/pci.h | 1 -
- 3 files changed, 3 insertions(+), 8 deletions(-)
-
-diff --git a/hw/pci/pci.c b/hw/pci/pci.c
-index 4c004f5..0389375 100644
---- a/hw/pci/pci.c
-+++ b/hw/pci/pci.c
-@@ -210,8 +210,9 @@ void pci_device_reset(PCIDevice *dev)
-  * Trigger pci bus reset under a given bus.
-  * To be called on RST# assert.
-  */
--void pci_bus_reset(PCIBus *bus)
-+static int pcibus_reset(BusState *qbus)
- {
-+    PCIBus *bus = DO_UPCAST(PCIBus, qbus, qbus);
-     int i;
- 
-     for (i = 0; i < bus->nirq; i++) {
-@@ -222,11 +223,6 @@ void pci_bus_reset(PCIBus *bus)
-             pci_device_reset(bus->devices[i]);
-         }
-     }
--}
--
--static int pcibus_reset(BusState *qbus)
--{
--    pci_bus_reset(DO_UPCAST(PCIBus, qbus, qbus));
- 
-     /* topology traverse is done by pci_bus_reset().
-        Tell qbus/qdev walker not to traverse the tree */
-diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c
-index a90671d..5d0e5ff 100644
---- a/hw/pci/pci_bridge.c
-+++ b/hw/pci/pci_bridge.c
-@@ -268,7 +268,7 @@ void pci_bridge_write_config(PCIDevice *d,
-     newctl = pci_get_word(d->config + PCI_BRIDGE_CONTROL);
-     if (~oldctl & newctl & PCI_BRIDGE_CTL_BUS_RESET) {
-         /* Trigger hot reset on 0->1 transition. */
--        pci_bus_reset(&s->sec_bus);
-+        qbus_reset_all(&s->sec_bus.qbus);
-     }
- }
- 
-diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
-index ccec2ba..32f1419 100644
---- a/include/hw/pci/pci.h
-+++ b/include/hw/pci/pci.h
-@@ -376,7 +376,6 @@ void pci_bus_fire_intx_routing_notifier(PCIBus *bus);
- void pci_device_set_intx_routing_notifier(PCIDevice *dev,
-                                           PCIINTxRoutingNotifier notifier);
- void pci_device_reset(PCIDevice *dev);
--void pci_bus_reset(PCIBus *bus);
- 
- PCIDevice *pci_nic_init(NICInfo *nd, PCIBus *rootbus,
-                         const char *default_model,
diff --git a/0003-qdev-switch-reset-to-post-order.patch b/0003-qdev-switch-reset-to-post-order.patch
new file mode 100644
index 0000000..d4dd4c9
--- /dev/null
+++ b/0003-qdev-switch-reset-to-post-order.patch
@@ -0,0 +1,143 @@
+From 6e6d80327eb2e249daaa0937468248d54222b125 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Thu, 2 May 2013 11:38:39 +0200
+Subject: [PATCH] qdev: switch reset to post-order
+
+Post-order is the only sensible direction for the reset signals.
+For example, suppose pre-order is used and the parent has some data
+structures that cache children state (for example a list of active
+requests).  When the reset method is invoked on the parent, these caches
+could be in any state.
+
+If post-order is used, on the other hand, these will be in a known state
+when the reset method is invoked on the parent.
+
+This change means that it is no longer possible to block the visit of
+the devices, so the callback is changed to return void.  This is not
+a problem, because PCI was returning 1 exactly in order to achieve the
+same ordering that this patch implements.
+
+PCI can then rely on the qdev core having sent a "reset signal"
+(whatever that means) to the device, and only do the PCI-specific
+initialization with the new function pci_do_device_reset, extracted
+from pci_device_reset.  There is no change in the operation of FLR,
+which used and still uses pci_device_reset.
+
+Tested-by: Claudio Bley <cbley@av-test.de>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+---
+ hw/core/qdev.c         |  6 +++---
+ hw/pci/pci.c           | 31 ++++++++++++++++---------------
+ include/hw/qdev-core.h |  2 +-
+ 3 files changed, 20 insertions(+), 19 deletions(-)
+
+diff --git a/hw/core/qdev.c b/hw/core/qdev.c
+index 5ddf1aa..d2ffe35 100644
+--- a/hw/core/qdev.c
++++ b/hw/core/qdev.c
+@@ -233,19 +233,19 @@ static int qbus_reset_one(BusState *bus, void *opaque)
+ {
+     BusClass *bc = BUS_GET_CLASS(bus);
+     if (bc->reset) {
+-        return bc->reset(bus);
++        bc->reset(bus);
+     }
+     return 0;
+ }
+ 
+ void qdev_reset_all(DeviceState *dev)
+ {
+-    qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL, NULL, NULL);
++    qdev_walk_children(dev, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
+ }
+ 
+ void qbus_reset_all(BusState *bus)
+ {
+-    qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL, NULL, NULL);
++    qbus_walk_children(bus, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
+ }
+ 
+ void qbus_reset_all_fn(void *opaque)
+diff --git a/hw/pci/pci.c b/hw/pci/pci.c
+index ab73b4c..b52df14 100644
+--- a/hw/pci/pci.c
++++ b/hw/pci/pci.c
+@@ -46,7 +46,7 @@
+ static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent);
+ static char *pcibus_get_dev_path(DeviceState *dev);
+ static char *pcibus_get_fw_dev_path(DeviceState *dev);
+-static int pcibus_reset(BusState *qbus);
++static void pcibus_reset(BusState *qbus);
+ 
+ static Property pci_props[] = {
+     DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
+@@ -165,16 +165,10 @@ void pci_device_deassert_intx(PCIDevice *dev)
+     }
+ }
+ 
+-/*
+- * This function is called on #RST and FLR.
+- * FLR if PCI_EXP_DEVCTL_BCR_FLR is set
+- */
+-void pci_device_reset(PCIDevice *dev)
++static void pci_do_device_reset(PCIDevice *dev)
+ {
+     int r;
+ 
+-    qdev_reset_all(&dev->qdev);
+-
+     dev->irq_state = 0;
+     pci_update_irq_status(dev);
+     pci_device_deassert_intx(dev);
+@@ -207,10 +201,21 @@ void pci_device_reset(PCIDevice *dev)
+ }
+ 
+ /*
++ * This function is called on #RST and FLR.
++ * FLR if PCI_EXP_DEVCTL_BCR_FLR is set
++ */
++void pci_device_reset(PCIDevice *dev)
++{
++    qdev_reset_all(&dev->qdev);
++    pci_do_device_reset(dev);
++}
++
++/*
+  * Trigger pci bus reset under a given bus.
+- * To be called on RST# assert.
++ * Called via qbus_reset_all on RST# assert, after the devices
++ * have been reset qdev_reset_all-ed already.
+  */
+-static int pcibus_reset(BusState *qbus)
++static void pcibus_reset(BusState *qbus)
+ {
+     PCIBus *bus = DO_UPCAST(PCIBus, qbus, qbus);
+     int i;
+@@ -220,13 +225,9 @@ static int pcibus_reset(BusState *qbus)
+     }
+     for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) {
+         if (bus->devices[i]) {
+-            pci_device_reset(bus->devices[i]);
++            pci_do_device_reset(bus->devices[i]);
+         }
+     }
+-
+-    /* topology traverse is done by pci_bus_reset().
+-       Tell qbus/qdev walker not to traverse the tree */
+-    return 1;
+ }
+ 
+ static void pci_host_bus_register(PCIBus *bus, DeviceState *parent)
+diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
+index ecf5cb3..a9ce4a3 100644
+--- a/include/hw/qdev-core.h
++++ b/include/hw/qdev-core.h
+@@ -158,7 +158,7 @@ struct BusClass {
+      * bindings can be found at http://playground.sun.com/1275/bindings/.
+      */
+     char *(*get_fw_dev_path)(DeviceState *dev);
+-    int (*reset)(BusState *bus);
++    void (*reset)(BusState *bus);
+     /* maximum devices allowed on the bus, 0: no limit. */
+     int max_dev;
+ };
diff --git a/0004-qdev-allow-both-pre-and-post-order-vists-in-qdev-wal.patch b/0004-qdev-allow-both-pre-and-post-order-vists-in-qdev-wal.patch
deleted file mode 100644
index 8580f62..0000000
--- a/0004-qdev-allow-both-pre-and-post-order-vists-in-qdev-wal.patch
+++ /dev/null
@@ -1,141 +0,0 @@
-From cf09bc533d82f2b16d1e9f4888c1afd977ca256d Mon Sep 17 00:00:00 2001
-From: Paolo Bonzini <pbonzini@redhat.com>
-Date: Thu, 2 May 2013 11:38:38 +0200
-Subject: [PATCH] qdev: allow both pre- and post-order vists in qdev walking
- functions
-
-Resetting should be done in post-order, not pre-order.  However,
-qdev_walk_children and qbus_walk_children do not allow this.  Fix
-it by adding two extra arguments to the functions.
-
-Tested-by: Claudio Bley <cbley@av-test.de>
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
----
- hw/core/qdev.c         | 45 +++++++++++++++++++++++++++++++++------------
- include/hw/qdev-core.h | 13 +++++++++----
- 2 files changed, 42 insertions(+), 16 deletions(-)
-
-diff --git a/hw/core/qdev.c b/hw/core/qdev.c
-index 9190a7e..842804f 100644
---- a/hw/core/qdev.c
-+++ b/hw/core/qdev.c
-@@ -240,12 +240,12 @@ static int qbus_reset_one(BusState *bus, void *opaque)
- 
- void qdev_reset_all(DeviceState *dev)
- {
--    qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
-+    qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL, NULL, NULL);
- }
- 
- void qbus_reset_all(BusState *bus)
- {
--    qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
-+    qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL, NULL, NULL);
- }
- 
- void qbus_reset_all_fn(void *opaque)
-@@ -343,49 +343,70 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
-     return NULL;
- }
- 
--int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
--                       qbus_walkerfn *busfn, void *opaque)
-+int qbus_walk_children(BusState *bus,
-+                       qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
-+                       qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
-+                       void *opaque)
- {
-     BusChild *kid;
-     int err;
- 
--    if (busfn) {
--        err = busfn(bus, opaque);
-+    if (pre_busfn) {
-+        err = pre_busfn(bus, opaque);
-         if (err) {
-             return err;
-         }
-     }
- 
-     QTAILQ_FOREACH(kid, &bus->children, sibling) {
--        err = qdev_walk_children(kid->child, devfn, busfn, opaque);
-+        err = qdev_walk_children(kid->child,
-+                                 pre_devfn, pre_busfn,
-+                                 post_devfn, post_busfn, opaque);
-         if (err < 0) {
-             return err;
-         }
-     }
- 
-+    if (post_busfn) {
-+        err = post_busfn(bus, opaque);
-+        if (err) {
-+            return err;
-+        }
-+    }
-+
-     return 0;
- }
- 
--int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
--                       qbus_walkerfn *busfn, void *opaque)
-+int qdev_walk_children(DeviceState *dev,
-+                       qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
-+                       qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
-+                       void *opaque)
- {
-     BusState *bus;
-     int err;
- 
--    if (devfn) {
--        err = devfn(dev, opaque);
-+    if (pre_devfn) {
-+        err = pre_devfn(dev, opaque);
-         if (err) {
-             return err;
-         }
-     }
- 
-     QLIST_FOREACH(bus, &dev->child_bus, sibling) {
--        err = qbus_walk_children(bus, devfn, busfn, opaque);
-+        err = qbus_walk_children(bus, pre_devfn, pre_busfn,
-+                                 post_devfn, post_busfn, opaque);
-         if (err < 0) {
-             return err;
-         }
-     }
- 
-+    if (post_devfn) {
-+        err = post_devfn(dev, opaque);
-+        if (err) {
-+            return err;
-+        }
-+    }
-+
-     return 0;
- }
- 
-diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
-index 46972f4..c6c9b14 100644
---- a/include/hw/qdev-core.h
-+++ b/include/hw/qdev-core.h
-@@ -270,10 +270,15 @@ BusState *qbus_create(const char *typename, DeviceState *parent, const char *nam
- /* Returns > 0 if either devfn or busfn skip walk somewhere in cursion,
-  *         < 0 if either devfn or busfn terminate walk somewhere in cursion,
-  *           0 otherwise. */
--int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
--                       qbus_walkerfn *busfn, void *opaque);
--int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
--                       qbus_walkerfn *busfn, void *opaque);
-+int qbus_walk_children(BusState *bus,
-+                       qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
-+                       qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
-+                       void *opaque);
-+int qdev_walk_children(DeviceState *dev,
-+                       qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
-+                       qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
-+                       void *opaque);
-+
- void qdev_reset_all(DeviceState *dev);
- 
- /**
diff --git a/0004-virtio-bus-remove-vdev-field.patch b/0004-virtio-bus-remove-vdev-field.patch
new file mode 100644
index 0000000..e058832
--- /dev/null
+++ b/0004-virtio-bus-remove-vdev-field.patch
@@ -0,0 +1,248 @@
+From 21cbcaf09677ba959d977bfc0712c5e08ca1aec9 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Fri, 20 Sep 2013 16:57:50 +0200
+Subject: [PATCH] virtio-bus: remove vdev field
+
+The vdev field is complicated to synchronize.  Just access the
+BusState's list of children.
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+---
+ hw/virtio/virtio-bus.c         | 65 +++++++++++++++++++++++++-----------------
+ hw/virtio/virtio-mmio.c        |  9 +++---
+ hw/virtio/virtio-pci.c         |  2 +-
+ include/hw/virtio/virtio-bus.h | 16 ++++++++---
+ 4 files changed, 57 insertions(+), 35 deletions(-)
+
+diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c
+index e6b103c..17dd06e 100644
+--- a/hw/virtio/virtio-bus.c
++++ b/hw/virtio/virtio-bus.c
+@@ -46,8 +46,6 @@ int virtio_bus_plug_device(VirtIODevice *vdev)
+     VirtioBusClass *klass = VIRTIO_BUS_GET_CLASS(bus);
+     DPRINTF("%s: plug device.\n", qbus->name);
+ 
+-    bus->vdev = vdev;
+-
+     if (klass->device_plugged != NULL) {
+         klass->device_plugged(qbus->parent);
+     }
+@@ -58,9 +56,11 @@ int virtio_bus_plug_device(VirtIODevice *vdev)
+ /* Reset the virtio_bus */
+ void virtio_bus_reset(VirtioBusState *bus)
+ {
++    VirtIODevice *vdev = virtio_bus_get_device(bus);
++
+     DPRINTF("%s: reset device.\n", qbus->name);
+-    if (bus->vdev != NULL) {
+-        virtio_reset(bus->vdev);
++    if (vdev != NULL) {
++        virtio_reset(vdev);
+     }
+ }
+ 
+@@ -69,62 +69,71 @@ void virtio_bus_destroy_device(VirtioBusState *bus)
+ {
+     BusState *qbus = BUS(bus);
+     VirtioBusClass *klass = VIRTIO_BUS_GET_CLASS(bus);
++    VirtIODevice *vdev = virtio_bus_get_device(bus);
++
+     DPRINTF("%s: remove device.\n", qbus->name);
+ 
+-    if (bus->vdev != NULL) {
++    if (vdev != NULL) {
+         if (klass->device_unplug != NULL) {
+             klass->device_unplug(qbus->parent);
+         }
+-        object_unparent(OBJECT(bus->vdev));
+-        bus->vdev = NULL;
++        object_unparent(OBJECT(vdev));
+     }
+ }
+ 
+ /* Get the device id of the plugged device. */
+ uint16_t virtio_bus_get_vdev_id(VirtioBusState *bus)
+ {
+-    assert(bus->vdev != NULL);
+-    return bus->vdev->device_id;
++    VirtIODevice *vdev = virtio_bus_get_device(bus);
++    assert(vdev != NULL);
++    return vdev->device_id;
+ }
+ 
+ /* Get the config_len field of the plugged device. */
+ size_t virtio_bus_get_vdev_config_len(VirtioBusState *bus)
+ {
+-    assert(bus->vdev != NULL);
+-    return bus->vdev->config_len;
++    VirtIODevice *vdev = virtio_bus_get_device(bus);
++    assert(vdev != NULL);
++    return vdev->config_len;
+ }
+ 
+ /* Get the features of the plugged device. */
+ uint32_t virtio_bus_get_vdev_features(VirtioBusState *bus,
+                                     uint32_t requested_features)
+ {
++    VirtIODevice *vdev = virtio_bus_get_device(bus);
+     VirtioDeviceClass *k;
+-    assert(bus->vdev != NULL);
+-    k = VIRTIO_DEVICE_GET_CLASS(bus->vdev);
++
++    assert(vdev != NULL);
++    k = VIRTIO_DEVICE_GET_CLASS(vdev);
+     assert(k->get_features != NULL);
+-    return k->get_features(bus->vdev, requested_features);
++    return k->get_features(vdev, requested_features);
+ }
+ 
+ /* Set the features of the plugged device. */
+ void virtio_bus_set_vdev_features(VirtioBusState *bus,
+                                       uint32_t requested_features)
+ {
++    VirtIODevice *vdev = virtio_bus_get_device(bus);
+     VirtioDeviceClass *k;
+-    assert(bus->vdev != NULL);
+-    k = VIRTIO_DEVICE_GET_CLASS(bus->vdev);
++
++    assert(vdev != NULL);
++    k = VIRTIO_DEVICE_GET_CLASS(vdev);
+     if (k->set_features != NULL) {
+-        k->set_features(bus->vdev, requested_features);
++        k->set_features(vdev, requested_features);
+     }
+ }
+ 
+ /* Get bad features of the plugged device. */
+ uint32_t virtio_bus_get_vdev_bad_features(VirtioBusState *bus)
+ {
++    VirtIODevice *vdev = virtio_bus_get_device(bus);
+     VirtioDeviceClass *k;
+-    assert(bus->vdev != NULL);
+-    k = VIRTIO_DEVICE_GET_CLASS(bus->vdev);
++
++    assert(vdev != NULL);
++    k = VIRTIO_DEVICE_GET_CLASS(vdev);
+     if (k->bad_features != NULL) {
+-        return k->bad_features(bus->vdev);
++        return k->bad_features(vdev);
+     } else {
+         return 0;
+     }
+@@ -133,22 +142,26 @@ uint32_t virtio_bus_get_vdev_bad_features(VirtioBusState *bus)
+ /* Get config of the plugged device. */
+ void virtio_bus_get_vdev_config(VirtioBusState *bus, uint8_t *config)
+ {
++    VirtIODevice *vdev = virtio_bus_get_device(bus);
+     VirtioDeviceClass *k;
+-    assert(bus->vdev != NULL);
+-    k = VIRTIO_DEVICE_GET_CLASS(bus->vdev);
++
++    assert(vdev != NULL);
++    k = VIRTIO_DEVICE_GET_CLASS(vdev);
+     if (k->get_config != NULL) {
+-        k->get_config(bus->vdev, config);
++        k->get_config(vdev, config);
+     }
+ }
+ 
+ /* Set config of the plugged device. */
+ void virtio_bus_set_vdev_config(VirtioBusState *bus, uint8_t *config)
+ {
++    VirtIODevice *vdev = virtio_bus_get_device(bus);
+     VirtioDeviceClass *k;
+-    assert(bus->vdev != NULL);
+-    k = VIRTIO_DEVICE_GET_CLASS(bus->vdev);
++
++    assert(vdev != NULL);
++    k = VIRTIO_DEVICE_GET_CLASS(vdev);
+     if (k->set_config != NULL) {
+-        k->set_config(bus->vdev, config);
++        k->set_config(vdev, config);
+     }
+ }
+ 
+diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
+index 29cf284..8829eb0 100644
+--- a/hw/virtio/virtio-mmio.c
++++ b/hw/virtio/virtio-mmio.c
+@@ -95,7 +95,7 @@ static void virtio_mmio_bus_new(VirtioBusState *bus, size_t bus_size,
+ static uint64_t virtio_mmio_read(void *opaque, hwaddr offset, unsigned size)
+ {
+     VirtIOMMIOProxy *proxy = (VirtIOMMIOProxy *)opaque;
+-    VirtIODevice *vdev = proxy->bus.vdev;
++    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+ 
+     DPRINTF("virtio_mmio_read offset 0x%x\n", (int)offset);
+ 
+@@ -185,7 +185,7 @@ static void virtio_mmio_write(void *opaque, hwaddr offset, uint64_t value,
+                               unsigned size)
+ {
+     VirtIOMMIOProxy *proxy = (VirtIOMMIOProxy *)opaque;
+-    VirtIODevice *vdev = proxy->bus.vdev;
++    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+ 
+     DPRINTF("virtio_mmio_write offset 0x%x value 0x%" PRIx64 "\n",
+             (int)offset, value);
+@@ -298,12 +298,13 @@ static const MemoryRegionOps virtio_mem_ops = {
+ static void virtio_mmio_update_irq(DeviceState *opaque, uint16_t vector)
+ {
+     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque);
++    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+     int level;
+ 
+-    if (!proxy->bus.vdev) {
++    if (!vdev) {
+         return;
+     }
+-    level = (proxy->bus.vdev->isr != 0);
++    level = (vdev->isr != 0);
+     DPRINTF("virtio_mmio setting IRQ %d\n", level);
+     qemu_set_irq(proxy->irq, level);
+ }
+diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
+index 7647be8..76b7652 100644
+--- a/hw/virtio/virtio-pci.c
++++ b/hw/virtio/virtio-pci.c
+@@ -943,7 +943,7 @@ static void virtio_pci_device_plugged(DeviceState *d)
+     uint8_t *config;
+     uint32_t size;
+ 
+-    proxy->vdev = bus->vdev;
++    proxy->vdev = virtio_bus_get_device(bus);
+ 
+     config = proxy->pci_dev.config;
+     if (proxy->class_code) {
+diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h
+index 9217f85..ba0f86a 100644
+--- a/include/hw/virtio/virtio-bus.h
++++ b/include/hw/virtio/virtio-bus.h
+@@ -72,10 +72,6 @@ typedef struct VirtioBusClass {
+ 
+ struct VirtioBusState {
+     BusState parent_obj;
+-    /*
+-     * Only one VirtIODevice can be plugged on the bus.
+-     */
+-    VirtIODevice *vdev;
+ };
+ 
+ int virtio_bus_plug_device(VirtIODevice *vdev);
+@@ -98,4 +94,16 @@ void virtio_bus_get_vdev_config(VirtioBusState *bus, uint8_t *config);
+ /* Set config of the plugged device. */
+ void virtio_bus_set_vdev_config(VirtioBusState *bus, uint8_t *config);
+ 
++static inline VirtIODevice *virtio_bus_get_device(VirtioBusState *bus)
++{
++    BusState *qbus = &bus->parent_obj;
++    BusChild *kid = QTAILQ_FIRST(&qbus->children);
++    DeviceState *qdev = kid ? kid->child : NULL;
++
++    /* This is used on the data path, the cast is guaranteed
++     * to succeed by the qdev machinery.
++     */
++    return (VirtIODevice *)qdev;
++}
++
+ #endif /* VIRTIO_BUS_H */
diff --git a/0005-qdev-switch-reset-to-post-order.patch b/0005-qdev-switch-reset-to-post-order.patch
deleted file mode 100644
index 2f533e5..0000000
--- a/0005-qdev-switch-reset-to-post-order.patch
+++ /dev/null
@@ -1,143 +0,0 @@
-From 41a2077cea8ce006dbef885bcb0778af05a0b159 Mon Sep 17 00:00:00 2001
-From: Paolo Bonzini <pbonzini@redhat.com>
-Date: Thu, 2 May 2013 11:38:39 +0200
-Subject: [PATCH] qdev: switch reset to post-order
-
-Post-order is the only sensible direction for the reset signals.
-For example, suppose pre-order is used and the parent has some data
-structures that cache children state (for example a list of active
-requests).  When the reset method is invoked on the parent, these caches
-could be in any state.
-
-If post-order is used, on the other hand, these will be in a known state
-when the reset method is invoked on the parent.
-
-This change means that it is no longer possible to block the visit of
-the devices, so the callback is changed to return void.  This is not
-a problem, because PCI was returning 1 exactly in order to achieve the
-same ordering that this patch implements.
-
-PCI can then rely on the qdev core having sent a "reset signal"
-(whatever that means) to the device, and only do the PCI-specific
-initialization with the new function pci_do_device_reset, extracted
-from pci_device_reset.  There is no change in the operation of FLR,
-which used and still uses pci_device_reset.
-
-Tested-by: Claudio Bley <cbley@av-test.de>
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
----
- hw/core/qdev.c         |  6 +++---
- hw/pci/pci.c           | 31 ++++++++++++++++---------------
- include/hw/qdev-core.h |  2 +-
- 3 files changed, 20 insertions(+), 19 deletions(-)
-
-diff --git a/hw/core/qdev.c b/hw/core/qdev.c
-index 842804f..87d7e1e 100644
---- a/hw/core/qdev.c
-+++ b/hw/core/qdev.c
-@@ -233,19 +233,19 @@ static int qbus_reset_one(BusState *bus, void *opaque)
- {
-     BusClass *bc = BUS_GET_CLASS(bus);
-     if (bc->reset) {
--        return bc->reset(bus);
-+        bc->reset(bus);
-     }
-     return 0;
- }
- 
- void qdev_reset_all(DeviceState *dev)
- {
--    qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL, NULL, NULL);
-+    qdev_walk_children(dev, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
- }
- 
- void qbus_reset_all(BusState *bus)
- {
--    qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL, NULL, NULL);
-+    qbus_walk_children(bus, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
- }
- 
- void qbus_reset_all_fn(void *opaque)
-diff --git a/hw/pci/pci.c b/hw/pci/pci.c
-index 0389375..bbca696 100644
---- a/hw/pci/pci.c
-+++ b/hw/pci/pci.c
-@@ -46,7 +46,7 @@
- static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent);
- static char *pcibus_get_dev_path(DeviceState *dev);
- static char *pcibus_get_fw_dev_path(DeviceState *dev);
--static int pcibus_reset(BusState *qbus);
-+static void pcibus_reset(BusState *qbus);
- 
- static Property pci_props[] = {
-     DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
-@@ -165,16 +165,10 @@ void pci_device_deassert_intx(PCIDevice *dev)
-     }
- }
- 
--/*
-- * This function is called on #RST and FLR.
-- * FLR if PCI_EXP_DEVCTL_BCR_FLR is set
-- */
--void pci_device_reset(PCIDevice *dev)
-+static void pci_do_device_reset(PCIDevice *dev)
- {
-     int r;
- 
--    qdev_reset_all(&dev->qdev);
--
-     dev->irq_state = 0;
-     pci_update_irq_status(dev);
-     pci_device_deassert_intx(dev);
-@@ -207,10 +201,21 @@ void pci_device_reset(PCIDevice *dev)
- }
- 
- /*
-+ * This function is called on #RST and FLR.
-+ * FLR if PCI_EXP_DEVCTL_BCR_FLR is set
-+ */
-+void pci_device_reset(PCIDevice *dev)
-+{
-+    qdev_reset_all(&dev->qdev);
-+    pci_do_device_reset(dev);
-+}
-+
-+/*
-  * Trigger pci bus reset under a given bus.
-- * To be called on RST# assert.
-+ * Called via qbus_reset_all on RST# assert, after the devices
-+ * have been reset qdev_reset_all-ed already.
-  */
--static int pcibus_reset(BusState *qbus)
-+static void pcibus_reset(BusState *qbus)
- {
-     PCIBus *bus = DO_UPCAST(PCIBus, qbus, qbus);
-     int i;
-@@ -220,13 +225,9 @@ static int pcibus_reset(BusState *qbus)
-     }
-     for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) {
-         if (bus->devices[i]) {
--            pci_device_reset(bus->devices[i]);
-+            pci_do_device_reset(bus->devices[i]);
-         }
-     }
--
--    /* topology traverse is done by pci_bus_reset().
--       Tell qbus/qdev walker not to traverse the tree */
--    return 1;
- }
- 
- static void pci_host_bus_register(PCIBus *bus, DeviceState *parent)
-diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
-index c6c9b14..89dcbad 100644
---- a/include/hw/qdev-core.h
-+++ b/include/hw/qdev-core.h
-@@ -174,7 +174,7 @@ struct BusClass {
-      * bindings can be found at http://playground.sun.com/1275/bindings/.
-      */
-     char *(*get_fw_dev_path)(DeviceState *dev);
--    int (*reset)(BusState *bus);
-+    void (*reset)(BusState *bus);
-     /* maximum devices allowed on the bus, 0: no limit. */
-     int max_dev;
- };
diff --git a/0005-virtio-pci-remove-vdev-field.patch b/0005-virtio-pci-remove-vdev-field.patch
new file mode 100644
index 0000000..2a4dabb
--- /dev/null
+++ b/0005-virtio-pci-remove-vdev-field.patch
@@ -0,0 +1,447 @@
+From cc7e97d969c93e197bda7ed17d32254e31793b2d Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Fri, 20 Sep 2013 16:57:51 +0200
+Subject: [PATCH] virtio-pci: remove vdev field
+
+The vdev field is complicated to synchronize.  Just access the
+BusState's list of children.
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+---
+ hw/s390x/virtio-ccw.h  |   1 -
+ hw/virtio/virtio-pci.c | 107 +++++++++++++++++++++++++++++--------------------
+ hw/virtio/virtio-pci.h |   1 -
+ 3 files changed, 63 insertions(+), 46 deletions(-)
+
+diff --git a/hw/s390x/virtio-ccw.h b/hw/s390x/virtio-ccw.h
+index 96d6f5d..00932c7 100644
+--- a/hw/s390x/virtio-ccw.h
++++ b/hw/s390x/virtio-ccw.h
+@@ -77,7 +77,6 @@ typedef struct VirtIOCCWDeviceClass {
+ struct VirtioCcwDevice {
+     DeviceState parent_obj;
+     SubchDev *sch;
+-    VirtIODevice *vdev;
+     char *bus_id;
+     uint32_t host_features[VIRTIO_CCW_FEATURE_SIZE];
+     VirtioBusState bus;
+diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
+index 76b7652..be18e92 100644
+--- a/hw/virtio/virtio-pci.c
++++ b/hw/virtio/virtio-pci.c
+@@ -113,31 +113,39 @@ static inline VirtIOPCIProxy *to_virtio_pci_proxy_fast(DeviceState *d)
+ static void virtio_pci_notify(DeviceState *d, uint16_t vector)
+ {
+     VirtIOPCIProxy *proxy = to_virtio_pci_proxy_fast(d);
++    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
++
+     if (msix_enabled(&proxy->pci_dev))
+         msix_notify(&proxy->pci_dev, vector);
+     else
+-        pci_set_irq(&proxy->pci_dev, proxy->vdev->isr & 1);
++        pci_set_irq(&proxy->pci_dev, vdev->isr & 1);
+ }
+ 
+ static void virtio_pci_save_config(DeviceState *d, QEMUFile *f)
+ {
+     VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
++    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
++
+     pci_device_save(&proxy->pci_dev, f);
+     msix_save(&proxy->pci_dev, f);
+     if (msix_present(&proxy->pci_dev))
+-        qemu_put_be16(f, proxy->vdev->config_vector);
++        qemu_put_be16(f, vdev->config_vector);
+ }
+ 
+ static void virtio_pci_save_queue(DeviceState *d, int n, QEMUFile *f)
+ {
+     VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
++    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
++
+     if (msix_present(&proxy->pci_dev))
+-        qemu_put_be16(f, virtio_queue_vector(proxy->vdev, n));
++        qemu_put_be16(f, virtio_queue_vector(vdev, n));
+ }
+ 
+ static int virtio_pci_load_config(DeviceState *d, QEMUFile *f)
+ {
+     VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
++    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
++
+     int ret;
+     ret = pci_device_load(&proxy->pci_dev, f);
+     if (ret) {
+@@ -146,12 +154,12 @@ static int virtio_pci_load_config(DeviceState *d, QEMUFile *f)
+     msix_unuse_all_vectors(&proxy->pci_dev);
+     msix_load(&proxy->pci_dev, f);
+     if (msix_present(&proxy->pci_dev)) {
+-        qemu_get_be16s(f, &proxy->vdev->config_vector);
++        qemu_get_be16s(f, &vdev->config_vector);
+     } else {
+-        proxy->vdev->config_vector = VIRTIO_NO_VECTOR;
++        vdev->config_vector = VIRTIO_NO_VECTOR;
+     }
+-    if (proxy->vdev->config_vector != VIRTIO_NO_VECTOR) {
+-        return msix_vector_use(&proxy->pci_dev, proxy->vdev->config_vector);
++    if (vdev->config_vector != VIRTIO_NO_VECTOR) {
++        return msix_vector_use(&proxy->pci_dev, vdev->config_vector);
+     }
+     return 0;
+ }
+@@ -159,13 +167,15 @@ static int virtio_pci_load_config(DeviceState *d, QEMUFile *f)
+ static int virtio_pci_load_queue(DeviceState *d, int n, QEMUFile *f)
+ {
+     VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
++    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
++
+     uint16_t vector;
+     if (msix_present(&proxy->pci_dev)) {
+         qemu_get_be16s(f, &vector);
+     } else {
+         vector = VIRTIO_NO_VECTOR;
+     }
+-    virtio_queue_set_vector(proxy->vdev, n, vector);
++    virtio_queue_set_vector(vdev, n, vector);
+     if (vector != VIRTIO_NO_VECTOR) {
+         return msix_vector_use(&proxy->pci_dev, vector);
+     }
+@@ -175,7 +185,8 @@ static int virtio_pci_load_queue(DeviceState *d, int n, QEMUFile *f)
+ static int virtio_pci_set_host_notifier_internal(VirtIOPCIProxy *proxy,
+                                                  int n, bool assign, bool set_handler)
+ {
+-    VirtQueue *vq = virtio_get_queue(proxy->vdev, n);
++    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
++    VirtQueue *vq = virtio_get_queue(vdev, n);
+     EventNotifier *notifier = virtio_queue_get_host_notifier(vq);
+     int r = 0;
+ 
+@@ -200,6 +211,7 @@ static int virtio_pci_set_host_notifier_internal(VirtIOPCIProxy *proxy,
+ 
+ static void virtio_pci_start_ioeventfd(VirtIOPCIProxy *proxy)
+ {
++    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+     int n, r;
+ 
+     if (!(proxy->flags & VIRTIO_PCI_FLAG_USE_IOEVENTFD) ||
+@@ -209,7 +221,7 @@ static void virtio_pci_start_ioeventfd(VirtIOPCIProxy *proxy)
+     }
+ 
+     for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
+-        if (!virtio_queue_get_num(proxy->vdev, n)) {
++        if (!virtio_queue_get_num(vdev, n)) {
+             continue;
+         }
+ 
+@@ -223,7 +235,7 @@ static void virtio_pci_start_ioeventfd(VirtIOPCIProxy *proxy)
+ 
+ assign_error:
+     while (--n >= 0) {
+-        if (!virtio_queue_get_num(proxy->vdev, n)) {
++        if (!virtio_queue_get_num(vdev, n)) {
+             continue;
+         }
+ 
+@@ -236,6 +248,7 @@ assign_error:
+ 
+ static void virtio_pci_stop_ioeventfd(VirtIOPCIProxy *proxy)
+ {
++    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+     int r;
+     int n;
+ 
+@@ -244,7 +257,7 @@ static void virtio_pci_stop_ioeventfd(VirtIOPCIProxy *proxy)
+     }
+ 
+     for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
+-        if (!virtio_queue_get_num(proxy->vdev, n)) {
++        if (!virtio_queue_get_num(vdev, n)) {
+             continue;
+         }
+ 
+@@ -257,7 +270,7 @@ static void virtio_pci_stop_ioeventfd(VirtIOPCIProxy *proxy)
+ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+ {
+     VirtIOPCIProxy *proxy = opaque;
+-    VirtIODevice *vdev = proxy->vdev;
++    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+     hwaddr pa;
+ 
+     switch (addr) {
+@@ -272,7 +285,7 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+         pa = (hwaddr)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT;
+         if (pa == 0) {
+             virtio_pci_stop_ioeventfd(proxy);
+-            virtio_reset(proxy->vdev);
++            virtio_reset(vdev);
+             msix_unuse_all_vectors(&proxy->pci_dev);
+         }
+         else
+@@ -299,7 +312,7 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+         }
+ 
+         if (vdev->status == 0) {
+-            virtio_reset(proxy->vdev);
++            virtio_reset(vdev);
+             msix_unuse_all_vectors(&proxy->pci_dev);
+         }
+ 
+@@ -335,7 +348,7 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+ 
+ static uint32_t virtio_ioport_read(VirtIOPCIProxy *proxy, uint32_t addr)
+ {
+-    VirtIODevice *vdev = proxy->vdev;
++    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+     uint32_t ret = 0xFFFFFFFF;
+ 
+     switch (addr) {
+@@ -381,6 +394,7 @@ static uint64_t virtio_pci_config_read(void *opaque, hwaddr addr,
+                                        unsigned size)
+ {
+     VirtIOPCIProxy *proxy = opaque;
++    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+     uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
+     uint64_t val = 0;
+     if (addr < config) {
+@@ -390,16 +404,16 @@ static uint64_t virtio_pci_config_read(void *opaque, hwaddr addr,
+ 
+     switch (size) {
+     case 1:
+-        val = virtio_config_readb(proxy->vdev, addr);
++        val = virtio_config_readb(vdev, addr);
+         break;
+     case 2:
+-        val = virtio_config_readw(proxy->vdev, addr);
++        val = virtio_config_readw(vdev, addr);
+         if (virtio_is_big_endian()) {
+             val = bswap16(val);
+         }
+         break;
+     case 4:
+-        val = virtio_config_readl(proxy->vdev, addr);
++        val = virtio_config_readl(vdev, addr);
+         if (virtio_is_big_endian()) {
+             val = bswap32(val);
+         }
+@@ -413,6 +427,7 @@ static void virtio_pci_config_write(void *opaque, hwaddr addr,
+ {
+     VirtIOPCIProxy *proxy = opaque;
+     uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
++    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+     if (addr < config) {
+         virtio_ioport_write(proxy, addr, val);
+         return;
+@@ -424,19 +439,19 @@ static void virtio_pci_config_write(void *opaque, hwaddr addr,
+      */
+     switch (size) {
+     case 1:
+-        virtio_config_writeb(proxy->vdev, addr, val);
++        virtio_config_writeb(vdev, addr, val);
+         break;
+     case 2:
+         if (virtio_is_big_endian()) {
+             val = bswap16(val);
+         }
+-        virtio_config_writew(proxy->vdev, addr, val);
++        virtio_config_writew(vdev, addr, val);
+         break;
+     case 4:
+         if (virtio_is_big_endian()) {
+             val = bswap32(val);
+         }
+-        virtio_config_writel(proxy->vdev, addr, val);
++        virtio_config_writel(vdev, addr, val);
+         break;
+     }
+ }
+@@ -455,6 +470,7 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
+                                 uint32_t val, int len)
+ {
+     VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
++    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+ 
+     pci_default_write_config(pci_dev, address, val, len);
+ 
+@@ -462,8 +478,7 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
+         !(pci_dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER) &&
+         !(proxy->flags & VIRTIO_PCI_FLAG_BUS_MASTER_BUG)) {
+         virtio_pci_stop_ioeventfd(proxy);
+-        virtio_set_status(proxy->vdev,
+-                          proxy->vdev->status & ~VIRTIO_CONFIG_S_DRIVER_OK);
++        virtio_set_status(vdev, vdev->status & ~VIRTIO_CONFIG_S_DRIVER_OK);
+     }
+ }
+ 
+@@ -506,7 +521,8 @@ static int kvm_virtio_pci_irqfd_use(VirtIOPCIProxy *proxy,
+                                  unsigned int vector)
+ {
+     VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
+-    VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no);
++    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
++    VirtQueue *vq = virtio_get_queue(vdev, queue_no);
+     EventNotifier *n = virtio_queue_get_guest_notifier(vq);
+     int ret;
+     ret = kvm_irqchip_add_irqfd_notifier(kvm_state, n, NULL, irqfd->virq);
+@@ -517,7 +533,8 @@ static void kvm_virtio_pci_irqfd_release(VirtIOPCIProxy *proxy,
+                                       unsigned int queue_no,
+                                       unsigned int vector)
+ {
+-    VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no);
++    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
++    VirtQueue *vq = virtio_get_queue(vdev, queue_no);
+     EventNotifier *n = virtio_queue_get_guest_notifier(vq);
+     VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
+     int ret;
+@@ -529,7 +546,7 @@ static void kvm_virtio_pci_irqfd_release(VirtIOPCIProxy *proxy,
+ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
+ {
+     PCIDevice *dev = &proxy->pci_dev;
+-    VirtIODevice *vdev = proxy->vdev;
++    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+     VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
+     unsigned int vector;
+     int ret, queue_no;
+@@ -578,7 +595,7 @@ undo:
+ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
+ {
+     PCIDevice *dev = &proxy->pci_dev;
+-    VirtIODevice *vdev = proxy->vdev;
++    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+     unsigned int vector;
+     int queue_no;
+     VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
+@@ -606,8 +623,9 @@ static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy,
+                                        unsigned int vector,
+                                        MSIMessage msg)
+ {
+-    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(proxy->vdev);
+-    VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no);
++    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
++    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
++    VirtQueue *vq = virtio_get_queue(vdev, queue_no);
+     EventNotifier *n = virtio_queue_get_guest_notifier(vq);
+     VirtIOIRQFD *irqfd;
+     int ret = 0;
+@@ -626,10 +644,10 @@ static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy,
+      * Otherwise, set it up now.
+      */
+     if (k->guest_notifier_mask) {
+-        k->guest_notifier_mask(proxy->vdev, queue_no, false);
++        k->guest_notifier_mask(vdev, queue_no, false);
+         /* Test after unmasking to avoid losing events. */
+         if (k->guest_notifier_pending &&
+-            k->guest_notifier_pending(proxy->vdev, queue_no)) {
++            k->guest_notifier_pending(vdev, queue_no)) {
+             event_notifier_set(n);
+         }
+     } else {
+@@ -642,13 +660,14 @@ static void virtio_pci_vq_vector_mask(VirtIOPCIProxy *proxy,
+                                              unsigned int queue_no,
+                                              unsigned int vector)
+ {
+-    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(proxy->vdev);
++    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
++    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
+ 
+     /* If guest supports masking, keep irqfd but mask it.
+      * Otherwise, clean it up now.
+      */ 
+     if (k->guest_notifier_mask) {
+-        k->guest_notifier_mask(proxy->vdev, queue_no, true);
++        k->guest_notifier_mask(vdev, queue_no, true);
+     } else {
+         kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
+     }
+@@ -658,7 +677,7 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector,
+                                     MSIMessage msg)
+ {
+     VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
+-    VirtIODevice *vdev = proxy->vdev;
++    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+     int ret, queue_no;
+ 
+     for (queue_no = 0; queue_no < proxy->nvqs_with_notifiers; queue_no++) {
+@@ -688,7 +707,7 @@ undo:
+ static void virtio_pci_vector_mask(PCIDevice *dev, unsigned vector)
+ {
+     VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
+-    VirtIODevice *vdev = proxy->vdev;
++    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+     int queue_no;
+ 
+     for (queue_no = 0; queue_no < proxy->nvqs_with_notifiers; queue_no++) {
+@@ -707,7 +726,7 @@ static void virtio_pci_vector_poll(PCIDevice *dev,
+                                    unsigned int vector_end)
+ {
+     VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
+-    VirtIODevice *vdev = proxy->vdev;
++    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+     VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
+     int queue_no;
+     unsigned int vector;
+@@ -739,8 +758,9 @@ static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign,
+                                          bool with_irqfd)
+ {
+     VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
+-    VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(proxy->vdev);
+-    VirtQueue *vq = virtio_get_queue(proxy->vdev, n);
++    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
++    VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
++    VirtQueue *vq = virtio_get_queue(vdev, n);
+     EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
+ 
+     if (assign) {
+@@ -755,7 +775,7 @@ static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign,
+     }
+ 
+     if (!msix_enabled(&proxy->pci_dev) && vdc->guest_notifier_mask) {
+-        vdc->guest_notifier_mask(proxy->vdev, n, !assign);
++        vdc->guest_notifier_mask(vdev, n, !assign);
+     }
+ 
+     return 0;
+@@ -770,7 +790,7 @@ static bool virtio_pci_query_guest_notifiers(DeviceState *d)
+ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign)
+ {
+     VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
+-    VirtIODevice *vdev = proxy->vdev;
++    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+     VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
+     int r, n;
+     bool with_irqfd = msix_enabled(&proxy->pci_dev) &&
+@@ -864,11 +884,12 @@ static int virtio_pci_set_host_notifier(DeviceState *d, int n, bool assign)
+ static void virtio_pci_vmstate_change(DeviceState *d, bool running)
+ {
+     VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
++    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+ 
+     if (running) {
+         /* Try to find out if the guest has bus master disabled, but is
+            in ready state. Then we have a buggy guest OS. */
+-        if ((proxy->vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) &&
++        if ((vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) &&
+             !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
+             proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
+         }
+@@ -943,8 +964,6 @@ static void virtio_pci_device_plugged(DeviceState *d)
+     uint8_t *config;
+     uint32_t size;
+ 
+-    proxy->vdev = virtio_bus_get_device(bus);
+-
+     config = proxy->pci_dev.config;
+     if (proxy->class_code) {
+         pci_config_set_class(config, proxy->class_code);
+diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h
+index 917bcc5..dc332ae 100644
+--- a/hw/virtio/virtio-pci.h
++++ b/hw/virtio/virtio-pci.h
+@@ -82,7 +82,6 @@ typedef struct VirtioPCIClass {
+ 
+ struct VirtIOPCIProxy {
+     PCIDevice pci_dev;
+-    VirtIODevice *vdev;
+     MemoryRegion bar;
+     uint32_t flags;
+     uint32_t class_code;
diff --git a/0006-virtio-bus-remove-vdev-field.patch b/0006-virtio-bus-remove-vdev-field.patch
deleted file mode 100644
index 617326f..0000000
--- a/0006-virtio-bus-remove-vdev-field.patch
+++ /dev/null
@@ -1,251 +0,0 @@
-From ed35f9edcc420b4f8c1f909bc7cfb002a54f437b Mon Sep 17 00:00:00 2001
-From: Paolo Bonzini <pbonzini@redhat.com>
-Date: Fri, 20 Sep 2013 16:57:50 +0200
-Subject: [PATCH] virtio-bus: remove vdev field
-
-The vdev field is complicated to synchronize.  Just access the
-BusState's list of children.
-
-Cc: qemu-stable@nongnu.org
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
----
- hw/virtio/virtio-bus.c         | 67 ++++++++++++++++++++++++------------------
- hw/virtio/virtio-mmio.c        |  9 +++---
- hw/virtio/virtio-pci.c         |  2 +-
- include/hw/virtio/virtio-bus.h | 16 +++++++---
- 4 files changed, 57 insertions(+), 37 deletions(-)
-
-diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c
-index 6849a01..669ce38 100644
---- a/hw/virtio/virtio-bus.c
-+++ b/hw/virtio/virtio-bus.c
-@@ -46,8 +46,6 @@ int virtio_bus_plug_device(VirtIODevice *vdev)
-     VirtioBusClass *klass = VIRTIO_BUS_GET_CLASS(bus);
-     DPRINTF("%s: plug device.\n", qbus->name);
- 
--    bus->vdev = vdev;
--
-     if (klass->device_plugged != NULL) {
-         klass->device_plugged(qbus->parent);
-     }
-@@ -58,75 +56,84 @@ int virtio_bus_plug_device(VirtIODevice *vdev)
- /* Reset the virtio_bus */
- void virtio_bus_reset(VirtioBusState *bus)
- {
-+    VirtIODevice *vdev = virtio_bus_get_device(bus);
-+
-     DPRINTF("%s: reset device.\n", qbus->name);
--    if (bus->vdev != NULL) {
--        virtio_reset(bus->vdev);
-+    if (vdev != NULL) {
-+        virtio_reset(vdev);
-     }
- }
- 
- /* Destroy the VirtIODevice */
- void virtio_bus_destroy_device(VirtioBusState *bus)
- {
--    DeviceState *qdev;
-     BusState *qbus = BUS(bus);
-     VirtioBusClass *klass = VIRTIO_BUS_GET_CLASS(bus);
-+    VirtIODevice *vdev = virtio_bus_get_device(bus);
-+
-     DPRINTF("%s: remove device.\n", qbus->name);
- 
--    if (bus->vdev != NULL) {
-+    if (vdev != NULL) {
-         if (klass->device_unplug != NULL) {
-             klass->device_unplug(qbus->parent);
-         }
--        qdev = DEVICE(bus->vdev);
--        qdev_free(qdev);
--        bus->vdev = NULL;
-+        qdev_free(DEVICE(vdev));
-     }
- }
- 
- /* Get the device id of the plugged device. */
- uint16_t virtio_bus_get_vdev_id(VirtioBusState *bus)
- {
--    assert(bus->vdev != NULL);
--    return bus->vdev->device_id;
-+    VirtIODevice *vdev = virtio_bus_get_device(bus);
-+    assert(vdev != NULL);
-+    return vdev->device_id;
- }
- 
- /* Get the config_len field of the plugged device. */
- size_t virtio_bus_get_vdev_config_len(VirtioBusState *bus)
- {
--    assert(bus->vdev != NULL);
--    return bus->vdev->config_len;
-+    VirtIODevice *vdev = virtio_bus_get_device(bus);
-+    assert(vdev != NULL);
-+    return vdev->config_len;
- }
- 
- /* Get the features of the plugged device. */
- uint32_t virtio_bus_get_vdev_features(VirtioBusState *bus,
-                                     uint32_t requested_features)
- {
-+    VirtIODevice *vdev = virtio_bus_get_device(bus);
-     VirtioDeviceClass *k;
--    assert(bus->vdev != NULL);
--    k = VIRTIO_DEVICE_GET_CLASS(bus->vdev);
-+
-+    assert(vdev != NULL);
-+    k = VIRTIO_DEVICE_GET_CLASS(vdev);
-     assert(k->get_features != NULL);
--    return k->get_features(bus->vdev, requested_features);
-+    return k->get_features(vdev, requested_features);
- }
- 
- /* Set the features of the plugged device. */
- void virtio_bus_set_vdev_features(VirtioBusState *bus,
-                                       uint32_t requested_features)
- {
-+    VirtIODevice *vdev = virtio_bus_get_device(bus);
-     VirtioDeviceClass *k;
--    assert(bus->vdev != NULL);
--    k = VIRTIO_DEVICE_GET_CLASS(bus->vdev);
-+
-+    assert(vdev != NULL);
-+    k = VIRTIO_DEVICE_GET_CLASS(vdev);
-     if (k->set_features != NULL) {
--        k->set_features(bus->vdev, requested_features);
-+        k->set_features(vdev, requested_features);
-     }
- }
- 
- /* Get bad features of the plugged device. */
- uint32_t virtio_bus_get_vdev_bad_features(VirtioBusState *bus)
- {
-+    VirtIODevice *vdev = virtio_bus_get_device(bus);
-     VirtioDeviceClass *k;
--    assert(bus->vdev != NULL);
--    k = VIRTIO_DEVICE_GET_CLASS(bus->vdev);
-+
-+    assert(vdev != NULL);
-+    k = VIRTIO_DEVICE_GET_CLASS(vdev);
-     if (k->bad_features != NULL) {
--        return k->bad_features(bus->vdev);
-+        return k->bad_features(vdev);
-     } else {
-         return 0;
-     }
-@@ -135,22 +142,26 @@ uint32_t virtio_bus_get_vdev_bad_features(VirtioBusState *bus)
- /* Get config of the plugged device. */
- void virtio_bus_get_vdev_config(VirtioBusState *bus, uint8_t *config)
- {
-+    VirtIODevice *vdev = virtio_bus_get_device(bus);
-     VirtioDeviceClass *k;
--    assert(bus->vdev != NULL);
--    k = VIRTIO_DEVICE_GET_CLASS(bus->vdev);
-+
-+    assert(vdev != NULL);
-+    k = VIRTIO_DEVICE_GET_CLASS(vdev);
-     if (k->get_config != NULL) {
--        k->get_config(bus->vdev, config);
-+        k->get_config(vdev, config);
-     }
- }
- 
- /* Set config of the plugged device. */
- void virtio_bus_set_vdev_config(VirtioBusState *bus, uint8_t *config)
- {
-+    VirtIODevice *vdev = virtio_bus_get_device(bus);
-     VirtioDeviceClass *k;
--    assert(bus->vdev != NULL);
--    k = VIRTIO_DEVICE_GET_CLASS(bus->vdev);
-+
-+    assert(vdev != NULL);
-+    k = VIRTIO_DEVICE_GET_CLASS(vdev);
-     if (k->set_config != NULL) {
--        k->set_config(bus->vdev, config);
-+        k->set_config(vdev, config);
-     }
- }
- 
-diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
-index 4bd2953..8f7b764 100644
---- a/hw/virtio/virtio-mmio.c
-+++ b/hw/virtio/virtio-mmio.c
-@@ -94,7 +94,7 @@ static void virtio_mmio_bus_new(VirtioBusState *bus, VirtIOMMIOProxy *dev);
- static uint64_t virtio_mmio_read(void *opaque, hwaddr offset, unsigned size)
- {
-     VirtIOMMIOProxy *proxy = (VirtIOMMIOProxy *)opaque;
--    VirtIODevice *vdev = proxy->bus.vdev;
-+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
- 
-     DPRINTF("virtio_mmio_read offset 0x%x\n", (int)offset);
- 
-@@ -184,7 +184,7 @@ static void virtio_mmio_write(void *opaque, hwaddr offset, uint64_t value,
-                               unsigned size)
- {
-     VirtIOMMIOProxy *proxy = (VirtIOMMIOProxy *)opaque;
--    VirtIODevice *vdev = proxy->bus.vdev;
-+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
- 
-     DPRINTF("virtio_mmio_write offset 0x%x value 0x%" PRIx64 "\n",
-             (int)offset, value);
-@@ -297,12 +297,13 @@ static const MemoryRegionOps virtio_mem_ops = {
- static void virtio_mmio_update_irq(DeviceState *opaque, uint16_t vector)
- {
-     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque);
-+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
-     int level;
- 
--    if (!proxy->bus.vdev) {
-+    if (!vdev) {
-         return;
-     }
--    level = (proxy->bus.vdev->isr != 0);
-+    level = (vdev->isr != 0);
-     DPRINTF("virtio_mmio setting IRQ %d\n", level);
-     qemu_set_irq(proxy->irq, level);
- }
-diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
-index 41b96ce..55617a6 100644
---- a/hw/virtio/virtio-pci.c
-+++ b/hw/virtio/virtio-pci.c
-@@ -942,7 +942,7 @@ static void virtio_pci_device_plugged(DeviceState *d)
-     uint8_t *config;
-     uint32_t size;
- 
--    proxy->vdev = bus->vdev;
-+    proxy->vdev = virtio_bus_get_device(bus);
- 
-     config = proxy->pci_dev.config;
-     if (proxy->class_code) {
-diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h
-index 9217f85..ba0f86a 100644
---- a/include/hw/virtio/virtio-bus.h
-+++ b/include/hw/virtio/virtio-bus.h
-@@ -72,10 +72,6 @@ typedef struct VirtioBusClass {
- 
- struct VirtioBusState {
-     BusState parent_obj;
--    /*
--     * Only one VirtIODevice can be plugged on the bus.
--     */
--    VirtIODevice *vdev;
- };
- 
- int virtio_bus_plug_device(VirtIODevice *vdev);
-@@ -98,4 +94,16 @@ void virtio_bus_get_vdev_config(VirtioBusState *bus, uint8_t *config);
- /* Set config of the plugged device. */
- void virtio_bus_set_vdev_config(VirtioBusState *bus, uint8_t *config);
- 
-+static inline VirtIODevice *virtio_bus_get_device(VirtioBusState *bus)
-+{
-+    BusState *qbus = &bus->parent_obj;
-+    BusChild *kid = QTAILQ_FIRST(&qbus->children);
-+    DeviceState *qdev = kid ? kid->child : NULL;
-+
-+    /* This is used on the data path, the cast is guaranteed
-+     * to succeed by the qdev machinery.
-+     */
-+    return (VirtIODevice *)qdev;
-+}
-+
- #endif /* VIRTIO_BUS_H */
diff --git a/0006-virtio-ccw-remove-vdev-field.patch b/0006-virtio-ccw-remove-vdev-field.patch
new file mode 100644
index 0000000..19e3fd6
--- /dev/null
+++ b/0006-virtio-ccw-remove-vdev-field.patch
@@ -0,0 +1,293 @@
+From 7b81da30e3f4cb6e617f08cc822f4575a4a9e431 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Fri, 20 Sep 2013 16:57:52 +0200
+Subject: [PATCH] virtio-ccw: remove vdev field
+
+The vdev field is complicated to synchronize.  Just access the
+BusState's list of children.
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+---
+ hw/s390x/virtio-ccw.c | 80 ++++++++++++++++++++++++++++-----------------------
+ 1 file changed, 44 insertions(+), 36 deletions(-)
+
+diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
+index f93a81c..8947196 100644
+--- a/hw/s390x/virtio-ccw.c
++++ b/hw/s390x/virtio-ccw.c
+@@ -57,9 +57,10 @@ static const TypeInfo virtual_css_bus_info = {
+ VirtIODevice *virtio_ccw_get_vdev(SubchDev *sch)
+ {
+     VirtIODevice *vdev = NULL;
++    VirtioCcwDevice *dev = sch->driver_data;
+ 
+-    if (sch->driver_data) {
+-        vdev = ((VirtioCcwDevice *)sch->driver_data)->vdev;
++    if (dev) {
++        vdev = virtio_bus_get_device(&dev->bus);
+     }
+     return vdev;
+ }
+@@ -67,7 +68,8 @@ VirtIODevice *virtio_ccw_get_vdev(SubchDev *sch)
+ static int virtio_ccw_set_guest2host_notifier(VirtioCcwDevice *dev, int n,
+                                               bool assign, bool set_handler)
+ {
+-    VirtQueue *vq = virtio_get_queue(dev->vdev, n);
++    VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
++    VirtQueue *vq = virtio_get_queue(vdev, n);
+     EventNotifier *notifier = virtio_queue_get_host_notifier(vq);
+     int r = 0;
+     SubchDev *sch = dev->sch;
+@@ -97,6 +99,7 @@ static int virtio_ccw_set_guest2host_notifier(VirtioCcwDevice *dev, int n,
+ 
+ static void virtio_ccw_start_ioeventfd(VirtioCcwDevice *dev)
+ {
++    VirtIODevice *vdev;
+     int n, r;
+ 
+     if (!(dev->flags & VIRTIO_CCW_FLAG_USE_IOEVENTFD) ||
+@@ -104,8 +107,9 @@ static void virtio_ccw_start_ioeventfd(VirtioCcwDevice *dev)
+         dev->ioeventfd_started) {
+         return;
+     }
++    vdev = virtio_bus_get_device(&dev->bus);
+     for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
+-        if (!virtio_queue_get_num(dev->vdev, n)) {
++        if (!virtio_queue_get_num(vdev, n)) {
+             continue;
+         }
+         r = virtio_ccw_set_guest2host_notifier(dev, n, true, true);
+@@ -118,7 +122,7 @@ static void virtio_ccw_start_ioeventfd(VirtioCcwDevice *dev)
+ 
+   assign_error:
+     while (--n >= 0) {
+-        if (!virtio_queue_get_num(dev->vdev, n)) {
++        if (!virtio_queue_get_num(vdev, n)) {
+             continue;
+         }
+         r = virtio_ccw_set_guest2host_notifier(dev, n, false, false);
+@@ -132,13 +136,15 @@ static void virtio_ccw_start_ioeventfd(VirtioCcwDevice *dev)
+ 
+ static void virtio_ccw_stop_ioeventfd(VirtioCcwDevice *dev)
+ {
++    VirtIODevice *vdev;
+     int n, r;
+ 
+     if (!dev->ioeventfd_started) {
+         return;
+     }
++    vdev = virtio_bus_get_device(&dev->bus);
+     for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
+-        if (!virtio_queue_get_num(dev->vdev, n)) {
++        if (!virtio_queue_get_num(vdev, n)) {
+             continue;
+         }
+         r = virtio_ccw_set_guest2host_notifier(dev, n, false, false);
+@@ -189,7 +195,7 @@ typedef struct VirtioFeatDesc {
+ static int virtio_ccw_set_vqs(SubchDev *sch, uint64_t addr, uint32_t align,
+                               uint16_t index, uint16_t num)
+ {
+-    VirtioCcwDevice *dev = sch->driver_data;
++    VirtIODevice *vdev = virtio_ccw_get_vdev(sch);
+ 
+     if (index > VIRTIO_PCI_QUEUE_MAX) {
+         return -EINVAL;
+@@ -200,23 +206,23 @@ static int virtio_ccw_set_vqs(SubchDev *sch, uint64_t addr, uint32_t align,
+         return -EINVAL;
+     }
+ 
+-    if (!dev) {
++    if (!vdev) {
+         return -EINVAL;
+     }
+ 
+-    virtio_queue_set_addr(dev->vdev, index, addr);
++    virtio_queue_set_addr(vdev, index, addr);
+     if (!addr) {
+-        virtio_queue_set_vector(dev->vdev, index, 0);
++        virtio_queue_set_vector(vdev, index, 0);
+     } else {
+         /* Fail if we don't have a big enough queue. */
+         /* TODO: Add interface to handle vring.num changing */
+-        if (virtio_queue_get_num(dev->vdev, index) > num) {
++        if (virtio_queue_get_num(vdev, index) > num) {
+             return -EINVAL;
+         }
+-        virtio_queue_set_vector(dev->vdev, index, index);
++        virtio_queue_set_vector(vdev, index, index);
+     }
+     /* tell notify handler in case of config change */
+-    dev->vdev->config_vector = VIRTIO_PCI_QUEUE_MAX;
++    vdev->config_vector = VIRTIO_PCI_QUEUE_MAX;
+     return 0;
+ }
+ 
+@@ -230,6 +236,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
+     hwaddr indicators;
+     VqConfigBlock vq_config;
+     VirtioCcwDevice *dev = sch->driver_data;
++    VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
+     bool check_len;
+     int len;
+     hwaddr hw_len;
+@@ -272,7 +279,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
+         break;
+     case CCW_CMD_VDEV_RESET:
+         virtio_ccw_stop_ioeventfd(dev);
+-        virtio_reset(dev->vdev);
++        virtio_reset(vdev);
+         ret = 0;
+         break;
+     case CCW_CMD_READ_FEAT:
+@@ -319,7 +326,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
+             features.features = ldl_le_phys(ccw.cda);
+             if (features.index < ARRAY_SIZE(dev->host_features)) {
+                 virtio_bus_set_vdev_features(&dev->bus, features.features);
+-                dev->vdev->guest_features = features.features;
++                vdev->guest_features = features.features;
+             } else {
+                 /*
+                  * If the guest supports more feature bits, assert that it
+@@ -337,30 +344,30 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
+         break;
+     case CCW_CMD_READ_CONF:
+         if (check_len) {
+-            if (ccw.count > dev->vdev->config_len) {
++            if (ccw.count > vdev->config_len) {
+                 ret = -EINVAL;
+                 break;
+             }
+         }
+-        len = MIN(ccw.count, dev->vdev->config_len);
++        len = MIN(ccw.count, vdev->config_len);
+         if (!ccw.cda) {
+             ret = -EFAULT;
+         } else {
+-            virtio_bus_get_vdev_config(&dev->bus, dev->vdev->config);
++            virtio_bus_get_vdev_config(&dev->bus, vdev->config);
+             /* XXX config space endianness */
+-            cpu_physical_memory_write(ccw.cda, dev->vdev->config, len);
++            cpu_physical_memory_write(ccw.cda, vdev->config, len);
+             sch->curr_status.scsw.count = ccw.count - len;
+             ret = 0;
+         }
+         break;
+     case CCW_CMD_WRITE_CONF:
+         if (check_len) {
+-            if (ccw.count > dev->vdev->config_len) {
++            if (ccw.count > vdev->config_len) {
+                 ret = -EINVAL;
+                 break;
+             }
+         }
+-        len = MIN(ccw.count, dev->vdev->config_len);
++        len = MIN(ccw.count, vdev->config_len);
+         hw_len = len;
+         if (!ccw.cda) {
+             ret = -EFAULT;
+@@ -371,9 +378,9 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
+             } else {
+                 len = hw_len;
+                 /* XXX config space endianness */
+-                memcpy(dev->vdev->config, config, len);
++                memcpy(vdev->config, config, len);
+                 cpu_physical_memory_unmap(config, hw_len, 0, hw_len);
+-                virtio_bus_set_vdev_config(&dev->bus, dev->vdev->config);
++                virtio_bus_set_vdev_config(&dev->bus, vdev->config);
+                 sch->curr_status.scsw.count = ccw.count - len;
+                 ret = 0;
+             }
+@@ -397,9 +404,9 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
+             if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) {
+                 virtio_ccw_stop_ioeventfd(dev);
+             }
+-            virtio_set_status(dev->vdev, status);
+-            if (dev->vdev->status == 0) {
+-                virtio_reset(dev->vdev);
++            virtio_set_status(vdev, status);
++            if (vdev->status == 0) {
++                virtio_reset(vdev);
+             }
+             if (status & VIRTIO_CONFIG_S_DRIVER_OK) {
+                 virtio_ccw_start_ioeventfd(dev);
+@@ -463,7 +470,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
+             ret = -EFAULT;
+         } else {
+             vq_config.index = lduw_phys(ccw.cda);
+-            vq_config.num_max = virtio_queue_get_num(dev->vdev,
++            vq_config.num_max = virtio_queue_get_num(vdev,
+                                                      vq_config.index);
+             stw_phys(ccw.cda + sizeof(vq_config.index), vq_config.num_max);
+             sch->curr_status.scsw.count = ccw.count - sizeof(vq_config);
+@@ -495,7 +502,6 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev)
+     sch->driver_data = dev;
+     dev->sch = sch;
+ 
+-    dev->vdev = vdev;
+     dev->indicators = 0;
+ 
+     /* Initialize subchannel structure. */
+@@ -608,7 +614,7 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev)
+     memset(&sch->id, 0, sizeof(SenseId));
+     sch->id.reserved = 0xff;
+     sch->id.cu_type = VIRTIO_CCW_CU_TYPE;
+-    sch->id.cu_model = dev->vdev->device_id;
++    sch->id.cu_model = vdev->device_id;
+ 
+     /* Only the first 32 feature bits are used. */
+     dev->host_features[0] = virtio_bus_get_vdev_features(&dev->bus,
+@@ -892,9 +898,10 @@ static unsigned virtio_ccw_get_features(DeviceState *d)
+ static void virtio_ccw_reset(DeviceState *d)
+ {
+     VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
++    VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
+ 
+     virtio_ccw_stop_ioeventfd(dev);
+-    virtio_reset(dev->vdev);
++    virtio_reset(vdev);
+     css_reset_sch(dev->sch);
+     dev->indicators = 0;
+     dev->indicators2 = 0;
+@@ -934,9 +941,10 @@ static int virtio_ccw_set_host_notifier(DeviceState *d, int n, bool assign)
+ static int virtio_ccw_set_guest_notifier(VirtioCcwDevice *dev, int n,
+                                          bool assign, bool with_irqfd)
+ {
+-    VirtQueue *vq = virtio_get_queue(dev->vdev, n);
++    VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
++    VirtQueue *vq = virtio_get_queue(vdev, n);
+     EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
+-    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(dev->vdev);
++    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
+ 
+     if (assign) {
+         int r = event_notifier_init(notifier, 0);
+@@ -952,16 +960,16 @@ static int virtio_ccw_set_guest_notifier(VirtioCcwDevice *dev, int n,
+          * land in qemu (and only the irq fd) in this code.
+          */
+         if (k->guest_notifier_mask) {
+-            k->guest_notifier_mask(dev->vdev, n, false);
++            k->guest_notifier_mask(vdev, n, false);
+         }
+         /* get lost events and re-inject */
+         if (k->guest_notifier_pending &&
+-            k->guest_notifier_pending(dev->vdev, n)) {
++            k->guest_notifier_pending(vdev, n)) {
+             event_notifier_set(notifier);
+         }
+     } else {
+         if (k->guest_notifier_mask) {
+-            k->guest_notifier_mask(dev->vdev, n, true);
++            k->guest_notifier_mask(vdev, n, true);
+         }
+         virtio_queue_set_guest_notifier_fd_handler(vq, false, with_irqfd);
+         event_notifier_cleanup(notifier);
+@@ -973,7 +981,7 @@ static int virtio_ccw_set_guest_notifiers(DeviceState *d, int nvqs,
+                                           bool assigned)
+ {
+     VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
+-    VirtIODevice *vdev = dev->vdev;
++    VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
+     int r, n;
+ 
+     for (n = 0; n < nvqs; n++) {
diff --git a/0007-virtio-bus-cleanup-plug-unplug-interface.patch b/0007-virtio-bus-cleanup-plug-unplug-interface.patch
new file mode 100644
index 0000000..b79e033
--- /dev/null
+++ b/0007-virtio-bus-cleanup-plug-unplug-interface.patch
@@ -0,0 +1,148 @@
+From 7d948d3491e58e32ece358d783a05d51fdbd6ec3 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Fri, 20 Sep 2013 16:57:53 +0200
+Subject: [PATCH] virtio-bus: cleanup plug/unplug interface
+
+Right now we have these pairs:
+
+- virtio_bus_plug_device/virtio_bus_destroy_device.  The first
+  takes a VirtIODevice, the second takes a VirtioBusState
+
+- device_plugged/device_unplug callbacks in the VirtioBusClass
+  (here it's just the naming that is inconsistent)
+
+- virtio_bus_destroy_device is not called by anyone (and since
+  it calls qdev_free, it would be called by the proxies---but
+  then the callback is useless since the proxies can do whatever
+  they want before calling virtio_bus_destroy_device)
+
+And there is a k->init but no k->exit, hence virtio_device_exit is
+overwritten by subclasses (except virtio-9p).  This cleans it up by:
+
+- renaming the device_unplug callback to device_unplugged
+
+- renaming virtio_bus_plug_device to virtio_bus_device_plugged,
+  matching the callback name
+
+- renaming virtio_bus_destroy_device to virtio_bus_device_unplugged,
+  removing the qdev_free, making it take a VirtIODevice and calling it
+  from virtio_device_exit
+
+- adding a k->exit callback
+
+virtio_device_exit is still overwritten, the next patches will fix that.
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+---
+ hw/virtio/virtio-bus.c         | 18 +++++++++---------
+ hw/virtio/virtio.c             |  7 ++++++-
+ include/hw/virtio/virtio-bus.h |  6 +++---
+ include/hw/virtio/virtio.h     |  1 +
+ 4 files changed, 19 insertions(+), 13 deletions(-)
+
+diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c
+index 17dd06e..7aed6a4 100644
+--- a/hw/virtio/virtio-bus.c
++++ b/hw/virtio/virtio-bus.c
+@@ -37,8 +37,8 @@ do { printf("virtio_bus: " fmt , ## __VA_ARGS__); } while (0)
+ #define DPRINTF(fmt, ...) do { } while (0)
+ #endif
+ 
+-/* Plug the VirtIODevice */
+-int virtio_bus_plug_device(VirtIODevice *vdev)
++/* A VirtIODevice is being plugged */
++int virtio_bus_device_plugged(VirtIODevice *vdev)
+ {
+     DeviceState *qdev = DEVICE(vdev);
+     BusState *qbus = BUS(qdev_get_parent_bus(qdev));
+@@ -64,20 +64,20 @@ void virtio_bus_reset(VirtioBusState *bus)
+     }
+ }
+ 
+-/* Destroy the VirtIODevice */
+-void virtio_bus_destroy_device(VirtioBusState *bus)
++/* A VirtIODevice is being unplugged */
++void virtio_bus_device_unplugged(VirtIODevice *vdev)
+ {
+-    BusState *qbus = BUS(bus);
++    DeviceState *qdev = DEVICE(vdev);
++    BusState *qbus = BUS(qdev_get_parent_bus(qdev));
++    VirtioBusState *bus = VIRTIO_BUS(qbus);
+     VirtioBusClass *klass = VIRTIO_BUS_GET_CLASS(bus);
+-    VirtIODevice *vdev = virtio_bus_get_device(bus);
+ 
+     DPRINTF("%s: remove device.\n", qbus->name);
+ 
+     if (vdev != NULL) {
+-        if (klass->device_unplug != NULL) {
+-            klass->device_unplug(qbus->parent);
++        if (klass->device_unplugged != NULL) {
++            klass->device_unplugged(qbus->parent);
+         }
+-        object_unparent(OBJECT(vdev));
+     }
+ }
+ 
+diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
+index 2f1e73b..965b2c0 100644
+--- a/hw/virtio/virtio.c
++++ b/hw/virtio/virtio.c
+@@ -1158,14 +1158,19 @@ static int virtio_device_init(DeviceState *qdev)
+     if (k->init(vdev) < 0) {
+         return -1;
+     }
+-    virtio_bus_plug_device(vdev);
++    virtio_bus_device_plugged(vdev);
+     return 0;
+ }
+ 
+ static int virtio_device_exit(DeviceState *qdev)
+ {
+     VirtIODevice *vdev = VIRTIO_DEVICE(qdev);
++    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(qdev);
+ 
++    virtio_bus_device_unplugged(vdev);
++    if (k->exit) {
++        k->exit(vdev);
++    }
+     if (vdev->bus_name) {
+         g_free(vdev->bus_name);
+         vdev->bus_name = NULL;
+diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h
+index ba0f86a..0756545 100644
+--- a/include/hw/virtio/virtio-bus.h
++++ b/include/hw/virtio/virtio-bus.h
+@@ -61,7 +61,7 @@ typedef struct VirtioBusClass {
+      * transport independent exit function.
+      * This is called by virtio-bus just before the device is unplugged.
+      */
+-    void (*device_unplug)(DeviceState *d);
++    void (*device_unplugged)(DeviceState *d);
+     /*
+      * Does the transport have variable vring alignment?
+      * (ie can it ever call virtio_queue_set_align()?)
+@@ -74,9 +74,9 @@ struct VirtioBusState {
+     BusState parent_obj;
+ };
+ 
+-int virtio_bus_plug_device(VirtIODevice *vdev);
++int virtio_bus_device_plugged(VirtIODevice *vdev);
+ void virtio_bus_reset(VirtioBusState *bus);
+-void virtio_bus_destroy_device(VirtioBusState *bus);
++void virtio_bus_device_unplugged(VirtIODevice *bus);
+ /* Get the device id of the plugged device. */
+ uint16_t virtio_bus_get_vdev_id(VirtioBusState *bus);
+ /* Get the config_len field of the plugged device. */
+diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
+index a90522d..59756c2 100644
+--- a/include/hw/virtio/virtio.h
++++ b/include/hw/virtio/virtio.h
+@@ -127,6 +127,7 @@ typedef struct VirtioDeviceClass {
+     /* This is what a VirtioDevice must implement */
+     DeviceClass parent;
+     int (*init)(VirtIODevice *vdev);
++    void (*exit)(VirtIODevice *vdev);
+     uint32_t (*get_features)(VirtIODevice *vdev, uint32_t requested_features);
+     uint32_t (*bad_features)(VirtIODevice *vdev);
+     void (*set_features)(VirtIODevice *vdev, uint32_t val);
diff --git a/0007-virtio-pci-remove-vdev-field.patch b/0007-virtio-pci-remove-vdev-field.patch
deleted file mode 100644
index f8000e7..0000000
--- a/0007-virtio-pci-remove-vdev-field.patch
+++ /dev/null
@@ -1,447 +0,0 @@
-From 1d388b4fda2c4c9d00dc6ae91aaf35eb9fc04c26 Mon Sep 17 00:00:00 2001
-From: Paolo Bonzini <pbonzini@redhat.com>
-Date: Fri, 20 Sep 2013 16:57:51 +0200
-Subject: [PATCH] virtio-pci: remove vdev field
-
-The vdev field is complicated to synchronize.  Just access the
-BusState's list of children.
-
-Cc: qemu-stable@nongnu.org
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
----
- hw/s390x/virtio-ccw.h  |   1 -
- hw/virtio/virtio-pci.c | 107 +++++++++++++++++++++++++++++--------------------
- hw/virtio/virtio-pci.h |   1 -
- 3 files changed, 63 insertions(+), 46 deletions(-)
-
-diff --git a/hw/s390x/virtio-ccw.h b/hw/s390x/virtio-ccw.h
-index 96d6f5d..00932c7 100644
---- a/hw/s390x/virtio-ccw.h
-+++ b/hw/s390x/virtio-ccw.h
-@@ -77,7 +77,6 @@ typedef struct VirtIOCCWDeviceClass {
- struct VirtioCcwDevice {
-     DeviceState parent_obj;
-     SubchDev *sch;
--    VirtIODevice *vdev;
-     char *bus_id;
-     uint32_t host_features[VIRTIO_CCW_FEATURE_SIZE];
-     VirtioBusState bus;
-diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
-index 55617a6..6fd6d6d 100644
---- a/hw/virtio/virtio-pci.c
-+++ b/hw/virtio/virtio-pci.c
-@@ -112,31 +112,39 @@ static inline VirtIOPCIProxy *to_virtio_pci_proxy_fast(DeviceState *d)
- static void virtio_pci_notify(DeviceState *d, uint16_t vector)
- {
-     VirtIOPCIProxy *proxy = to_virtio_pci_proxy_fast(d);
-+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
-+
-     if (msix_enabled(&proxy->pci_dev))
-         msix_notify(&proxy->pci_dev, vector);
-     else
--        qemu_set_irq(proxy->pci_dev.irq[0], proxy->vdev->isr & 1);
-+        qemu_set_irq(proxy->pci_dev.irq[0], vdev->isr & 1);
- }
- 
- static void virtio_pci_save_config(DeviceState *d, QEMUFile *f)
- {
-     VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
-+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
-+
-     pci_device_save(&proxy->pci_dev, f);
-     msix_save(&proxy->pci_dev, f);
-     if (msix_present(&proxy->pci_dev))
--        qemu_put_be16(f, proxy->vdev->config_vector);
-+        qemu_put_be16(f, vdev->config_vector);
- }
- 
- static void virtio_pci_save_queue(DeviceState *d, int n, QEMUFile *f)
- {
-     VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
-+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
-+
-     if (msix_present(&proxy->pci_dev))
--        qemu_put_be16(f, virtio_queue_vector(proxy->vdev, n));
-+        qemu_put_be16(f, virtio_queue_vector(vdev, n));
- }
- 
- static int virtio_pci_load_config(DeviceState *d, QEMUFile *f)
- {
-     VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
-+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
-+
-     int ret;
-     ret = pci_device_load(&proxy->pci_dev, f);
-     if (ret) {
-@@ -145,12 +153,12 @@ static int virtio_pci_load_config(DeviceState *d, QEMUFile *f)
-     msix_unuse_all_vectors(&proxy->pci_dev);
-     msix_load(&proxy->pci_dev, f);
-     if (msix_present(&proxy->pci_dev)) {
--        qemu_get_be16s(f, &proxy->vdev->config_vector);
-+        qemu_get_be16s(f, &vdev->config_vector);
-     } else {
--        proxy->vdev->config_vector = VIRTIO_NO_VECTOR;
-+        vdev->config_vector = VIRTIO_NO_VECTOR;
-     }
--    if (proxy->vdev->config_vector != VIRTIO_NO_VECTOR) {
--        return msix_vector_use(&proxy->pci_dev, proxy->vdev->config_vector);
-+    if (vdev->config_vector != VIRTIO_NO_VECTOR) {
-+        return msix_vector_use(&proxy->pci_dev, vdev->config_vector);
-     }
-     return 0;
- }
-@@ -158,13 +166,15 @@ static int virtio_pci_load_config(DeviceState *d, QEMUFile *f)
- static int virtio_pci_load_queue(DeviceState *d, int n, QEMUFile *f)
- {
-     VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
-+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
-+
-     uint16_t vector;
-     if (msix_present(&proxy->pci_dev)) {
-         qemu_get_be16s(f, &vector);
-     } else {
-         vector = VIRTIO_NO_VECTOR;
-     }
--    virtio_queue_set_vector(proxy->vdev, n, vector);
-+    virtio_queue_set_vector(vdev, n, vector);
-     if (vector != VIRTIO_NO_VECTOR) {
-         return msix_vector_use(&proxy->pci_dev, vector);
-     }
-@@ -174,7 +184,8 @@ static int virtio_pci_load_queue(DeviceState *d, int n, QEMUFile *f)
- static int virtio_pci_set_host_notifier_internal(VirtIOPCIProxy *proxy,
-                                                  int n, bool assign, bool set_handler)
- {
--    VirtQueue *vq = virtio_get_queue(proxy->vdev, n);
-+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
-+    VirtQueue *vq = virtio_get_queue(vdev, n);
-     EventNotifier *notifier = virtio_queue_get_host_notifier(vq);
-     int r = 0;
- 
-@@ -199,6 +210,7 @@ static int virtio_pci_set_host_notifier_internal(VirtIOPCIProxy *proxy,
- 
- static void virtio_pci_start_ioeventfd(VirtIOPCIProxy *proxy)
- {
-+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
-     int n, r;
- 
-     if (!(proxy->flags & VIRTIO_PCI_FLAG_USE_IOEVENTFD) ||
-@@ -208,7 +220,7 @@ static void virtio_pci_start_ioeventfd(VirtIOPCIProxy *proxy)
-     }
- 
-     for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
--        if (!virtio_queue_get_num(proxy->vdev, n)) {
-+        if (!virtio_queue_get_num(vdev, n)) {
-             continue;
-         }
- 
-@@ -222,7 +234,7 @@ static void virtio_pci_start_ioeventfd(VirtIOPCIProxy *proxy)
- 
- assign_error:
-     while (--n >= 0) {
--        if (!virtio_queue_get_num(proxy->vdev, n)) {
-+        if (!virtio_queue_get_num(vdev, n)) {
-             continue;
-         }
- 
-@@ -235,6 +247,7 @@ assign_error:
- 
- static void virtio_pci_stop_ioeventfd(VirtIOPCIProxy *proxy)
- {
-+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
-     int r;
-     int n;
- 
-@@ -243,7 +256,7 @@ static void virtio_pci_stop_ioeventfd(VirtIOPCIProxy *proxy)
-     }
- 
-     for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
--        if (!virtio_queue_get_num(proxy->vdev, n)) {
-+        if (!virtio_queue_get_num(vdev, n)) {
-             continue;
-         }
- 
-@@ -256,7 +269,7 @@ static void virtio_pci_stop_ioeventfd(VirtIOPCIProxy *proxy)
- static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
- {
-     VirtIOPCIProxy *proxy = opaque;
--    VirtIODevice *vdev = proxy->vdev;
-+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
-     hwaddr pa;
- 
-     switch (addr) {
-@@ -271,7 +284,7 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-         pa = (hwaddr)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT;
-         if (pa == 0) {
-             virtio_pci_stop_ioeventfd(proxy);
--            virtio_reset(proxy->vdev);
-+            virtio_reset(vdev);
-             msix_unuse_all_vectors(&proxy->pci_dev);
-         }
-         else
-@@ -298,7 +311,7 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-         }
- 
-         if (vdev->status == 0) {
--            virtio_reset(proxy->vdev);
-+            virtio_reset(vdev);
-             msix_unuse_all_vectors(&proxy->pci_dev);
-         }
- 
-@@ -334,7 +347,7 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
- 
- static uint32_t virtio_ioport_read(VirtIOPCIProxy *proxy, uint32_t addr)
- {
--    VirtIODevice *vdev = proxy->vdev;
-+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
-     uint32_t ret = 0xFFFFFFFF;
- 
-     switch (addr) {
-@@ -380,6 +393,7 @@ static uint64_t virtio_pci_config_read(void *opaque, hwaddr addr,
-                                        unsigned size)
- {
-     VirtIOPCIProxy *proxy = opaque;
-+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
-     uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
-     uint64_t val = 0;
-     if (addr < config) {
-@@ -389,16 +403,16 @@ static uint64_t virtio_pci_config_read(void *opaque, hwaddr addr,
- 
-     switch (size) {
-     case 1:
--        val = virtio_config_readb(proxy->vdev, addr);
-+        val = virtio_config_readb(vdev, addr);
-         break;
-     case 2:
--        val = virtio_config_readw(proxy->vdev, addr);
-+        val = virtio_config_readw(vdev, addr);
-         if (virtio_is_big_endian()) {
-             val = bswap16(val);
-         }
-         break;
-     case 4:
--        val = virtio_config_readl(proxy->vdev, addr);
-+        val = virtio_config_readl(vdev, addr);
-         if (virtio_is_big_endian()) {
-             val = bswap32(val);
-         }
-@@ -412,6 +426,7 @@ static void virtio_pci_config_write(void *opaque, hwaddr addr,
- {
-     VirtIOPCIProxy *proxy = opaque;
-     uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
-+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
-     if (addr < config) {
-         virtio_ioport_write(proxy, addr, val);
-         return;
-@@ -423,19 +438,19 @@ static void virtio_pci_config_write(void *opaque, hwaddr addr,
-      */
-     switch (size) {
-     case 1:
--        virtio_config_writeb(proxy->vdev, addr, val);
-+        virtio_config_writeb(vdev, addr, val);
-         break;
-     case 2:
-         if (virtio_is_big_endian()) {
-             val = bswap16(val);
-         }
--        virtio_config_writew(proxy->vdev, addr, val);
-+        virtio_config_writew(vdev, addr, val);
-         break;
-     case 4:
-         if (virtio_is_big_endian()) {
-             val = bswap32(val);
-         }
--        virtio_config_writel(proxy->vdev, addr, val);
-+        virtio_config_writel(vdev, addr, val);
-         break;
-     }
- }
-@@ -454,6 +469,7 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
-                                 uint32_t val, int len)
- {
-     VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
-+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
- 
-     pci_default_write_config(pci_dev, address, val, len);
- 
-@@ -461,8 +477,7 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
-         !(pci_dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER) &&
-         !(proxy->flags & VIRTIO_PCI_FLAG_BUS_MASTER_BUG)) {
-         virtio_pci_stop_ioeventfd(proxy);
--        virtio_set_status(proxy->vdev,
--                          proxy->vdev->status & ~VIRTIO_CONFIG_S_DRIVER_OK);
-+        virtio_set_status(vdev, vdev->status & ~VIRTIO_CONFIG_S_DRIVER_OK);
-     }
- }
- 
-@@ -505,7 +520,8 @@ static int kvm_virtio_pci_irqfd_use(VirtIOPCIProxy *proxy,
-                                  unsigned int vector)
- {
-     VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
--    VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no);
-+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
-+    VirtQueue *vq = virtio_get_queue(vdev, queue_no);
-     EventNotifier *n = virtio_queue_get_guest_notifier(vq);
-     int ret;
-     ret = kvm_irqchip_add_irqfd_notifier(kvm_state, n, irqfd->virq);
-@@ -516,7 +532,8 @@ static void kvm_virtio_pci_irqfd_release(VirtIOPCIProxy *proxy,
-                                       unsigned int queue_no,
-                                       unsigned int vector)
- {
--    VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no);
-+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
-+    VirtQueue *vq = virtio_get_queue(vdev, queue_no);
-     EventNotifier *n = virtio_queue_get_guest_notifier(vq);
-     VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
-     int ret;
-@@ -528,7 +545,7 @@ static void kvm_virtio_pci_irqfd_release(VirtIOPCIProxy *proxy,
- static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
- {
-     PCIDevice *dev = &proxy->pci_dev;
--    VirtIODevice *vdev = proxy->vdev;
-+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
-     VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
-     unsigned int vector;
-     int ret, queue_no;
-@@ -577,7 +594,7 @@ undo:
- static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
- {
-     PCIDevice *dev = &proxy->pci_dev;
--    VirtIODevice *vdev = proxy->vdev;
-+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
-     unsigned int vector;
-     int queue_no;
-     VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
-@@ -605,8 +622,9 @@ static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy,
-                                        unsigned int vector,
-                                        MSIMessage msg)
- {
--    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(proxy->vdev);
--    VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no);
-+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
-+    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
-+    VirtQueue *vq = virtio_get_queue(vdev, queue_no);
-     EventNotifier *n = virtio_queue_get_guest_notifier(vq);
-     VirtIOIRQFD *irqfd;
-     int ret = 0;
-@@ -625,10 +643,10 @@ static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy,
-      * Otherwise, set it up now.
-      */
-     if (k->guest_notifier_mask) {
--        k->guest_notifier_mask(proxy->vdev, queue_no, false);
-+        k->guest_notifier_mask(vdev, queue_no, false);
-         /* Test after unmasking to avoid losing events. */
-         if (k->guest_notifier_pending &&
--            k->guest_notifier_pending(proxy->vdev, queue_no)) {
-+            k->guest_notifier_pending(vdev, queue_no)) {
-             event_notifier_set(n);
-         }
-     } else {
-@@ -641,13 +659,14 @@ static void virtio_pci_vq_vector_mask(VirtIOPCIProxy *proxy,
-                                              unsigned int queue_no,
-                                              unsigned int vector)
- {
--    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(proxy->vdev);
-+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
-+    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
- 
-     /* If guest supports masking, keep irqfd but mask it.
-      * Otherwise, clean it up now.
-      */ 
-     if (k->guest_notifier_mask) {
--        k->guest_notifier_mask(proxy->vdev, queue_no, true);
-+        k->guest_notifier_mask(vdev, queue_no, true);
-     } else {
-         kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
-     }
-@@ -657,7 +676,7 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector,
-                                     MSIMessage msg)
- {
-     VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
--    VirtIODevice *vdev = proxy->vdev;
-+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
-     int ret, queue_no;
- 
-     for (queue_no = 0; queue_no < proxy->nvqs_with_notifiers; queue_no++) {
-@@ -687,7 +706,7 @@ undo:
- static void virtio_pci_vector_mask(PCIDevice *dev, unsigned vector)
- {
-     VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
--    VirtIODevice *vdev = proxy->vdev;
-+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
-     int queue_no;
- 
-     for (queue_no = 0; queue_no < proxy->nvqs_with_notifiers; queue_no++) {
-@@ -706,7 +725,7 @@ static void virtio_pci_vector_poll(PCIDevice *dev,
-                                    unsigned int vector_end)
- {
-     VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
--    VirtIODevice *vdev = proxy->vdev;
-+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
-     VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
-     int queue_no;
-     unsigned int vector;
-@@ -738,8 +757,9 @@ static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign,
-                                          bool with_irqfd)
- {
-     VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
--    VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(proxy->vdev);
--    VirtQueue *vq = virtio_get_queue(proxy->vdev, n);
-+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
-+    VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
-+    VirtQueue *vq = virtio_get_queue(vdev, n);
-     EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
- 
-     if (assign) {
-@@ -754,7 +774,7 @@ static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign,
-     }
- 
-     if (!msix_enabled(&proxy->pci_dev) && vdc->guest_notifier_mask) {
--        vdc->guest_notifier_mask(proxy->vdev, n, !assign);
-+        vdc->guest_notifier_mask(vdev, n, !assign);
-     }
- 
-     return 0;
-@@ -769,7 +789,7 @@ static bool virtio_pci_query_guest_notifiers(DeviceState *d)
- static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign)
- {
-     VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
--    VirtIODevice *vdev = proxy->vdev;
-+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
-     VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
-     int r, n;
-     bool with_irqfd = msix_enabled(&proxy->pci_dev) &&
-@@ -863,11 +883,12 @@ static int virtio_pci_set_host_notifier(DeviceState *d, int n, bool assign)
- static void virtio_pci_vmstate_change(DeviceState *d, bool running)
- {
-     VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
-+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
- 
-     if (running) {
-         /* Try to find out if the guest has bus master disabled, but is
-            in ready state. Then we have a buggy guest OS. */
--        if ((proxy->vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) &&
-+        if ((vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) &&
-             !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
-             proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
-         }
-@@ -942,8 +963,6 @@ static void virtio_pci_device_plugged(DeviceState *d)
-     uint8_t *config;
-     uint32_t size;
- 
--    proxy->vdev = virtio_bus_get_device(bus);
--
-     config = proxy->pci_dev.config;
-     if (proxy->class_code) {
-         pci_config_set_class(config, proxy->class_code);
-diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h
-index 917bcc5..dc332ae 100644
---- a/hw/virtio/virtio-pci.h
-+++ b/hw/virtio/virtio-pci.h
-@@ -82,7 +82,6 @@ typedef struct VirtioPCIClass {
- 
- struct VirtIOPCIProxy {
-     PCIDevice pci_dev;
--    VirtIODevice *vdev;
-     MemoryRegion bar;
-     uint32_t flags;
-     uint32_t class_code;
diff --git a/0008-virtio-blk-switch-exit-callback-to-VirtioDeviceClass.patch b/0008-virtio-blk-switch-exit-callback-to-VirtioDeviceClass.patch
new file mode 100644
index 0000000..24aa7df
--- /dev/null
+++ b/0008-virtio-blk-switch-exit-callback-to-VirtioDeviceClass.patch
@@ -0,0 +1,53 @@
+From 07ffeff19959e11ae7d68f7dc17a3225deb88f8f Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Fri, 20 Sep 2013 16:57:54 +0200
+Subject: [PATCH] virtio-blk: switch exit callback to VirtioDeviceClass
+
+This ensures hot-unplug is handled properly by the proxy.
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+---
+ hw/block/virtio-blk.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
+index 13f6d82..7f0440f 100644
+--- a/hw/block/virtio-blk.c
++++ b/hw/block/virtio-blk.c
+@@ -728,20 +728,18 @@ static int virtio_blk_device_init(VirtIODevice *vdev)
+     return 0;
+ }
+ 
+-static int virtio_blk_device_exit(DeviceState *dev)
++static void virtio_blk_device_exit(VirtIODevice *vdev)
+ {
+-    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+-    VirtIOBlock *s = VIRTIO_BLK(dev);
++    VirtIOBlock *s = VIRTIO_BLK(vdev);
+ #ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
+     remove_migration_state_change_notifier(&s->migration_state_notifier);
+     virtio_blk_data_plane_destroy(s->dataplane);
+     s->dataplane = NULL;
+ #endif
+     qemu_del_vm_change_state_handler(s->change);
+-    unregister_savevm(dev, "virtio-blk", s);
++    unregister_savevm(DEVICE(vdev), "virtio-blk", s);
+     blockdev_mark_auto_del(s->bs);
+     virtio_cleanup(vdev);
+-    return 0;
+ }
+ 
+ static Property virtio_blk_properties[] = {
+@@ -753,10 +751,10 @@ static void virtio_blk_class_init(ObjectClass *klass, void *data)
+ {
+     DeviceClass *dc = DEVICE_CLASS(klass);
+     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+-    dc->exit = virtio_blk_device_exit;
+     dc->props = virtio_blk_properties;
+     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
+     vdc->init = virtio_blk_device_init;
++    vdc->exit = virtio_blk_device_exit;
+     vdc->get_config = virtio_blk_update_config;
+     vdc->set_config = virtio_blk_set_config;
+     vdc->get_features = virtio_blk_get_features;
diff --git a/0008-virtio-ccw-remove-vdev-field.patch b/0008-virtio-ccw-remove-vdev-field.patch
deleted file mode 100644
index d0c8d62..0000000
--- a/0008-virtio-ccw-remove-vdev-field.patch
+++ /dev/null
@@ -1,293 +0,0 @@
-From a9b1f1aeba8167ae90aecea9b8ca223faf33ae90 Mon Sep 17 00:00:00 2001
-From: Paolo Bonzini <pbonzini@redhat.com>
-Date: Fri, 20 Sep 2013 16:57:52 +0200
-Subject: [PATCH] virtio-ccw: remove vdev field
-
-The vdev field is complicated to synchronize.  Just access the
-BusState's list of children.
-
-Cc: qemu-stable@nongnu.org
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
----
- hw/s390x/virtio-ccw.c | 80 ++++++++++++++++++++++++++++-----------------------
- 1 file changed, 44 insertions(+), 36 deletions(-)
-
-diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
-index 8835bd4..0fc7387 100644
---- a/hw/s390x/virtio-ccw.c
-+++ b/hw/s390x/virtio-ccw.c
-@@ -56,9 +56,10 @@ static const TypeInfo virtual_css_bus_info = {
- VirtIODevice *virtio_ccw_get_vdev(SubchDev *sch)
- {
-     VirtIODevice *vdev = NULL;
-+    VirtioCcwDevice *dev = sch->driver_data;
- 
--    if (sch->driver_data) {
--        vdev = ((VirtioCcwDevice *)sch->driver_data)->vdev;
-+    if (dev) {
-+        vdev = virtio_bus_get_device(&dev->bus);
-     }
-     return vdev;
- }
-@@ -66,7 +67,8 @@ VirtIODevice *virtio_ccw_get_vdev(SubchDev *sch)
- static int virtio_ccw_set_guest2host_notifier(VirtioCcwDevice *dev, int n,
-                                               bool assign, bool set_handler)
- {
--    VirtQueue *vq = virtio_get_queue(dev->vdev, n);
-+    VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
-+    VirtQueue *vq = virtio_get_queue(vdev, n);
-     EventNotifier *notifier = virtio_queue_get_host_notifier(vq);
-     int r = 0;
-     SubchDev *sch = dev->sch;
-@@ -96,6 +98,7 @@ static int virtio_ccw_set_guest2host_notifier(VirtioCcwDevice *dev, int n,
- 
- static void virtio_ccw_start_ioeventfd(VirtioCcwDevice *dev)
- {
-+    VirtIODevice *vdev;
-     int n, r;
- 
-     if (!(dev->flags & VIRTIO_CCW_FLAG_USE_IOEVENTFD) ||
-@@ -103,8 +106,9 @@ static void virtio_ccw_start_ioeventfd(VirtioCcwDevice *dev)
-         dev->ioeventfd_started) {
-         return;
-     }
-+    vdev = virtio_bus_get_device(&dev->bus);
-     for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
--        if (!virtio_queue_get_num(dev->vdev, n)) {
-+        if (!virtio_queue_get_num(vdev, n)) {
-             continue;
-         }
-         r = virtio_ccw_set_guest2host_notifier(dev, n, true, true);
-@@ -117,7 +121,7 @@ static void virtio_ccw_start_ioeventfd(VirtioCcwDevice *dev)
- 
-   assign_error:
-     while (--n >= 0) {
--        if (!virtio_queue_get_num(dev->vdev, n)) {
-+        if (!virtio_queue_get_num(vdev, n)) {
-             continue;
-         }
-         r = virtio_ccw_set_guest2host_notifier(dev, n, false, false);
-@@ -131,13 +135,15 @@ static void virtio_ccw_start_ioeventfd(VirtioCcwDevice *dev)
- 
- static void virtio_ccw_stop_ioeventfd(VirtioCcwDevice *dev)
- {
-+    VirtIODevice *vdev;
-     int n, r;
- 
-     if (!dev->ioeventfd_started) {
-         return;
-     }
-+    vdev = virtio_bus_get_device(&dev->bus);
-     for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
--        if (!virtio_queue_get_num(dev->vdev, n)) {
-+        if (!virtio_queue_get_num(vdev, n)) {
-             continue;
-         }
-         r = virtio_ccw_set_guest2host_notifier(dev, n, false, false);
-@@ -188,7 +194,7 @@ typedef struct VirtioFeatDesc {
- static int virtio_ccw_set_vqs(SubchDev *sch, uint64_t addr, uint32_t align,
-                               uint16_t index, uint16_t num)
- {
--    VirtioCcwDevice *dev = sch->driver_data;
-+    VirtIODevice *vdev = virtio_ccw_get_vdev(sch);
- 
-     if (index > VIRTIO_PCI_QUEUE_MAX) {
-         return -EINVAL;
-@@ -199,23 +205,23 @@ static int virtio_ccw_set_vqs(SubchDev *sch, uint64_t addr, uint32_t align,
-         return -EINVAL;
-     }
- 
--    if (!dev) {
-+    if (!vdev) {
-         return -EINVAL;
-     }
- 
--    virtio_queue_set_addr(dev->vdev, index, addr);
-+    virtio_queue_set_addr(vdev, index, addr);
-     if (!addr) {
--        virtio_queue_set_vector(dev->vdev, index, 0);
-+        virtio_queue_set_vector(vdev, index, 0);
-     } else {
-         /* Fail if we don't have a big enough queue. */
-         /* TODO: Add interface to handle vring.num changing */
--        if (virtio_queue_get_num(dev->vdev, index) > num) {
-+        if (virtio_queue_get_num(vdev, index) > num) {
-             return -EINVAL;
-         }
--        virtio_queue_set_vector(dev->vdev, index, index);
-+        virtio_queue_set_vector(vdev, index, index);
-     }
-     /* tell notify handler in case of config change */
--    dev->vdev->config_vector = VIRTIO_PCI_QUEUE_MAX;
-+    vdev->config_vector = VIRTIO_PCI_QUEUE_MAX;
-     return 0;
- }
- 
-@@ -229,6 +235,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
-     hwaddr indicators;
-     VqConfigBlock vq_config;
-     VirtioCcwDevice *dev = sch->driver_data;
-+    VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
-     bool check_len;
-     int len;
-     hwaddr hw_len;
-@@ -271,7 +278,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
-         break;
-     case CCW_CMD_VDEV_RESET:
-         virtio_ccw_stop_ioeventfd(dev);
--        virtio_reset(dev->vdev);
-+        virtio_reset(vdev);
-         ret = 0;
-         break;
-     case CCW_CMD_READ_FEAT:
-@@ -318,7 +325,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
-             features.features = ldl_le_phys(ccw.cda);
-             if (features.index < ARRAY_SIZE(dev->host_features)) {
-                 virtio_bus_set_vdev_features(&dev->bus, features.features);
--                dev->vdev->guest_features = features.features;
-+                vdev->guest_features = features.features;
-             } else {
-                 /*
-                  * If the guest supports more feature bits, assert that it
-@@ -336,30 +343,30 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
-         break;
-     case CCW_CMD_READ_CONF:
-         if (check_len) {
--            if (ccw.count > dev->vdev->config_len) {
-+            if (ccw.count > vdev->config_len) {
-                 ret = -EINVAL;
-                 break;
-             }
-         }
--        len = MIN(ccw.count, dev->vdev->config_len);
-+        len = MIN(ccw.count, vdev->config_len);
-         if (!ccw.cda) {
-             ret = -EFAULT;
-         } else {
--            virtio_bus_get_vdev_config(&dev->bus, dev->vdev->config);
-+            virtio_bus_get_vdev_config(&dev->bus, vdev->config);
-             /* XXX config space endianness */
--            cpu_physical_memory_write(ccw.cda, dev->vdev->config, len);
-+            cpu_physical_memory_write(ccw.cda, vdev->config, len);
-             sch->curr_status.scsw.count = ccw.count - len;
-             ret = 0;
-         }
-         break;
-     case CCW_CMD_WRITE_CONF:
-         if (check_len) {
--            if (ccw.count > dev->vdev->config_len) {
-+            if (ccw.count > vdev->config_len) {
-                 ret = -EINVAL;
-                 break;
-             }
-         }
--        len = MIN(ccw.count, dev->vdev->config_len);
-+        len = MIN(ccw.count, vdev->config_len);
-         hw_len = len;
-         if (!ccw.cda) {
-             ret = -EFAULT;
-@@ -370,9 +377,9 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
-             } else {
-                 len = hw_len;
-                 /* XXX config space endianness */
--                memcpy(dev->vdev->config, config, len);
-+                memcpy(vdev->config, config, len);
-                 cpu_physical_memory_unmap(config, hw_len, 0, hw_len);
--                virtio_bus_set_vdev_config(&dev->bus, dev->vdev->config);
-+                virtio_bus_set_vdev_config(&dev->bus, vdev->config);
-                 sch->curr_status.scsw.count = ccw.count - len;
-                 ret = 0;
-             }
-@@ -396,9 +403,9 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
-             if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) {
-                 virtio_ccw_stop_ioeventfd(dev);
-             }
--            virtio_set_status(dev->vdev, status);
--            if (dev->vdev->status == 0) {
--                virtio_reset(dev->vdev);
-+            virtio_set_status(vdev, status);
-+            if (vdev->status == 0) {
-+                virtio_reset(vdev);
-             }
-             if (status & VIRTIO_CONFIG_S_DRIVER_OK) {
-                 virtio_ccw_start_ioeventfd(dev);
-@@ -462,7 +469,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
-             ret = -EFAULT;
-         } else {
-             vq_config.index = lduw_phys(ccw.cda);
--            vq_config.num_max = virtio_queue_get_num(dev->vdev,
-+            vq_config.num_max = virtio_queue_get_num(vdev,
-                                                      vq_config.index);
-             stw_phys(ccw.cda + sizeof(vq_config.index), vq_config.num_max);
-             sch->curr_status.scsw.count = ccw.count - sizeof(vq_config);
-@@ -494,7 +501,6 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev)
-     sch->driver_data = dev;
-     dev->sch = sch;
- 
--    dev->vdev = vdev;
-     dev->indicators = 0;
- 
-     /* Initialize subchannel structure. */
-@@ -607,7 +613,7 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev)
-     memset(&sch->id, 0, sizeof(SenseId));
-     sch->id.reserved = 0xff;
-     sch->id.cu_type = VIRTIO_CCW_CU_TYPE;
--    sch->id.cu_model = dev->vdev->device_id;
-+    sch->id.cu_model = vdev->device_id;
- 
-     /* Only the first 32 feature bits are used. */
-     dev->host_features[0] = virtio_bus_get_vdev_features(&dev->bus,
-@@ -891,9 +897,10 @@ static unsigned virtio_ccw_get_features(DeviceState *d)
- static void virtio_ccw_reset(DeviceState *d)
- {
-     VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
-+    VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
- 
-     virtio_ccw_stop_ioeventfd(dev);
--    virtio_reset(dev->vdev);
-+    virtio_reset(vdev);
-     css_reset_sch(dev->sch);
-     dev->indicators = 0;
-     dev->indicators2 = 0;
-@@ -933,9 +940,10 @@ static int virtio_ccw_set_host_notifier(DeviceState *d, int n, bool assign)
- static int virtio_ccw_set_guest_notifier(VirtioCcwDevice *dev, int n,
-                                          bool assign, bool with_irqfd)
- {
--    VirtQueue *vq = virtio_get_queue(dev->vdev, n);
-+    VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
-+    VirtQueue *vq = virtio_get_queue(vdev, n);
-     EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
--    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(dev->vdev);
-+    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
- 
-     if (assign) {
-         int r = event_notifier_init(notifier, 0);
-@@ -951,16 +959,16 @@ static int virtio_ccw_set_guest_notifier(VirtioCcwDevice *dev, int n,
-          * land in qemu (and only the irq fd) in this code.
-          */
-         if (k->guest_notifier_mask) {
--            k->guest_notifier_mask(dev->vdev, n, false);
-+            k->guest_notifier_mask(vdev, n, false);
-         }
-         /* get lost events and re-inject */
-         if (k->guest_notifier_pending &&
--            k->guest_notifier_pending(dev->vdev, n)) {
-+            k->guest_notifier_pending(vdev, n)) {
-             event_notifier_set(notifier);
-         }
-     } else {
-         if (k->guest_notifier_mask) {
--            k->guest_notifier_mask(dev->vdev, n, true);
-+            k->guest_notifier_mask(vdev, n, true);
-         }
-         virtio_queue_set_guest_notifier_fd_handler(vq, false, with_irqfd);
-         event_notifier_cleanup(notifier);
-@@ -972,7 +980,7 @@ static int virtio_ccw_set_guest_notifiers(DeviceState *d, int nvqs,
-                                           bool assigned)
- {
-     VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
--    VirtIODevice *vdev = dev->vdev;
-+    VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
-     int r, n;
- 
-     for (n = 0; n < nvqs; n++) {
diff --git a/0009-virtio-bus-cleanup-plug-unplug-interface.patch b/0009-virtio-bus-cleanup-plug-unplug-interface.patch
deleted file mode 100644
index b8a91f4..0000000
--- a/0009-virtio-bus-cleanup-plug-unplug-interface.patch
+++ /dev/null
@@ -1,148 +0,0 @@
-From fe02fcc2b929e6a678ec783cb80890b79b7dca78 Mon Sep 17 00:00:00 2001
-From: Paolo Bonzini <pbonzini@redhat.com>
-Date: Fri, 20 Sep 2013 16:57:53 +0200
-Subject: [PATCH] virtio-bus: cleanup plug/unplug interface
-
-Right now we have these pairs:
-
-- virtio_bus_plug_device/virtio_bus_destroy_device.  The first
-  takes a VirtIODevice, the second takes a VirtioBusState
-
-- device_plugged/device_unplug callbacks in the VirtioBusClass
-  (here it's just the naming that is inconsistent)
-
-- virtio_bus_destroy_device is not called by anyone (and since
-  it calls qdev_free, it would be called by the proxies---but
-  then the callback is useless since the proxies can do whatever
-  they want before calling virtio_bus_destroy_device)
-
-And there is a k->init but no k->exit, hence virtio_device_exit is
-overwritten by subclasses (except virtio-9p).  This cleans it up by:
-
-- renaming the device_unplug callback to device_unplugged
-
-- renaming virtio_bus_plug_device to virtio_bus_device_plugged,
-  matching the callback name
-
-- renaming virtio_bus_destroy_device to virtio_bus_device_unplugged,
-  removing the qdev_free, making it take a VirtIODevice and calling it
-  from virtio_device_exit
-
-- adding a k->exit callback
-
-virtio_device_exit is still overwritten, the next patches will fix that.
-
-Cc: qemu-stable@nongnu.org
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
----
- hw/virtio/virtio-bus.c         | 18 +++++++++---------
- hw/virtio/virtio.c             |  7 ++++++-
- include/hw/virtio/virtio-bus.h |  6 +++---
- include/hw/virtio/virtio.h     |  1 +
- 4 files changed, 19 insertions(+), 13 deletions(-)
-
-diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c
-index 669ce38..7aed6a4 100644
---- a/hw/virtio/virtio-bus.c
-+++ b/hw/virtio/virtio-bus.c
-@@ -37,8 +37,8 @@ do { printf("virtio_bus: " fmt , ## __VA_ARGS__); } while (0)
- #define DPRINTF(fmt, ...) do { } while (0)
- #endif
- 
--/* Plug the VirtIODevice */
--int virtio_bus_plug_device(VirtIODevice *vdev)
-+/* A VirtIODevice is being plugged */
-+int virtio_bus_device_plugged(VirtIODevice *vdev)
- {
-     DeviceState *qdev = DEVICE(vdev);
-     BusState *qbus = BUS(qdev_get_parent_bus(qdev));
-@@ -64,20 +64,20 @@ void virtio_bus_reset(VirtioBusState *bus)
-     }
- }
- 
--/* Destroy the VirtIODevice */
--void virtio_bus_destroy_device(VirtioBusState *bus)
-+/* A VirtIODevice is being unplugged */
-+void virtio_bus_device_unplugged(VirtIODevice *vdev)
- {
--    BusState *qbus = BUS(bus);
-+    DeviceState *qdev = DEVICE(vdev);
-+    BusState *qbus = BUS(qdev_get_parent_bus(qdev));
-+    VirtioBusState *bus = VIRTIO_BUS(qbus);
-     VirtioBusClass *klass = VIRTIO_BUS_GET_CLASS(bus);
--    VirtIODevice *vdev = virtio_bus_get_device(bus);
- 
-     DPRINTF("%s: remove device.\n", qbus->name);
- 
-     if (vdev != NULL) {
--        if (klass->device_unplug != NULL) {
--            klass->device_unplug(qbus->parent);
-+        if (klass->device_unplugged != NULL) {
-+            klass->device_unplugged(qbus->parent);
-         }
--        qdev_free(DEVICE(vdev));
-     }
- }
- 
-diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
-index 2f1e73b..965b2c0 100644
---- a/hw/virtio/virtio.c
-+++ b/hw/virtio/virtio.c
-@@ -1158,14 +1158,19 @@ static int virtio_device_init(DeviceState *qdev)
-     if (k->init(vdev) < 0) {
-         return -1;
-     }
--    virtio_bus_plug_device(vdev);
-+    virtio_bus_device_plugged(vdev);
-     return 0;
- }
- 
- static int virtio_device_exit(DeviceState *qdev)
- {
-     VirtIODevice *vdev = VIRTIO_DEVICE(qdev);
-+    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(qdev);
- 
-+    virtio_bus_device_unplugged(vdev);
-+    if (k->exit) {
-+        k->exit(vdev);
-+    }
-     if (vdev->bus_name) {
-         g_free(vdev->bus_name);
-         vdev->bus_name = NULL;
-diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h
-index ba0f86a..0756545 100644
---- a/include/hw/virtio/virtio-bus.h
-+++ b/include/hw/virtio/virtio-bus.h
-@@ -61,7 +61,7 @@ typedef struct VirtioBusClass {
-      * transport independent exit function.
-      * This is called by virtio-bus just before the device is unplugged.
-      */
--    void (*device_unplug)(DeviceState *d);
-+    void (*device_unplugged)(DeviceState *d);
-     /*
-      * Does the transport have variable vring alignment?
-      * (ie can it ever call virtio_queue_set_align()?)
-@@ -74,9 +74,9 @@ struct VirtioBusState {
-     BusState parent_obj;
- };
- 
--int virtio_bus_plug_device(VirtIODevice *vdev);
-+int virtio_bus_device_plugged(VirtIODevice *vdev);
- void virtio_bus_reset(VirtioBusState *bus);
--void virtio_bus_destroy_device(VirtioBusState *bus);
-+void virtio_bus_device_unplugged(VirtIODevice *bus);
- /* Get the device id of the plugged device. */
- uint16_t virtio_bus_get_vdev_id(VirtioBusState *bus);
- /* Get the config_len field of the plugged device. */
-diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
-index a90522d..59756c2 100644
---- a/include/hw/virtio/virtio.h
-+++ b/include/hw/virtio/virtio.h
-@@ -127,6 +127,7 @@ typedef struct VirtioDeviceClass {
-     /* This is what a VirtioDevice must implement */
-     DeviceClass parent;
-     int (*init)(VirtIODevice *vdev);
-+    void (*exit)(VirtIODevice *vdev);
-     uint32_t (*get_features)(VirtIODevice *vdev, uint32_t requested_features);
-     uint32_t (*bad_features)(VirtIODevice *vdev);
-     void (*set_features)(VirtIODevice *vdev, uint32_t val);
diff --git a/0009-virtio-serial-switch-exit-callback-to-VirtioDeviceCl.patch b/0009-virtio-serial-switch-exit-callback-to-VirtioDeviceCl.patch
new file mode 100644
index 0000000..0da9ea5
--- /dev/null
+++ b/0009-virtio-serial-switch-exit-callback-to-VirtioDeviceCl.patch
@@ -0,0 +1,53 @@
+From 010f4a29c797e098a1fe4b5b2b14c6cfba2f6327 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Fri, 20 Sep 2013 16:57:55 +0200
+Subject: [PATCH] virtio-serial: switch exit callback to VirtioDeviceClass
+
+This ensures hot-unplug is handled properly by the proxy.
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+---
+ hw/char/virtio-serial-bus.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
+index 703f026..a7ede90 100644
+--- a/hw/char/virtio-serial-bus.c
++++ b/hw/char/virtio-serial-bus.c
+@@ -987,12 +987,11 @@ static const TypeInfo virtio_serial_port_type_info = {
+     .class_init = virtio_serial_port_class_init,
+ };
+ 
+-static int virtio_serial_device_exit(DeviceState *dev)
++static void virtio_serial_device_exit(VirtIODevice *vdev)
+ {
+-    VirtIOSerial *vser = VIRTIO_SERIAL(dev);
+-    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
++    VirtIOSerial *vser = VIRTIO_SERIAL(vdev);
+ 
+-    unregister_savevm(dev, "virtio-console", vser);
++    unregister_savevm(DEVICE(vdev), "virtio-console", vser);
+ 
+     g_free(vser->ivqs);
+     g_free(vser->ovqs);
+@@ -1004,7 +1003,6 @@ static int virtio_serial_device_exit(DeviceState *dev)
+         g_free(vser->post_load);
+     }
+     virtio_cleanup(vdev);
+-    return 0;
+ }
+ 
+ static Property virtio_serial_properties[] = {
+@@ -1016,10 +1014,10 @@ static void virtio_serial_class_init(ObjectClass *klass, void *data)
+ {
+     DeviceClass *dc = DEVICE_CLASS(klass);
+     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+-    dc->exit = virtio_serial_device_exit;
+     dc->props = virtio_serial_properties;
+     set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
+     vdc->init = virtio_serial_device_init;
++    vdc->exit = virtio_serial_device_exit;
+     vdc->get_features = get_features;
+     vdc->get_config = get_config;
+     vdc->set_config = set_config;
diff --git a/0010-virtio-blk-switch-exit-callback-to-VirtioDeviceClass.patch b/0010-virtio-blk-switch-exit-callback-to-VirtioDeviceClass.patch
deleted file mode 100644
index 57c2353..0000000
--- a/0010-virtio-blk-switch-exit-callback-to-VirtioDeviceClass.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From aa75555e6fb5cae0e495cb5f7d9f3511ad5ac6ce Mon Sep 17 00:00:00 2001
-From: Paolo Bonzini <pbonzini@redhat.com>
-Date: Fri, 20 Sep 2013 16:57:54 +0200
-Subject: [PATCH] virtio-blk: switch exit callback to VirtioDeviceClass
-
-This ensures hot-unplug is handled properly by the proxy.
-
-Cc: qemu-stable@nongnu.org
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
----
- hw/block/virtio-blk.c | 10 ++++------
- 1 file changed, 4 insertions(+), 6 deletions(-)
-
-diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
-index 49a23c3..aa37cc9 100644
---- a/hw/block/virtio-blk.c
-+++ b/hw/block/virtio-blk.c
-@@ -729,20 +729,18 @@ static int virtio_blk_device_init(VirtIODevice *vdev)
-     return 0;
- }
- 
--static int virtio_blk_device_exit(DeviceState *dev)
-+static void virtio_blk_device_exit(VirtIODevice *vdev)
- {
--    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
--    VirtIOBlock *s = VIRTIO_BLK(dev);
-+    VirtIOBlock *s = VIRTIO_BLK(vdev);
- #ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
-     remove_migration_state_change_notifier(&s->migration_state_notifier);
-     virtio_blk_data_plane_destroy(s->dataplane);
-     s->dataplane = NULL;
- #endif
-     qemu_del_vm_change_state_handler(s->change);
--    unregister_savevm(dev, "virtio-blk", s);
-+    unregister_savevm(DEVICE(vdev), "virtio-blk", s);
-     blockdev_mark_auto_del(s->bs);
-     virtio_cleanup(vdev);
--    return 0;
- }
- 
- static Property virtio_blk_properties[] = {
-@@ -754,10 +752,10 @@ static void virtio_blk_class_init(ObjectClass *klass, void *data)
- {
-     DeviceClass *dc = DEVICE_CLASS(klass);
-     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
--    dc->exit = virtio_blk_device_exit;
-     dc->props = virtio_blk_properties;
-     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
-     vdc->init = virtio_blk_device_init;
-+    vdc->exit = virtio_blk_device_exit;
-     vdc->get_config = virtio_blk_update_config;
-     vdc->set_config = virtio_blk_set_config;
-     vdc->get_features = virtio_blk_get_features;
diff --git a/0010-virtio-net-switch-exit-callback-to-VirtioDeviceClass.patch b/0010-virtio-net-switch-exit-callback-to-VirtioDeviceClass.patch
new file mode 100644
index 0000000..41b4eec
--- /dev/null
+++ b/0010-virtio-net-switch-exit-callback-to-VirtioDeviceClass.patch
@@ -0,0 +1,58 @@
+From 8ed30b7ae128c31617c96128d9aa126332c7afaa Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Fri, 20 Sep 2013 16:57:56 +0200
+Subject: [PATCH] virtio-net: switch exit callback to VirtioDeviceClass
+
+This ensures hot-unplug is handled properly by the proxy.
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+---
+ hw/net/virtio-net.c | 11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
+
+diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
+index b75c753..93a81eb 100644
+--- a/hw/net/virtio-net.c
++++ b/hw/net/virtio-net.c
+@@ -1570,16 +1570,15 @@ static int virtio_net_device_init(VirtIODevice *vdev)
+     return 0;
+ }
+ 
+-static int virtio_net_device_exit(DeviceState *qdev)
++static void virtio_net_device_exit(VirtIODevice *vdev)
+ {
+-    VirtIONet *n = VIRTIO_NET(qdev);
+-    VirtIODevice *vdev = VIRTIO_DEVICE(qdev);
++    VirtIONet *n = VIRTIO_NET(vdev);
+     int i;
+ 
+     /* This will stop vhost backend if appropriate. */
+     virtio_net_set_status(vdev, 0);
+ 
+-    unregister_savevm(qdev, "virtio-net", n);
++    unregister_savevm(DEVICE(vdev), "virtio-net", n);
+ 
+     if (n->netclient_name) {
+         g_free(n->netclient_name);
+@@ -1610,8 +1609,6 @@ static int virtio_net_device_exit(DeviceState *qdev)
+     g_free(n->vqs);
+     qemu_del_nic(n->nic);
+     virtio_cleanup(vdev);
+-
+-    return 0;
+ }
+ 
+ static void virtio_net_instance_init(Object *obj)
+@@ -1638,10 +1635,10 @@ static void virtio_net_class_init(ObjectClass *klass, void *data)
+ {
+     DeviceClass *dc = DEVICE_CLASS(klass);
+     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+-    dc->exit = virtio_net_device_exit;
+     dc->props = virtio_net_properties;
+     set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
+     vdc->init = virtio_net_device_init;
++    vdc->exit = virtio_net_device_exit;
+     vdc->get_config = virtio_net_get_config;
+     vdc->set_config = virtio_net_set_config;
+     vdc->get_features = virtio_net_get_features;
diff --git a/0011-virtio-scsi-switch-exit-callback-to-VirtioDeviceClas.patch b/0011-virtio-scsi-switch-exit-callback-to-VirtioDeviceClas.patch
new file mode 100644
index 0000000..7eac763
--- /dev/null
+++ b/0011-virtio-scsi-switch-exit-callback-to-VirtioDeviceClas.patch
@@ -0,0 +1,112 @@
+From 78ad270fe43666fb11ba1352f591a7f217dd87b7 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Fri, 20 Sep 2013 16:57:57 +0200
+Subject: [PATCH] virtio-scsi: switch exit callback to VirtioDeviceClass
+
+This ensures hot-unplug is handled properly by the proxy.
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+---
+ hw/scsi/vhost-scsi.c            | 11 +++++------
+ hw/scsi/virtio-scsi.c           | 15 +++++++--------
+ include/hw/virtio/virtio-scsi.h |  2 +-
+ 3 files changed, 13 insertions(+), 15 deletions(-)
+
+diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c
+index 9e770fb..5e3cc61 100644
+--- a/hw/scsi/vhost-scsi.c
++++ b/hw/scsi/vhost-scsi.c
+@@ -240,11 +240,10 @@ static int vhost_scsi_init(VirtIODevice *vdev)
+     return 0;
+ }
+ 
+-static int vhost_scsi_exit(DeviceState *qdev)
++static void vhost_scsi_exit(VirtIODevice *vdev)
+ {
+-    VirtIODevice *vdev = VIRTIO_DEVICE(qdev);
+-    VHostSCSI *s = VHOST_SCSI(qdev);
+-    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(qdev);
++    VHostSCSI *s = VHOST_SCSI(vdev);
++    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev);
+ 
+     migrate_del_blocker(s->migration_blocker);
+     error_free(s->migration_blocker);
+@@ -253,7 +252,7 @@ static int vhost_scsi_exit(DeviceState *qdev)
+     vhost_scsi_set_status(vdev, 0);
+ 
+     g_free(s->dev.vqs);
+-    return virtio_scsi_common_exit(vs);
++    virtio_scsi_common_exit(vs);
+ }
+ 
+ static Property vhost_scsi_properties[] = {
+@@ -265,10 +264,10 @@ static void vhost_scsi_class_init(ObjectClass *klass, void *data)
+ {
+     DeviceClass *dc = DEVICE_CLASS(klass);
+     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+-    dc->exit = vhost_scsi_exit;
+     dc->props = vhost_scsi_properties;
+     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
+     vdc->init = vhost_scsi_init;
++    vdc->exit = vhost_scsi_exit;
+     vdc->get_features = vhost_scsi_get_features;
+     vdc->set_config = vhost_scsi_set_config;
+     vdc->set_status = vhost_scsi_set_status;
+diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
+index 26d95a1..83344ea 100644
+--- a/hw/scsi/virtio-scsi.c
++++ b/hw/scsi/virtio-scsi.c
+@@ -644,22 +644,21 @@ static int virtio_scsi_device_init(VirtIODevice *vdev)
+     return 0;
+ }
+ 
+-int virtio_scsi_common_exit(VirtIOSCSICommon *vs)
++void virtio_scsi_common_exit(VirtIOSCSICommon *vs)
+ {
+     VirtIODevice *vdev = VIRTIO_DEVICE(vs);
+ 
+     g_free(vs->cmd_vqs);
+     virtio_cleanup(vdev);
+-    return 0;
+ }
+ 
+-static int virtio_scsi_device_exit(DeviceState *qdev)
++static void virtio_scsi_device_exit(VirtIODevice *vdev)
+ {
+-    VirtIOSCSI *s = VIRTIO_SCSI(qdev);
+-    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(qdev);
++    VirtIOSCSI *s = VIRTIO_SCSI(vdev);
++    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev);
+ 
+-    unregister_savevm(qdev, "virtio-scsi", s);
+-    return virtio_scsi_common_exit(vs);
++    unregister_savevm(DEVICE(vdev), "virtio-scsi", s);
++    virtio_scsi_common_exit(vs);
+ }
+ 
+ static Property virtio_scsi_properties[] = {
+@@ -680,10 +679,10 @@ static void virtio_scsi_class_init(ObjectClass *klass, void *data)
+ {
+     DeviceClass *dc = DEVICE_CLASS(klass);
+     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+-    dc->exit = virtio_scsi_device_exit;
+     dc->props = virtio_scsi_properties;
+     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
+     vdc->init = virtio_scsi_device_init;
++    vdc->exit = virtio_scsi_device_exit;
+     vdc->set_config = virtio_scsi_set_config;
+     vdc->get_features = virtio_scsi_get_features;
+     vdc->reset = virtio_scsi_reset;
+diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h
+index 9a98540..206c61d 100644
+--- a/include/hw/virtio/virtio-scsi.h
++++ b/include/hw/virtio/virtio-scsi.h
+@@ -187,6 +187,6 @@ typedef struct {
+                                             VIRTIO_SCSI_F_CHANGE, true)
+ 
+ int virtio_scsi_common_init(VirtIOSCSICommon *vs);
+-int virtio_scsi_common_exit(VirtIOSCSICommon *vs);
++void virtio_scsi_common_exit(VirtIOSCSICommon *vs);
+ 
+ #endif /* _QEMU_VIRTIO_SCSI_H */
diff --git a/0011-virtio-serial-switch-exit-callback-to-VirtioDeviceCl.patch b/0011-virtio-serial-switch-exit-callback-to-VirtioDeviceCl.patch
deleted file mode 100644
index 86e48e4..0000000
--- a/0011-virtio-serial-switch-exit-callback-to-VirtioDeviceCl.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 811b51426d9e7819e6498d4dad0d6ac744a8e5d0 Mon Sep 17 00:00:00 2001
-From: Paolo Bonzini <pbonzini@redhat.com>
-Date: Fri, 20 Sep 2013 16:57:55 +0200
-Subject: [PATCH] virtio-serial: switch exit callback to VirtioDeviceClass
-
-This ensures hot-unplug is handled properly by the proxy.
-
-Cc: qemu-stable@nongnu.org
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
----
- hw/char/virtio-serial-bus.c | 10 ++++------
- 1 file changed, 4 insertions(+), 6 deletions(-)
-
-diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
-index da417c7..57dd070 100644
---- a/hw/char/virtio-serial-bus.c
-+++ b/hw/char/virtio-serial-bus.c
-@@ -987,12 +987,11 @@ static const TypeInfo virtio_serial_port_type_info = {
-     .class_init = virtio_serial_port_class_init,
- };
- 
--static int virtio_serial_device_exit(DeviceState *dev)
-+static void virtio_serial_device_exit(VirtIODevice *vdev)
- {
--    VirtIOSerial *vser = VIRTIO_SERIAL(dev);
--    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
-+    VirtIOSerial *vser = VIRTIO_SERIAL(vdev);
- 
--    unregister_savevm(dev, "virtio-console", vser);
-+    unregister_savevm(DEVICE(vdev), "virtio-console", vser);
- 
-     g_free(vser->ivqs);
-     g_free(vser->ovqs);
-@@ -1004,7 +1003,6 @@ static int virtio_serial_device_exit(DeviceState *dev)
-         g_free(vser->post_load);
-     }
-     virtio_cleanup(vdev);
--    return 0;
- }
- 
- static Property virtio_serial_properties[] = {
-@@ -1016,10 +1014,10 @@ static void virtio_serial_class_init(ObjectClass *klass, void *data)
- {
-     DeviceClass *dc = DEVICE_CLASS(klass);
-     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
--    dc->exit = virtio_serial_device_exit;
-     dc->props = virtio_serial_properties;
-     set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
-     vdc->init = virtio_serial_device_init;
-+    vdc->exit = virtio_serial_device_exit;
-     vdc->get_features = get_features;
-     vdc->get_config = get_config;
-     vdc->set_config = set_config;
diff --git a/0012-virtio-balloon-switch-exit-callback-to-VirtioDeviceC.patch b/0012-virtio-balloon-switch-exit-callback-to-VirtioDeviceC.patch
new file mode 100644
index 0000000..55019b0
--- /dev/null
+++ b/0012-virtio-balloon-switch-exit-callback-to-VirtioDeviceC.patch
@@ -0,0 +1,49 @@
+From 6b83317ba5edf378a1d5d4ccf1af7cc2a521f6ca Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Fri, 20 Sep 2013 16:57:58 +0200
+Subject: [PATCH] virtio-balloon: switch exit callback to VirtioDeviceClass
+
+This ensures hot-unplug is handled properly by the proxy.
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+---
+ hw/virtio/virtio-balloon.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
+index 9504877..d7a392d 100644
+--- a/hw/virtio/virtio-balloon.c
++++ b/hw/virtio/virtio-balloon.c
+@@ -370,16 +370,14 @@ static int virtio_balloon_device_init(VirtIODevice *vdev)
+     return 0;
+ }
+ 
+-static int virtio_balloon_device_exit(DeviceState *qdev)
++static void virtio_balloon_device_exit(VirtIODevice *vdev)
+ {
+-    VirtIOBalloon *s = VIRTIO_BALLOON(qdev);
+-    VirtIODevice *vdev = VIRTIO_DEVICE(qdev);
++    VirtIOBalloon *s = VIRTIO_BALLOON(vdev);
+ 
+     balloon_stats_destroy_timer(s);
+     qemu_remove_balloon_handler(s);
+-    unregister_savevm(qdev, "virtio-balloon", s);
++    unregister_savevm(DEVICE(vdev), "virtio-balloon", s);
+     virtio_cleanup(vdev);
+-    return 0;
+ }
+ 
+ static Property virtio_balloon_properties[] = {
+@@ -390,10 +388,10 @@ static void virtio_balloon_class_init(ObjectClass *klass, void *data)
+ {
+     DeviceClass *dc = DEVICE_CLASS(klass);
+     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+-    dc->exit = virtio_balloon_device_exit;
+     dc->props = virtio_balloon_properties;
+     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+     vdc->init = virtio_balloon_device_init;
++    vdc->exit = virtio_balloon_device_exit;
+     vdc->get_config = virtio_balloon_get_config;
+     vdc->set_config = virtio_balloon_set_config;
+     vdc->get_features = virtio_balloon_get_features;
diff --git a/0012-virtio-net-switch-exit-callback-to-VirtioDeviceClass.patch b/0012-virtio-net-switch-exit-callback-to-VirtioDeviceClass.patch
deleted file mode 100644
index 4bd6ede..0000000
--- a/0012-virtio-net-switch-exit-callback-to-VirtioDeviceClass.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From 1582699fb9f748f9f91b015ef311f93bf5a95f5d Mon Sep 17 00:00:00 2001
-From: Paolo Bonzini <pbonzini@redhat.com>
-Date: Fri, 20 Sep 2013 16:57:56 +0200
-Subject: [PATCH] virtio-net: switch exit callback to VirtioDeviceClass
-
-This ensures hot-unplug is handled properly by the proxy.
-
-Cc: qemu-stable@nongnu.org
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
----
- hw/net/virtio-net.c | 11 ++++-------
- 1 file changed, 4 insertions(+), 7 deletions(-)
-
-diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
-index aa1880c..46a4d8c 100644
---- a/hw/net/virtio-net.c
-+++ b/hw/net/virtio-net.c
-@@ -1568,16 +1568,15 @@ static int virtio_net_device_init(VirtIODevice *vdev)
-     return 0;
- }
- 
--static int virtio_net_device_exit(DeviceState *qdev)
-+static void virtio_net_device_exit(VirtIODevice *vdev)
- {
--    VirtIONet *n = VIRTIO_NET(qdev);
--    VirtIODevice *vdev = VIRTIO_DEVICE(qdev);
-+    VirtIONet *n = VIRTIO_NET(vdev);
-     int i;
- 
-     /* This will stop vhost backend if appropriate. */
-     virtio_net_set_status(vdev, 0);
- 
--    unregister_savevm(qdev, "virtio-net", n);
-+    unregister_savevm(DEVICE(vdev), "virtio-net", n);
- 
-     if (n->netclient_name) {
-         g_free(n->netclient_name);
-@@ -1608,8 +1607,6 @@ static int virtio_net_device_exit(DeviceState *qdev)
-     g_free(n->vqs);
-     qemu_del_nic(n->nic);
-     virtio_cleanup(vdev);
--
--    return 0;
- }
- 
- static void virtio_net_instance_init(Object *obj)
-@@ -1636,10 +1633,10 @@ static void virtio_net_class_init(ObjectClass *klass, void *data)
- {
-     DeviceClass *dc = DEVICE_CLASS(klass);
-     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
--    dc->exit = virtio_net_device_exit;
-     dc->props = virtio_net_properties;
-     set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
-     vdc->init = virtio_net_device_init;
-+    vdc->exit = virtio_net_device_exit;
-     vdc->get_config = virtio_net_get_config;
-     vdc->set_config = virtio_net_set_config;
-     vdc->get_features = virtio_net_get_features;
diff --git a/0013-virtio-rng-switch-exit-callback-to-VirtioDeviceClass.patch b/0013-virtio-rng-switch-exit-callback-to-VirtioDeviceClass.patch
new file mode 100644
index 0000000..b870c03
--- /dev/null
+++ b/0013-virtio-rng-switch-exit-callback-to-VirtioDeviceClass.patch
@@ -0,0 +1,49 @@
+From 8095a86fea23b06cd6bac2e3d054e1df8b1558c6 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Fri, 20 Sep 2013 16:57:59 +0200
+Subject: [PATCH] virtio-rng: switch exit callback to VirtioDeviceClass
+
+This ensures hot-unplug is handled properly by the proxy.
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+---
+ hw/virtio/virtio-rng.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c
+index b22ccf1..42ca568 100644
+--- a/hw/virtio/virtio-rng.c
++++ b/hw/virtio/virtio-rng.c
+@@ -190,16 +190,14 @@ static int virtio_rng_device_init(VirtIODevice *vdev)
+     return 0;
+ }
+ 
+-static int virtio_rng_device_exit(DeviceState *qdev)
++static void virtio_rng_device_exit(VirtIODevice *vdev)
+ {
+-    VirtIORNG *vrng = VIRTIO_RNG(qdev);
+-    VirtIODevice *vdev = VIRTIO_DEVICE(qdev);
++    VirtIORNG *vrng = VIRTIO_RNG(vdev);
+ 
+     timer_del(vrng->rate_limit_timer);
+     timer_free(vrng->rate_limit_timer);
+-    unregister_savevm(qdev, "virtio-rng", vrng);
++    unregister_savevm(DEVICE(vdev), "virtio-rng", vrng);
+     virtio_cleanup(vdev);
+-    return 0;
+ }
+ 
+ static Property virtio_rng_properties[] = {
+@@ -211,10 +209,10 @@ static void virtio_rng_class_init(ObjectClass *klass, void *data)
+ {
+     DeviceClass *dc = DEVICE_CLASS(klass);
+     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+-    dc->exit = virtio_rng_device_exit;
+     dc->props = virtio_rng_properties;
+     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+     vdc->init = virtio_rng_device_init;
++    vdc->exit = virtio_rng_device_exit;
+     vdc->get_features = get_features;
+ }
+ 
diff --git a/0013-virtio-scsi-switch-exit-callback-to-VirtioDeviceClas.patch b/0013-virtio-scsi-switch-exit-callback-to-VirtioDeviceClas.patch
deleted file mode 100644
index e654a87..0000000
--- a/0013-virtio-scsi-switch-exit-callback-to-VirtioDeviceClas.patch
+++ /dev/null
@@ -1,112 +0,0 @@
-From df750f462929ba85a61dbdd6a4020cb4b2ee68d0 Mon Sep 17 00:00:00 2001
-From: Paolo Bonzini <pbonzini@redhat.com>
-Date: Fri, 20 Sep 2013 16:57:57 +0200
-Subject: [PATCH] virtio-scsi: switch exit callback to VirtioDeviceClass
-
-This ensures hot-unplug is handled properly by the proxy.
-
-Cc: qemu-stable@nongnu.org
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
----
- hw/scsi/vhost-scsi.c            | 11 +++++------
- hw/scsi/virtio-scsi.c           | 15 +++++++--------
- include/hw/virtio/virtio-scsi.h |  2 +-
- 3 files changed, 13 insertions(+), 15 deletions(-)
-
-diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c
-index 9e770fb..5e3cc61 100644
---- a/hw/scsi/vhost-scsi.c
-+++ b/hw/scsi/vhost-scsi.c
-@@ -240,11 +240,10 @@ static int vhost_scsi_init(VirtIODevice *vdev)
-     return 0;
- }
- 
--static int vhost_scsi_exit(DeviceState *qdev)
-+static void vhost_scsi_exit(VirtIODevice *vdev)
- {
--    VirtIODevice *vdev = VIRTIO_DEVICE(qdev);
--    VHostSCSI *s = VHOST_SCSI(qdev);
--    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(qdev);
-+    VHostSCSI *s = VHOST_SCSI(vdev);
-+    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev);
- 
-     migrate_del_blocker(s->migration_blocker);
-     error_free(s->migration_blocker);
-@@ -253,7 +252,7 @@ static int vhost_scsi_exit(DeviceState *qdev)
-     vhost_scsi_set_status(vdev, 0);
- 
-     g_free(s->dev.vqs);
--    return virtio_scsi_common_exit(vs);
-+    virtio_scsi_common_exit(vs);
- }
- 
- static Property vhost_scsi_properties[] = {
-@@ -265,10 +264,10 @@ static void vhost_scsi_class_init(ObjectClass *klass, void *data)
- {
-     DeviceClass *dc = DEVICE_CLASS(klass);
-     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
--    dc->exit = vhost_scsi_exit;
-     dc->props = vhost_scsi_properties;
-     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
-     vdc->init = vhost_scsi_init;
-+    vdc->exit = vhost_scsi_exit;
-     vdc->get_features = vhost_scsi_get_features;
-     vdc->set_config = vhost_scsi_set_config;
-     vdc->set_status = vhost_scsi_set_status;
-diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
-index 05da56b..5545993 100644
---- a/hw/scsi/virtio-scsi.c
-+++ b/hw/scsi/virtio-scsi.c
-@@ -643,22 +643,21 @@ static int virtio_scsi_device_init(VirtIODevice *vdev)
-     return 0;
- }
- 
--int virtio_scsi_common_exit(VirtIOSCSICommon *vs)
-+void virtio_scsi_common_exit(VirtIOSCSICommon *vs)
- {
-     VirtIODevice *vdev = VIRTIO_DEVICE(vs);
- 
-     g_free(vs->cmd_vqs);
-     virtio_cleanup(vdev);
--    return 0;
- }
- 
--static int virtio_scsi_device_exit(DeviceState *qdev)
-+static void virtio_scsi_device_exit(VirtIODevice *vdev)
- {
--    VirtIOSCSI *s = VIRTIO_SCSI(qdev);
--    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(qdev);
-+    VirtIOSCSI *s = VIRTIO_SCSI(vdev);
-+    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev);
- 
--    unregister_savevm(qdev, "virtio-scsi", s);
--    return virtio_scsi_common_exit(vs);
-+    unregister_savevm(DEVICE(vdev), "virtio-scsi", s);
-+    virtio_scsi_common_exit(vs);
- }
- 
- static Property virtio_scsi_properties[] = {
-@@ -679,10 +678,10 @@ static void virtio_scsi_class_init(ObjectClass *klass, void *data)
- {
-     DeviceClass *dc = DEVICE_CLASS(klass);
-     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
--    dc->exit = virtio_scsi_device_exit;
-     dc->props = virtio_scsi_properties;
-     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
-     vdc->init = virtio_scsi_device_init;
-+    vdc->exit = virtio_scsi_device_exit;
-     vdc->set_config = virtio_scsi_set_config;
-     vdc->get_features = virtio_scsi_get_features;
-     vdc->reset = virtio_scsi_reset;
-diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h
-index 9a98540..206c61d 100644
---- a/include/hw/virtio/virtio-scsi.h
-+++ b/include/hw/virtio/virtio-scsi.h
-@@ -187,6 +187,6 @@ typedef struct {
-                                             VIRTIO_SCSI_F_CHANGE, true)
- 
- int virtio_scsi_common_init(VirtIOSCSICommon *vs);
--int virtio_scsi_common_exit(VirtIOSCSICommon *vs);
-+void virtio_scsi_common_exit(VirtIOSCSICommon *vs);
- 
- #endif /* _QEMU_VIRTIO_SCSI_H */
diff --git a/0014-virtio-balloon-switch-exit-callback-to-VirtioDeviceC.patch b/0014-virtio-balloon-switch-exit-callback-to-VirtioDeviceC.patch
deleted file mode 100644
index 5c921d1..0000000
--- a/0014-virtio-balloon-switch-exit-callback-to-VirtioDeviceC.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From d42ac36363ef9e3d3963c2c31fa7122492dbaf0e Mon Sep 17 00:00:00 2001
-From: Paolo Bonzini <pbonzini@redhat.com>
-Date: Fri, 20 Sep 2013 16:57:58 +0200
-Subject: [PATCH] virtio-balloon: switch exit callback to VirtioDeviceClass
-
-This ensures hot-unplug is handled properly by the proxy.
-
-Cc: qemu-stable@nongnu.org
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
----
- hw/virtio/virtio-balloon.c | 10 ++++------
- 1 file changed, 4 insertions(+), 6 deletions(-)
-
-diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
-index aac7f83..c23facb 100644
---- a/hw/virtio/virtio-balloon.c
-+++ b/hw/virtio/virtio-balloon.c
-@@ -370,16 +370,14 @@ static int virtio_balloon_device_init(VirtIODevice *vdev)
-     return 0;
- }
- 
--static int virtio_balloon_device_exit(DeviceState *qdev)
-+static void virtio_balloon_device_exit(VirtIODevice *vdev)
- {
--    VirtIOBalloon *s = VIRTIO_BALLOON(qdev);
--    VirtIODevice *vdev = VIRTIO_DEVICE(qdev);
-+    VirtIOBalloon *s = VIRTIO_BALLOON(vdev);
- 
-     balloon_stats_destroy_timer(s);
-     qemu_remove_balloon_handler(s);
--    unregister_savevm(qdev, "virtio-balloon", s);
-+    unregister_savevm(DEVICE(vdev), "virtio-balloon", s);
-     virtio_cleanup(vdev);
--    return 0;
- }
- 
- static Property virtio_balloon_properties[] = {
-@@ -390,10 +388,10 @@ static void virtio_balloon_class_init(ObjectClass *klass, void *data)
- {
-     DeviceClass *dc = DEVICE_CLASS(klass);
-     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
--    dc->exit = virtio_balloon_device_exit;
-     dc->props = virtio_balloon_properties;
-     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
-     vdc->init = virtio_balloon_device_init;
-+    vdc->exit = virtio_balloon_device_exit;
-     vdc->get_config = virtio_balloon_get_config;
-     vdc->set_config = virtio_balloon_set_config;
-     vdc->get_features = virtio_balloon_get_features;
diff --git a/0014-virtio-pci-add-device_unplugged-callback.patch b/0014-virtio-pci-add-device_unplugged-callback.patch
new file mode 100644
index 0000000..17c8ae6
--- /dev/null
+++ b/0014-virtio-pci-add-device_unplugged-callback.patch
@@ -0,0 +1,59 @@
+From 91ff7bf3e20ced8742319d77bd5f2b9929bc3c24 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Fri, 20 Sep 2013 16:58:00 +0200
+Subject: [PATCH] virtio-pci: add device_unplugged callback
+
+This fixes a crash in hot-unplug of virtio-pci devices behind a PCIe
+switch.  The crash happens because the ioeventfd is still set whent the
+child is destroyed (destruction happens in postorder).  Then the proxy
+tries to unset to ioeventfd, but the virtqueue structure that holds the
+EventNotifier has been trashed in the meanwhile.  kvm_set_ioeventfd_pio
+does not expect failure and aborts.
+
+The fix is simply to move parts of uninitialization to a new
+device_unplugged callback, which is called before the child is destroyed.
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+---
+ hw/virtio/virtio-pci.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
+index be18e92..1a363ca 100644
+--- a/hw/virtio/virtio-pci.c
++++ b/hw/virtio/virtio-pci.c
+@@ -1001,6 +1001,15 @@ static void virtio_pci_device_plugged(DeviceState *d)
+                                                       proxy->host_features);
+ }
+ 
++static void virtio_pci_device_unplugged(DeviceState *d)
++{
++    PCIDevice *pci_dev = PCI_DEVICE(d);
++    VirtIOPCIProxy *proxy = VIRTIO_PCI(d);
++
++    virtio_pci_stop_ioeventfd(proxy);
++    msix_uninit_exclusive_bar(pci_dev);
++}
++
+ static int virtio_pci_init(PCIDevice *pci_dev)
+ {
+     VirtIOPCIProxy *dev = VIRTIO_PCI(pci_dev);
+@@ -1015,9 +1024,7 @@ static int virtio_pci_init(PCIDevice *pci_dev)
+ static void virtio_pci_exit(PCIDevice *pci_dev)
+ {
+     VirtIOPCIProxy *proxy = VIRTIO_PCI(pci_dev);
+-    virtio_pci_stop_ioeventfd(proxy);
+     memory_region_destroy(&proxy->bar);
+-    msix_uninit_exclusive_bar(pci_dev);
+ }
+ 
+ static void virtio_pci_reset(DeviceState *qdev)
+@@ -1552,6 +1559,7 @@ static void virtio_pci_bus_class_init(ObjectClass *klass, void *data)
+     k->set_guest_notifiers = virtio_pci_set_guest_notifiers;
+     k->vmstate_change = virtio_pci_vmstate_change;
+     k->device_plugged = virtio_pci_device_plugged;
++    k->device_unplugged = virtio_pci_device_unplugged;
+ }
+ 
+ static const TypeInfo virtio_pci_bus_info = {
diff --git a/0015-virtio-rng-switch-exit-callback-to-VirtioDeviceClass.patch b/0015-virtio-rng-switch-exit-callback-to-VirtioDeviceClass.patch
deleted file mode 100644
index 6c54e1b..0000000
--- a/0015-virtio-rng-switch-exit-callback-to-VirtioDeviceClass.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 2bb10b85ffa655f91a4777da4f7a5534ee4c266c Mon Sep 17 00:00:00 2001
-From: Paolo Bonzini <pbonzini@redhat.com>
-Date: Fri, 20 Sep 2013 16:57:59 +0200
-Subject: [PATCH] virtio-rng: switch exit callback to VirtioDeviceClass
-
-This ensures hot-unplug is handled properly by the proxy.
-
-Cc: qemu-stable@nongnu.org
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
----
- hw/virtio/virtio-rng.c | 10 ++++------
- 1 file changed, 4 insertions(+), 6 deletions(-)
-
-diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c
-index bac8421..6895146 100644
---- a/hw/virtio/virtio-rng.c
-+++ b/hw/virtio/virtio-rng.c
-@@ -184,16 +184,14 @@ static int virtio_rng_device_init(VirtIODevice *vdev)
-     return 0;
- }
- 
--static int virtio_rng_device_exit(DeviceState *qdev)
-+static void virtio_rng_device_exit(VirtIODevice *vdev)
- {
--    VirtIORNG *vrng = VIRTIO_RNG(qdev);
--    VirtIODevice *vdev = VIRTIO_DEVICE(qdev);
-+    VirtIORNG *vrng = VIRTIO_RNG(vdev);
- 
-     qemu_del_timer(vrng->rate_limit_timer);
-     qemu_free_timer(vrng->rate_limit_timer);
--    unregister_savevm(qdev, "virtio-rng", vrng);
-+    unregister_savevm(DEVICE(vdev), "virtio-rng", vrng);
-     virtio_cleanup(vdev);
--    return 0;
- }
- 
- static Property virtio_rng_properties[] = {
-@@ -205,10 +203,10 @@ static void virtio_rng_class_init(ObjectClass *klass, void *data)
- {
-     DeviceClass *dc = DEVICE_CLASS(klass);
-     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
--    dc->exit = virtio_rng_device_exit;
-     dc->props = virtio_rng_properties;
-     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
-     vdc->init = virtio_rng_device_init;
-+    vdc->exit = virtio_rng_device_exit;
-     vdc->get_features = get_features;
- }
- 
diff --git a/0016-virtio-pci-add-device_unplugged-callback.patch b/0016-virtio-pci-add-device_unplugged-callback.patch
deleted file mode 100644
index e96fc3b..0000000
--- a/0016-virtio-pci-add-device_unplugged-callback.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From cb2282d55ee34d04a67d74111d69ab098f765680 Mon Sep 17 00:00:00 2001
-From: Paolo Bonzini <pbonzini@redhat.com>
-Date: Fri, 20 Sep 2013 16:58:00 +0200
-Subject: [PATCH] virtio-pci: add device_unplugged callback
-
-This fixes a crash in hot-unplug of virtio-pci devices behind a PCIe
-switch.  The crash happens because the ioeventfd is still set whent the
-child is destroyed (destruction happens in postorder).  Then the proxy
-tries to unset to ioeventfd, but the virtqueue structure that holds the
-EventNotifier has been trashed in the meanwhile.  kvm_set_ioeventfd_pio
-does not expect failure and aborts.
-
-The fix is simply to move parts of uninitialization to a new
-device_unplugged callback, which is called before the child is destroyed.
-
-Cc: qemu-stable@nongnu.org
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
----
- hw/virtio/virtio-pci.c | 12 ++++++++++--
- 1 file changed, 10 insertions(+), 2 deletions(-)
-
-diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
-index 6fd6d6d..242ec3e 100644
---- a/hw/virtio/virtio-pci.c
-+++ b/hw/virtio/virtio-pci.c
-@@ -1000,6 +1000,15 @@ static void virtio_pci_device_plugged(DeviceState *d)
-                                                       proxy->host_features);
- }
- 
-+static void virtio_pci_device_unplugged(DeviceState *d)
-+{
-+    PCIDevice *pci_dev = PCI_DEVICE(d);
-+    VirtIOPCIProxy *proxy = VIRTIO_PCI(d);
-+
-+    virtio_pci_stop_ioeventfd(proxy);
-+    msix_uninit_exclusive_bar(pci_dev);
-+}
-+
- static int virtio_pci_init(PCIDevice *pci_dev)
- {
-     VirtIOPCIProxy *dev = VIRTIO_PCI(pci_dev);
-@@ -1014,9 +1023,7 @@ static int virtio_pci_init(PCIDevice *pci_dev)
- static void virtio_pci_exit(PCIDevice *pci_dev)
- {
-     VirtIOPCIProxy *proxy = VIRTIO_PCI(pci_dev);
--    virtio_pci_stop_ioeventfd(proxy);
-     memory_region_destroy(&proxy->bar);
--    msix_uninit_exclusive_bar(pci_dev);
- }
- 
- static void virtio_pci_reset(DeviceState *qdev)
-@@ -1550,6 +1557,7 @@ static void virtio_pci_bus_class_init(ObjectClass *klass, void *data)
-     k->set_guest_notifiers = virtio_pci_set_guest_notifiers;
-     k->vmstate_change = virtio_pci_vmstate_change;
-     k->device_plugged = virtio_pci_device_plugged;
-+    k->device_unplugged = virtio_pci_device_unplugged;
- }
- 
- static const TypeInfo virtio_pci_bus_info = {
diff --git a/0101-qcow2-Pass-discard-type-to-qcow2_discard_clusters.patch b/0101-qcow2-Pass-discard-type-to-qcow2_discard_clusters.patch
deleted file mode 100644
index b31f925..0000000
--- a/0101-qcow2-Pass-discard-type-to-qcow2_discard_clusters.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-From 411a7e4ad457f7f3c9f1d02ef9f726ce13a35f08 Mon Sep 17 00:00:00 2001
-From: Kevin Wolf <kwolf@redhat.com>
-Date: Fri, 6 Sep 2013 12:32:25 +0200
-Subject: [PATCH] qcow2: Pass discard type to qcow2_discard_clusters()
-
-The function will be used internally instead of only being called for
-guest discard requests.
-
-Signed-off-by: Kevin Wolf <kwolf@redhat.com>
----
- block/qcow2-cluster.c | 8 ++++----
- block/qcow2.c         | 2 +-
- block/qcow2.h         | 2 +-
- 3 files changed, 6 insertions(+), 6 deletions(-)
-
-diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
-index cca76d4..8c3185d 100644
---- a/block/qcow2-cluster.c
-+++ b/block/qcow2-cluster.c
-@@ -1317,7 +1317,7 @@ int qcow2_decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset)
-  * clusters.
-  */
- static int discard_single_l2(BlockDriverState *bs, uint64_t offset,
--    unsigned int nb_clusters)
-+    unsigned int nb_clusters, enum qcow2_discard_type type)
- {
-     BDRVQcowState *s = bs->opaque;
-     uint64_t *l2_table;
-@@ -1346,7 +1346,7 @@ static int discard_single_l2(BlockDriverState *bs, uint64_t offset,
-         l2_table[l2_index + i] = cpu_to_be64(0);
- 
-         /* Then decrease the refcount */
--        qcow2_free_any_clusters(bs, old_offset, 1, QCOW2_DISCARD_REQUEST);
-+        qcow2_free_any_clusters(bs, old_offset, 1, type);
-     }
- 
-     ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
-@@ -1358,7 +1358,7 @@ static int discard_single_l2(BlockDriverState *bs, uint64_t offset,
- }
- 
- int qcow2_discard_clusters(BlockDriverState *bs, uint64_t offset,
--    int nb_sectors)
-+    int nb_sectors, enum qcow2_discard_type type)
- {
-     BDRVQcowState *s = bs->opaque;
-     uint64_t end_offset;
-@@ -1381,7 +1381,7 @@ int qcow2_discard_clusters(BlockDriverState *bs, uint64_t offset,
- 
-     /* Each L2 table is handled by its own loop iteration */
-     while (nb_clusters > 0) {
--        ret = discard_single_l2(bs, offset, nb_clusters);
-+        ret = discard_single_l2(bs, offset, nb_clusters, type);
-         if (ret < 0) {
-             goto fail;
-         }
-diff --git a/block/qcow2.c b/block/qcow2.c
-index 7f7282e..16e45a0 100644
---- a/block/qcow2.c
-+++ b/block/qcow2.c
-@@ -1506,7 +1506,7 @@ static coroutine_fn int qcow2_co_discard(BlockDriverState *bs,
- 
-     qemu_co_mutex_lock(&s->lock);
-     ret = qcow2_discard_clusters(bs, sector_num << BDRV_SECTOR_BITS,
--        nb_sectors);
-+        nb_sectors, QCOW2_DISCARD_REQUEST);
-     qemu_co_mutex_unlock(&s->lock);
-     return ret;
- }
-diff --git a/block/qcow2.h b/block/qcow2.h
-index dba9771..52cf193 100644
---- a/block/qcow2.h
-+++ b/block/qcow2.h
-@@ -405,7 +405,7 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
- 
- int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m);
- int qcow2_discard_clusters(BlockDriverState *bs, uint64_t offset,
--    int nb_sectors);
-+    int nb_sectors, enum qcow2_discard_type type);
- int qcow2_zero_clusters(BlockDriverState *bs, uint64_t offset, int nb_sectors);
- 
- /* qcow2-snapshot.c functions */
diff --git a/0102-qcow2-Discard-VM-state-in-active-L1-after-creating-s.patch b/0102-qcow2-Discard-VM-state-in-active-L1-after-creating-s.patch
deleted file mode 100644
index cb0e92c..0000000
--- a/0102-qcow2-Discard-VM-state-in-active-L1-after-creating-s.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From 16d78f7cd9e1455ebb0599706ba5badfa3ee4fdc Mon Sep 17 00:00:00 2001
-From: Kevin Wolf <kwolf@redhat.com>
-Date: Fri, 6 Sep 2013 12:32:26 +0200
-Subject: [PATCH] qcow2: Discard VM state in active L1 after creating snapshot
-
-During savevm, the VM state is written to the active L1 of the image and
-then a snapshot is taken. After that, the VM state isn't needed any more
-in the active L1 and should be discarded. This is implemented by this
-patch.
-
-The impact of not discarding the VM state is that a snapshot can never
-become smaller than any previous snapshot (because it would be padded
-with old VM state), and more importantly that future savevm operations
-cause unnecessary COWs (with associated flushes), which makes subsequent
-snapshots much slower.
-
-Signed-off-by: Kevin Wolf <kwolf@redhat.com>
----
- block/qcow2-snapshot.c | 7 +++++++
- block/qcow2.c          | 5 -----
- block/qcow2.h          | 5 +++++
- 3 files changed, 12 insertions(+), 5 deletions(-)
-
-diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
-index 0caac90..ae33b45 100644
---- a/block/qcow2-snapshot.c
-+++ b/block/qcow2-snapshot.c
-@@ -401,6 +401,13 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
- 
-     g_free(old_snapshot_list);
- 
-+    /* The VM state isn't needed any more in the active L1 table; in fact, it
-+     * hurts by causing expensive COW for the next snapshot. */
-+    qcow2_discard_clusters(bs, qcow2_vm_state_offset(s),
-+                           align_offset(sn->vm_state_size, s->cluster_size)
-+                                >> BDRV_SECTOR_BITS,
-+                           QCOW2_DISCARD_NEVER);
-+
- #ifdef DEBUG_ALLOC
-     {
-       BdrvCheckResult result = {0};
-diff --git a/block/qcow2.c b/block/qcow2.c
-index 16e45a0..f63c2cb 100644
---- a/block/qcow2.c
-+++ b/block/qcow2.c
-@@ -1666,11 +1666,6 @@ static coroutine_fn int qcow2_co_flush_to_os(BlockDriverState *bs)
-     return 0;
- }
- 
--static int64_t qcow2_vm_state_offset(BDRVQcowState *s)
--{
--	return (int64_t)s->l1_vm_state_index << (s->cluster_bits + s->l2_bits);
--}
--
- static int qcow2_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
- {
-     BDRVQcowState *s = bs->opaque;
-diff --git a/block/qcow2.h b/block/qcow2.h
-index 52cf193..da61d18 100644
---- a/block/qcow2.h
-+++ b/block/qcow2.h
-@@ -324,6 +324,11 @@ static inline int64_t align_offset(int64_t offset, int n)
-     return offset;
- }
- 
-+static inline int64_t qcow2_vm_state_offset(BDRVQcowState *s)
-+{
-+	return (int64_t)s->l1_vm_state_index << (s->cluster_bits + s->l2_bits);
-+}
-+
- static inline int qcow2_get_cluster_type(uint64_t l2_entry)
- {
-     if (l2_entry & QCOW_OFLAG_COMPRESSED) {
diff --git a/0103-hw-9pfs-Fix-errno-value-for-xattr-functions.patch b/0103-hw-9pfs-Fix-errno-value-for-xattr-functions.patch
deleted file mode 100644
index cd7b42f..0000000
--- a/0103-hw-9pfs-Fix-errno-value-for-xattr-functions.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From 6f7e1d2bddb5a0a1c65f6f02467460d6edbcc901 Mon Sep 17 00:00:00 2001
-From: "Daniel P. Berrange" <berrange@redhat.com>
-Date: Tue, 1 Oct 2013 12:28:17 +0100
-Subject: [PATCH] hw/9pfs: Fix errno value for xattr functions
-
-If there is no operation driver for the xattr type the
-functions return '-1' and set errno to '-EOPNOTSUPP'.
-When the calling code sets 'ret = -errno' this turns
-into a large positive number.
-
-In Linux 3.11, the kernel has switched to using 9p
-version 9p2000.L, instead of 9p2000.u, which enables
-support for xattr operations. This on its own is harmless,
-but for another change which makes it request the xattr
-with a name 'security.capability'.
-
-The result is that the guest sees a succesful return
-of 95 bytes of data, instead of a failure with errno
-set to 95. Since the kernel expects a maximum of 20
-bytes for an xattr return this gets translated to the
-unexpected errno ERANGE.
-
-This all means that when running a binary off a 9p fs
-in 3.11 kernels you get a fun result of:
-
-  # ./date
-  sh: ./date: Numerical result out of range
-
-The only workaround is to pass 'version=9p2000.u' when
-mounting the 9p fs in the guest, to disable all use of
-xattrs.
-
-Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
----
- hw/9pfs/virtio-9p-xattr.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/hw/9pfs/virtio-9p-xattr.c b/hw/9pfs/virtio-9p-xattr.c
-index 90ae565..3fae557 100644
---- a/hw/9pfs/virtio-9p-xattr.c
-+++ b/hw/9pfs/virtio-9p-xattr.c
-@@ -36,7 +36,7 @@ ssize_t v9fs_get_xattr(FsContext *ctx, const char *path,
-     if (xops) {
-         return xops->getxattr(ctx, path, name, value, size);
-     }
--    errno = -EOPNOTSUPP;
-+    errno = EOPNOTSUPP;
-     return -1;
- }
- 
-@@ -123,7 +123,7 @@ int v9fs_set_xattr(FsContext *ctx, const char *path, const char *name,
-     if (xops) {
-         return xops->setxattr(ctx, path, name, value, size, flags);
-     }
--    errno = -EOPNOTSUPP;
-+    errno = EOPNOTSUPP;
-     return -1;
- 
- }
-@@ -135,7 +135,7 @@ int v9fs_remove_xattr(FsContext *ctx,
-     if (xops) {
-         return xops->removexattr(ctx, path, name);
-     }
--    errno = -EOPNOTSUPP;
-+    errno = EOPNOTSUPP;
-     return -1;
- 
- }
diff --git a/0104-Fix-pc-migration-from-qemu-1.5.patch b/0104-Fix-pc-migration-from-qemu-1.5.patch
deleted file mode 100644
index 022b66c..0000000
--- a/0104-Fix-pc-migration-from-qemu-1.5.patch
+++ /dev/null
@@ -1,203 +0,0 @@
-From 042c76790b1168766332b1aafa4429c265d35ed0 Mon Sep 17 00:00:00 2001
-From: Cole Robinson <crobinso@redhat.com>
-Date: Mon, 7 Oct 2013 16:32:24 -0400
-Subject: [PATCH] Fix pc migration from qemu <= 1.5
-
-The following commit introduced a migration incompatibility:
-
-commit 568f0690fd9aa4d39d84b04c1a5dbb53a915c3fe
-Author: David Gibson <david@gibson.dropbear.id.au>
-Date:   Thu Jun 6 18:48:49 2013 +1000
-
-    pci: Replace pci_find_domain() with more general pci_root_bus_path()
-
-The issue is that i440fx savevm idstr went from 0000:00:00.0/I440FX to
-0000:00.0/I440FX. Unfortunately we are stuck with the breakage for
-1.6 machine types.
-
-Add a compat property to maintain the busted idstr for the 1.6 machine
-types, but revert to the old style format for 1.7+, and <= 1.5.
-
-Tested with migration from qemu 1.5, qemu 1.6, and qemu.git.
-
-Cc: qemu-stable@nongnu.org
-Signed-off-by: Cole Robinson <crobinso@redhat.com>
----
- hw/i386/pc_piix.c         | 11 +++++++++++
- hw/i386/pc_q35.c          | 11 +++++++++++
- hw/pci-host/piix.c        |  9 ++++++++-
- hw/pci-host/q35.c         | 10 ++++++++--
- include/hw/i386/pc.h      | 20 ++++++++++++++++++++
- include/hw/pci-host/q35.h |  1 +
- 6 files changed, 59 insertions(+), 3 deletions(-)
-
-diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
-index 2f2cb4d..10866f5 100644
---- a/hw/i386/pc_piix.c
-+++ b/hw/i386/pc_piix.c
-@@ -341,6 +341,13 @@ static void pc_xen_hvm_init(QEMUMachineInitArgs *args)
- }
- #endif
- 
-+#define PC_I440FX_MACHINE_OPTIONS \
-+    PC_DEFAULT_MACHINE_OPTIONS, \
-+    .desc = "Standard PC (i440FX + PIIX, 1996)", \
-+    .hot_add_cpu = pc_hot_add_cpu
-+
-+#define PC_I440FX_1_6_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS
-+
- static QEMUMachine pc_i440fx_machine_v1_6 = {
-     .name = "pc-i440fx-1.6",
-     .alias = "pc",
-@@ -349,6 +356,10 @@ static QEMUMachine pc_i440fx_machine_v1_6 = {
-     .hot_add_cpu = pc_hot_add_cpu,
-     .max_cpus = 255,
-     .is_default = 1,
-+    .compat_props = (GlobalProperty[]) {
-+        PC_COMPAT_1_6,
-+        { /* end of list */ }
-+    },
-     DEFAULT_MACHINE_OPTIONS,
- };
- 
-diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
-index dd13130..4998ed3 100644
---- a/hw/i386/pc_q35.c
-+++ b/hw/i386/pc_q35.c
-@@ -243,6 +243,13 @@ static void pc_q35_init_1_4(QEMUMachineInitArgs *args)
-     pc_q35_init(args);
- }
- 
-+#define PC_Q35_MACHINE_OPTIONS \
-+    PC_DEFAULT_MACHINE_OPTIONS, \
-+    .desc = "Standard PC (Q35 + ICH9, 2009)", \
-+    .hot_add_cpu = pc_hot_add_cpu
-+
-+#define PC_Q35_1_6_MACHINE_OPTIONS PC_Q35_MACHINE_OPTIONS
-+
- static QEMUMachine pc_q35_machine_v1_6 = {
-     .name = "pc-q35-1.6",
-     .alias = "q35",
-@@ -250,6 +257,10 @@ static QEMUMachine pc_q35_machine_v1_6 = {
-     .init = pc_q35_init_1_6,
-     .hot_add_cpu = pc_hot_add_cpu,
-     .max_cpus = 255,
-+    .compat_props = (GlobalProperty[]) {
-+        PC_COMPAT_1_6,
-+        { /* end of list */ }
-+    },
-     DEFAULT_MACHINE_OPTIONS,
- };
- 
-diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
-index 221d82b..967f949 100644
---- a/hw/pci-host/piix.c
-+++ b/hw/pci-host/piix.c
-@@ -48,6 +48,7 @@ typedef struct I440FXState {
-     PCIHostState parent_obj;
-     PcPciInfo pci_info;
-     uint64_t pci_hole64_size;
-+    uint32_t short_root_bus;
- } I440FXState;
- 
- #define PIIX_NUM_PIC_IRQS       16      /* i8259 * 2 */
-@@ -706,13 +707,19 @@ static const TypeInfo i440fx_info = {
- static const char *i440fx_pcihost_root_bus_path(PCIHostState *host_bridge,
-                                                 PCIBus *rootbus)
- {
-+    I440FXState *s = I440FX_PCI_HOST_BRIDGE(host_bridge);
-+
-     /* For backwards compat with old device paths */
--    return "0000";
-+    if (s->short_root_bus) {
-+        return "0000";
-+    }
-+    return "0000:00";
- }
- 
- static Property i440fx_props[] = {
-     DEFINE_PROP_SIZE(PCI_HOST_PROP_PCI_HOLE64_SIZE, I440FXState,
-                      pci_hole64_size, DEFAULT_PCI_HOLE64_SIZE),
-+    DEFINE_PROP_UINT32("short_root_bus", I440FXState, short_root_bus, 0),
-     DEFINE_PROP_END_OF_LIST(),
- };
- 
-diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
-index 4febd24..f762053 100644
---- a/hw/pci-host/q35.c
-+++ b/hw/pci-host/q35.c
-@@ -61,8 +61,13 @@ static void q35_host_realize(DeviceState *dev, Error **errp)
- static const char *q35_host_root_bus_path(PCIHostState *host_bridge,
-                                           PCIBus *rootbus)
- {
--    /* For backwards compat with old device paths */
--    return "0000";
-+    Q35PCIHost *s = Q35_HOST_DEVICE(host_bridge);
-+
-+     /* For backwards compat with old device paths */
-+    if (s->mch.short_root_bus) {
-+        return "0000";
-+    }
-+    return "0000:00";
- }
- 
- static void q35_host_get_pci_hole_start(Object *obj, Visitor *v,
-@@ -108,6 +113,7 @@ static Property mch_props[] = {
-                         MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT),
-     DEFINE_PROP_SIZE(PCI_HOST_PROP_PCI_HOLE64_SIZE, Q35PCIHost,
-                      mch.pci_hole64_size, DEFAULT_PCI_HOLE64_SIZE),
-+    DEFINE_PROP_UINT32("short_root_bus", Q35PCIHost, mch.short_root_bus, 0),
-     DEFINE_PROP_END_OF_LIST(),
- };
- 
-diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
-index 475ba9e..6e2b839 100644
---- a/include/hw/i386/pc.h
-+++ b/include/hw/i386/pc.h
-@@ -225,7 +225,19 @@ void pvpanic_init(ISABus *bus);
- 
- int e820_add_entry(uint64_t, uint64_t, uint32_t);
- 
-+#define PC_COMPAT_1_6 \
-+        {\
-+            .driver   = "i440FX-pcihost",\
-+            .property = "short_root_bus",\
-+            .value    = stringify(1),\
-+        },{\
-+            .driver   = "q35-pcihost",\
-+            .property = "short_root_bus",\
-+            .value    = stringify(1),\
-+        }
-+
- #define PC_COMPAT_1_5 \
-+        PC_COMPAT_1_6, \
-         {\
-             .driver   = "Conroe-" TYPE_X86_CPU,\
-             .property = "model",\
-@@ -258,6 +270,14 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t);
-             .driver = TYPE_X86_CPU,\
-             .property = "pmu",\
-             .value = "on",\
-+        },{\
-+            .driver   = "i440FX-pcihost",\
-+            .property = "short_root_bus",\
-+            .value    = stringify(0),\
-+        },{\
-+            .driver   = "q35-pcihost",\
-+            .property = "short_root_bus",\
-+            .value    = stringify(0),\
-         }
- 
- #define PC_COMPAT_1_4 \
-diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h
-index 6eb7ab6..95a3cc2 100644
---- a/include/hw/pci-host/q35.h
-+++ b/include/hw/pci-host/q35.h
-@@ -61,6 +61,7 @@ typedef struct MCHPCIState {
-     ram_addr_t above_4g_mem_size;
-     uint64_t pci_hole64_size;
-     PcGuestInfo *guest_info;
-+    uint32_t short_root_bus;
- } MCHPCIState;
- 
- typedef struct Q35PCIHost {
diff --git a/0105-audio-honor-QEMU_AUDIO_TIMER_PERIOD-instead-of-wakin.patch b/0105-audio-honor-QEMU_AUDIO_TIMER_PERIOD-instead-of-wakin.patch
deleted file mode 100644
index 30cfa3d..0000000
--- a/0105-audio-honor-QEMU_AUDIO_TIMER_PERIOD-instead-of-wakin.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 6b7ac46a461482c06c5ccdf54815e94205bc7d95 Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Wed, 9 Oct 2013 21:33:44 +0200
-Subject: [PATCH] audio: honor QEMU_AUDIO_TIMER_PERIOD instead of waking up
- every *nano* second
-
-Now that we no longer have MIN_REARM_TIMER_NS a bug in the audio subsys has
-clearly shown it self by trying to make a timer fire every nano second.
-
-Note we have a similar problem in 1.6, 1.5 and older but there
-MIN_REARM_TIMER_NS limits the wakeups caused by audio being active to
-4000 times / second. This still causes a host cpu load of 50 % for simply
-playing audio, where as with this patch git master is at 13%, so we should
-backport this to 1.5 and 1.6 too.
-
-Note this will not apply to 1.5 and 1.6 as is.
-
-Cc: qemu-stable@nongnu.org
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
-(cherry picked from commit b4350deed67b95651896ddb60cf9f765093a4848)
-
-Conflicts:
-	audio/audio.c
----
- audio/audio.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/audio/audio.c b/audio/audio.c
-index 02bb886..f9b3e95 100644
---- a/audio/audio.c
-+++ b/audio/audio.c
-@@ -1124,7 +1124,8 @@ static int audio_is_timer_needed (void)
- static void audio_reset_timer (AudioState *s)
- {
-     if (audio_is_timer_needed ()) {
--        qemu_mod_timer (s->ts, qemu_get_clock_ns (vm_clock) + 1);
-+        qemu_mod_timer (s->ts,
-+            qemu_get_clock_ns (vm_clock) + conf.period.ticks);
-     }
-     else {
-         qemu_del_timer (s->ts);
diff --git a/0106-qmp-access-the-local-QemuOptsLists-for-drive-option.patch b/0106-qmp-access-the-local-QemuOptsLists-for-drive-option.patch
deleted file mode 100644
index 7ffa62a..0000000
--- a/0106-qmp-access-the-local-QemuOptsLists-for-drive-option.patch
+++ /dev/null
@@ -1,181 +0,0 @@
-From dd733d7097c126ee3b8ee8a0f4c38b8ccac76504 Mon Sep 17 00:00:00 2001
-From: Amos Kong <akong@redhat.com>
-Date: Fri, 15 Nov 2013 18:53:14 +0100
-Subject: [PATCH] qmp: access the local QemuOptsLists for drive option
-
-Currently we have three QemuOptsList (qemu_common_drive_opts,
-qemu_legacy_drive_opts, and qemu_drive_opts), only qemu_drive_opts
-is added to vm_config_groups[].
-
-This patch changes query-command-line-options to access three local
-QemuOptsLists for drive option, and merge the description items
-together.
-
-Signed-off-by: Amos Kong <akong@redhat.com>
-Signed-off-by: Kevin Wolf <kwolf@redhat.com>
----
- blockdev.c                 |  1 -
- include/qemu/config-file.h |  1 +
- include/sysemu/sysemu.h    |  1 +
- util/qemu-config.c         | 77 +++++++++++++++++++++++++++++++++++++++++++++-
- vl.c                       |  2 ++
- 5 files changed, 80 insertions(+), 2 deletions(-)
-
-diff --git a/blockdev.c b/blockdev.c
-index 097932c..1a6892e 100644
---- a/blockdev.c
-+++ b/blockdev.c
-@@ -45,7 +45,6 @@
- #include "sysemu/arch_init.h"
- 
- static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives);
--extern QemuOptsList qemu_common_drive_opts;
- extern QemuOptsList qemu_old_drive_opts;
- 
- static const char *const if_name[IF_COUNT] = {
-diff --git a/include/qemu/config-file.h b/include/qemu/config-file.h
-index ad4a9e5..508428f 100644
---- a/include/qemu/config-file.h
-+++ b/include/qemu/config-file.h
-@@ -8,6 +8,7 @@
- QemuOptsList *qemu_find_opts(const char *group);
- QemuOptsList *qemu_find_opts_err(const char *group, Error **errp);
- void qemu_add_opts(QemuOptsList *list);
-+void qemu_add_drive_opts(QemuOptsList *list);
- int qemu_set_option(const char *str);
- int qemu_global_option(const char *str);
- void qemu_add_globals(void);
-diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
-index 1a77c99..4962cef 100644
---- a/include/sysemu/sysemu.h
-+++ b/include/sysemu/sysemu.h
-@@ -190,6 +190,7 @@ QemuOpts *qemu_get_machine_opts(void);
- 
- bool usb_enabled(bool default_usb);
- 
-+extern QemuOptsList qemu_common_drive_opts;
- extern QemuOptsList qemu_drive_opts;
- extern QemuOptsList qemu_chardev_opts;
- extern QemuOptsList qemu_device_opts;
-diff --git a/util/qemu-config.c b/util/qemu-config.c
-index a59568d..04da942 100644
---- a/util/qemu-config.c
-+++ b/util/qemu-config.c
-@@ -8,6 +8,7 @@
- #include "qmp-commands.h"
- 
- static QemuOptsList *vm_config_groups[32];
-+static QemuOptsList *drive_config_groups[4];
- 
- static QemuOptsList *find_list(QemuOptsList **lists, const char *group,
-                                Error **errp)
-@@ -77,6 +78,59 @@ static CommandLineParameterInfoList *query_option_descs(const QemuOptDesc *desc)
-     return param_list;
- }
- 
-+/* remove repeated entry from the info list */
-+static void cleanup_infolist(CommandLineParameterInfoList *head)
-+{
-+    CommandLineParameterInfoList *pre_entry, *cur, *del_entry;
-+
-+    cur = head;
-+    while (cur->next) {
-+        pre_entry = head;
-+        while (pre_entry != cur->next) {
-+            if (!strcmp(pre_entry->value->name, cur->next->value->name)) {
-+                del_entry = cur->next;
-+                cur->next = cur->next->next;
-+                g_free(del_entry);
-+                break;
-+            }
-+            pre_entry = pre_entry->next;
-+        }
-+        cur = cur->next;
-+    }
-+}
-+
-+/* merge the description items of two parameter infolists */
-+static void connect_infolist(CommandLineParameterInfoList *head,
-+                             CommandLineParameterInfoList *new)
-+{
-+    CommandLineParameterInfoList *cur;
-+
-+    cur = head;
-+    while (cur->next) {
-+        cur = cur->next;
-+    }
-+    cur->next = new;
-+}
-+
-+/* access all the local QemuOptsLists for drive option */
-+static CommandLineParameterInfoList *get_drive_infolist(void)
-+{
-+    CommandLineParameterInfoList *head = NULL, *cur;
-+    int i;
-+
-+    for (i = 0; drive_config_groups[i] != NULL; i++) {
-+        if (!head) {
-+            head = query_option_descs(drive_config_groups[i]->desc);
-+        } else {
-+            cur = query_option_descs(drive_config_groups[i]->desc);
-+            connect_infolist(head, cur);
-+        }
-+    }
-+    cleanup_infolist(head);
-+
-+    return head;
-+}
-+
- CommandLineOptionInfoList *qmp_query_command_line_options(bool has_option,
-                                                           const char *option,
-                                                           Error **errp)
-@@ -89,7 +143,12 @@ CommandLineOptionInfoList *qmp_query_command_line_options(bool has_option,
-         if (!has_option || !strcmp(option, vm_config_groups[i]->name)) {
-             info = g_malloc0(sizeof(*info));
-             info->option = g_strdup(vm_config_groups[i]->name);
--            info->parameters = query_option_descs(vm_config_groups[i]->desc);
-+            if (!strcmp("drive", vm_config_groups[i]->name)) {
-+                info->parameters = get_drive_infolist();
-+            } else {
-+                info->parameters =
-+                    query_option_descs(vm_config_groups[i]->desc);
-+            }
-             entry = g_malloc0(sizeof(*entry));
-             entry->value = info;
-             entry->next = conf_list;
-@@ -109,6 +168,22 @@ QemuOptsList *qemu_find_opts_err(const char *group, Error **errp)
-     return find_list(vm_config_groups, group, errp);
- }
- 
-+void qemu_add_drive_opts(QemuOptsList *list)
-+{
-+    int entries, i;
-+
-+    entries = ARRAY_SIZE(drive_config_groups);
-+    entries--; /* keep list NULL terminated */
-+    for (i = 0; i < entries; i++) {
-+        if (drive_config_groups[i] == NULL) {
-+            drive_config_groups[i] = list;
-+            return;
-+        }
-+    }
-+    fprintf(stderr, "ran out of space in drive_config_groups");
-+    abort();
-+}
-+
- void qemu_add_opts(QemuOptsList *list)
- {
-     int entries, i;
-diff --git a/vl.c b/vl.c
-index 2160933..63ecf16 100644
---- a/vl.c
-+++ b/vl.c
-@@ -2942,6 +2942,8 @@ int main(int argc, char **argv, char **envp)
-     module_call_init(MODULE_INIT_QOM);
- 
-     qemu_add_opts(&qemu_drive_opts);
-+    qemu_add_drive_opts(&qemu_common_drive_opts);
-+    qemu_add_drive_opts(&qemu_drive_opts);
-     qemu_add_opts(&qemu_chardev_opts);
-     qemu_add_opts(&qemu_device_opts);
-     qemu_add_opts(&qemu_netdev_opts);
diff --git a/0107-seccomp-fine-tuning-whitelist-by-adding-times.patch b/0107-seccomp-fine-tuning-whitelist-by-adding-times.patch
deleted file mode 100644
index 6818b37..0000000
--- a/0107-seccomp-fine-tuning-whitelist-by-adding-times.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From aafda3de0ce3589fa69472bd4a1782c65c8c7ade Mon Sep 17 00:00:00 2001
-From: Eduardo Otubo <otubo@linux.vnet.ibm.com>
-Date: Tue, 24 Sep 2013 14:50:44 -0300
-Subject: [PATCH] seccomp: fine tuning whitelist by adding times()
-
-This was causing Qemu process to hang when using -sandbox on as
-discribed on RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1004175
-
-Signed-off-by: Eduardo Otubo <otubo@linux.vnet.ibm.com>
-Tested-by: Paul Moore <pmoore@redhat.com>
-Acked-by: Paul Moore <pmoore@redhat.com>
-(cherry picked from commit c236f4519c9838801798f3705c17dce9ab9e3b9d)
----
- qemu-seccomp.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/qemu-seccomp.c b/qemu-seccomp.c
-index 37d38f8..69cee44 100644
---- a/qemu-seccomp.c
-+++ b/qemu-seccomp.c
-@@ -90,6 +90,7 @@ static const struct QemuSeccompSyscall seccomp_whitelist[] = {
-     { SCMP_SYS(getuid), 245 },
-     { SCMP_SYS(geteuid), 245 },
-     { SCMP_SYS(timer_create), 245 },
-+    { SCMP_SYS(times), 245 },
-     { SCMP_SYS(exit), 245 },
-     { SCMP_SYS(clock_gettime), 245 },
-     { SCMP_SYS(time), 245 },
diff --git a/qemu.spec b/qemu.spec
index 1c04dab..9f1822b 100644
--- a/qemu.spec
+++ b/qemu.spec
@@ -138,8 +138,8 @@
 
 Summary: QEMU is a FAST! processor emulator
 Name: qemu
-Version: 1.6.1
-Release: 2%{?dist}
+Version: 1.7.0
+Release: 0.1.rc1%{?dist}
 Epoch: 2
 License: GPLv2+ and LGPLv2+ and BSD
 Group: Development/Tools
@@ -154,7 +154,8 @@ ExclusiveArch: %{kvm_archs}
 %define _smp_mflags %{nil}
 %endif
 
-Source0: http://wiki.qemu-project.org/download/%{name}-%{version}.tar.bz2
+#Source0: http://wiki.qemu-project.org/download/%{name}-%{version}.tar.bz2
+Source0: http://wiki.qemu-project.org/download/%{name}-%{version}-rc1.tar.bz2
 
 
 Source1: qemu.binfmt
@@ -180,47 +181,25 @@ Source12: bridge.conf
 # qemu-kvm back compat wrapper
 Source13: qemu-kvm.sh
 
-# qemu-kvm migration compat (not for upstream, drop by Fedora 21?)
-Patch0001: 0001-Fix-migration-from-qemu-kvm.patch
-# Fix crash with -M isapc -cpu Haswell (bz #986790)
-Patch0002: 0002-isapc-disable-kvmvapic.patch
 # Fix crash in lsi_soft_reset (bz #1000947)
 # Patches posted upstream
-Patch0003: 0003-pci-do-not-export-pci_bus_reset.patch
-Patch0004: 0004-qdev-allow-both-pre-and-post-order-vists-in-qdev-wal.patch
-Patch0005: 0005-qdev-switch-reset-to-post-order.patch
+Patch0001: 0001-pci-do-not-export-pci_bus_reset.patch
+Patch0002: 0002-qdev-allow-both-pre-and-post-order-vists-in-qdev-wal.patch
+Patch0003: 0003-qdev-switch-reset-to-post-order.patch
 # CVE-2013-4377: Fix crash when unplugging virtio devices (bz #1012633,
 # bz #1012641)
 # Patches posted upstream
-Patch0006: 0006-virtio-bus-remove-vdev-field.patch
-Patch0007: 0007-virtio-pci-remove-vdev-field.patch
-Patch0008: 0008-virtio-ccw-remove-vdev-field.patch
-Patch0009: 0009-virtio-bus-cleanup-plug-unplug-interface.patch
-Patch0010: 0010-virtio-blk-switch-exit-callback-to-VirtioDeviceClass.patch
-Patch0011: 0011-virtio-serial-switch-exit-callback-to-VirtioDeviceCl.patch
-Patch0012: 0012-virtio-net-switch-exit-callback-to-VirtioDeviceClass.patch
-Patch0013: 0013-virtio-scsi-switch-exit-callback-to-VirtioDeviceClas.patch
-Patch0014: 0014-virtio-balloon-switch-exit-callback-to-VirtioDeviceC.patch
-Patch0015: 0015-virtio-rng-switch-exit-callback-to-VirtioDeviceClass.patch
-Patch0016: 0016-virtio-pci-add-device_unplugged-callback.patch
-
-# Fix 'new snapshot' slowness after the first snap (bz #988436)
-# Patches queued for upstream
-Patch0101: 0101-qcow2-Pass-discard-type-to-qcow2_discard_clusters.patch
-Patch0102: 0102-qcow2-Discard-VM-state-in-active-L1-after-creating-s.patch
-# Fix 9pfs xattrs on kernel 3.11 (bz #1013676)
-# Patch posted upstream
-Patch0103: 0103-hw-9pfs-Fix-errno-value-for-xattr-functions.patch
-# Fix migration from qemu <= 1.5
-# Patch posted upstream
-Patch0104: 0104-Fix-pc-migration-from-qemu-1.5.patch
-# Reduce CPU usage when audio is playing (bz #1017644)
-Patch0105: 0105-audio-honor-QEMU_AUDIO_TIMER_PERIOD-instead-of-wakin.patch
-# Fix drive discard options via libvirt (bz #1029953)
-# Patch queued upstream
-Patch0106: 0106-qmp-access-the-local-QemuOptsLists-for-drive-option.patch
-# Fix process exit with -sandbox on (bz #1027421)
-Patch0107: 0107-seccomp-fine-tuning-whitelist-by-adding-times.patch
+Patch0004: 0004-virtio-bus-remove-vdev-field.patch
+Patch0005: 0005-virtio-pci-remove-vdev-field.patch
+Patch0006: 0006-virtio-ccw-remove-vdev-field.patch
+Patch0007: 0007-virtio-bus-cleanup-plug-unplug-interface.patch
+Patch0008: 0008-virtio-blk-switch-exit-callback-to-VirtioDeviceClass.patch
+Patch0009: 0009-virtio-serial-switch-exit-callback-to-VirtioDeviceCl.patch
+Patch0010: 0010-virtio-net-switch-exit-callback-to-VirtioDeviceClass.patch
+Patch0011: 0011-virtio-scsi-switch-exit-callback-to-VirtioDeviceClas.patch
+Patch0012: 0012-virtio-balloon-switch-exit-callback-to-VirtioDeviceC.patch
+Patch0013: 0013-virtio-rng-switch-exit-callback-to-VirtioDeviceClass.patch
+Patch0014: 0014-virtio-pci-add-device_unplugged-callback.patch
 
 BuildRequires: SDL-devel
 BuildRequires: zlib-devel
@@ -311,6 +290,7 @@ BuildRequires: librdmacm-devel
 BuildRequires: qemu-sanity-check-nodeps
 BuildRequires: kernel
 %endif
+BuildRequires: iasl
 
 %if 0%{?user:1}
 Requires: %{name}-%{user} = %{epoch}:%{version}-%{release}
@@ -731,20 +711,18 @@ CAC emulation development files.
 %endif
 
 %prep
-%setup -q
+%setup -q -n qemu-1.7.0-rc1
 
-# qemu-kvm migration compat (not for upstream, drop by Fedora 21?)
-%patch0001 -p1
-# Fix crash with -M isapc -cpu Haswell (bz #986790)
-%patch0002 -p1
 # Fix crash in lsi_soft_reset (bz #1000947)
 # Patches posted upstream
+%patch0001 -p1
+%patch0002 -p1
 %patch0003 -p1
-%patch0004 -p1
-%patch0005 -p1
 # CVE-2013-4377: Fix crash when unplugging virtio devices (bz #1012633,
 # bz #1012641)
 # Patches posted upstream
+%patch0004 -p1
+%patch0005 -p1
 %patch0006 -p1
 %patch0007 -p1
 %patch0008 -p1
@@ -754,26 +732,6 @@ CAC emulation development files.
 %patch0012 -p1
 %patch0013 -p1
 %patch0014 -p1
-%patch0015 -p1
-%patch0016 -p1
-
-# Fix 'new snapshot' slowness after the first snap (bz #988436)
-# Patches queued for upstream
-%patch0101 -p1
-%patch0102 -p1
-# Fix 9pfs xattrs on kernel 3.11 (bz #1013676)
-# Patch posted upstream
-%patch0103 -p1
-# Fix migration from qemu <= 1.5
-# Patch posted upstream
-%patch0104 -p1
-# Reduce CPU usage when audio is playing (bz #1017644)
-%patch0105 -p1
-# Fix drive discard options via libvirt (bz #1029953)
-# Patch queued upstream
-%patch0106 -p1
-# Fix process exit with -sandbox on (bz #1027421)
-%patch0107 -p1
 
 
 %build
@@ -814,17 +772,17 @@ dobuild() {
         --libdir=%{_libdir} \
         --sysconfdir=%{_sysconfdir} \
         --interp-prefix=%{_prefix}/qemu-%%M \
-        --audio-drv-list=pa,sdl,alsa,oss \
         --localstatedir=%{_localstatedir} \
         --libexecdir=%{_libexecdir} \
         --disable-strip \
         --extra-ldflags="$extraldflags -pie -Wl,-z,relro -Wl,-z,now" \
         --extra-cflags="%{optflags} -fPIE -DPIE" \
-        --enable-mixemu \
-        --enable-trace-backend=dtrace \
         --disable-werror \
+        --audio-drv-list=pa,sdl,alsa,oss \
+        --enable-trace-backend=dtrace \
         --disable-xen \
         --enable-kvm \
+        --enable-tpm \
 %if 0%{?have_spice:1}
         --enable-spice \
 %endif
@@ -842,7 +800,6 @@ dobuild() {
 %if %{with gtk}
         --with-gtkabi="3.0" \
 %endif
-        --enable-tpm \
 %ifarch s390
         --enable-tcg-interpreter \
 %endif
@@ -1481,6 +1438,9 @@ getent passwd qemu >/dev/null || \
 %endif
 
 %changelog
+* Thu Nov 21 2013 Cole Robinson <crobinso@redhat.com> - 2:1.7.0-0.1.rc1
+- Update qemu-1.7.0-rc1
+
 * Sun Nov 17 2013 Cole Robinson <crobinso@redhat.com> - 2:1.6.1-2
 - Fix drive discard options via libvirt (bz #1029953)
 - Fix process exit with -sandbox on (bz #1027421)
diff --git a/sources b/sources
index 06f99b4..0eec911 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-3a897d722457c5a895cd6ac79a28fda0  qemu-1.6.1.tar.bz2
+4cd5d82632335e0a586c77725ef0547d  qemu-1.7.0-rc1.tar.bz2