Git-Url: 
http://git.frugalware.org/gitweb/gitweb.cgi?p=frugalware-1.9.git;a=commitdiff;h=dee8afe418ec2cb19544aca29c7634efebf5cdd2

commit dee8afe418ec2cb19544aca29c7634efebf5cdd2
Author: kikadf <[email protected]>
Date:   Thu Feb 6 10:21:36 2014 +0100

qemu-1.5.2-3arcturus1-x86_64

Fix CVE-2013-4344 CVE-2013-4375 CVE-2013-4377

diff --git a/source/xapps-extra/qemu/CVE-2013-4344.patch 
b/source/xapps-extra/qemu/CVE-2013-4344.patch
new file mode 100644
index 0000000..a6a3ee1
--- /dev/null
+++ b/source/xapps-extra/qemu/CVE-2013-4344.patch
@@ -0,0 +1,152 @@
+From 846424350b292f16b732b573273a5c1f195cd7a3 Mon Sep 17 00:00:00 2001
+From: Asias He <[email protected]>
+Date: Wed, 9 Oct 2013 15:41:03 +0800
+Subject: [PATCH] scsi: Allocate SCSITargetReq r->buf dynamically 
[CVE-2013-4344]
+
+r->buf is hardcoded to 2056 which is (256 + 1) * 8, allowing 256 luns at
+most. If more than 256 luns are specified by user, we have buffer
+overflow in scsi_target_emulate_report_luns.
+
+To fix, we allocate the buffer dynamically.
+
+Signed-off-by: Asias He <[email protected]>
+Tested-by: Michael Roth <[email protected]>
+Signed-off-by: Paolo Bonzini <[email protected]>
+---
+ hw/scsi/scsi-bus.c     |   45 ++++++++++++++++++++++++++++++++++-----------
+ include/hw/scsi/scsi.h |    2 ++
+ 2 files changed, 36 insertions(+), 11 deletions(-)
+
+Index: qemu-1.5.0+dfsg/hw/scsi/scsi-bus.c
+===================================================================
+--- qemu-1.5.0+dfsg.orig/hw/scsi/scsi-bus.c    2014-01-28 05:40:46.424948492 
-0500
++++ qemu-1.5.0+dfsg/hw/scsi/scsi-bus.c 2014-01-28 05:40:46.420948492 -0500
+@@ -11,6 +11,8 @@
+ static char *scsibus_get_fw_dev_path(DeviceState *dev);
+ static int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf);
+ static void scsi_req_dequeue(SCSIRequest *req);
++static uint8_t *scsi_target_alloc_buf(SCSIRequest *req, size_t len);
++static void scsi_target_free_buf(SCSIRequest *req);
+
+ static Property scsi_props[] = {
+     DEFINE_PROP_UINT32("channel", SCSIDevice, channel, 0),
+@@ -309,7 +311,8 @@
+ struct SCSITargetReq {
+     SCSIRequest req;
+     int len;
+-    uint8_t buf[2056];
++    uint8_t *buf;
++    int buf_len;
+ };
+
+ static void store_lun(uint8_t *outbuf, int lun)
+@@ -353,14 +356,12 @@
+     if (!found_lun0) {
+         n += 8;
+     }
+-    len = MIN(n + 8, r->req.cmd.xfer & ~7);
+-    if (len > sizeof(r->buf)) {
+-        /* TODO: > 256 LUNs? */
+-        return false;
+-    }
+
++    scsi_target_alloc_buf(&r->req, n + 8);
++
++    len = MIN(n + 8, r->req.cmd.xfer & ~7);
+     memset(r->buf, 0, len);
+-    stl_be_p(&r->buf, n);
++    stl_be_p(&r->buf[0], n);
+     i = found_lun0 ? 8 : 16;
+     QTAILQ_FOREACH(kid, &r->req.bus->qbus.children, sibling) {
+         DeviceState *qdev = kid->child;
+@@ -379,6 +380,9 @@
+ static bool scsi_target_emulate_inquiry(SCSITargetReq *r)
+ {
+     assert(r->req.dev->lun != r->req.lun);
++
++    scsi_target_alloc_buf(&r->req, SCSI_INQUIRY_LEN);
++
+     if (r->req.cmd.buf[1] & 0x2) {
+         /* Command support data - optional, not implemented */
+         return false;
+@@ -403,7 +407,7 @@
+             return false;
+         }
+         /* done with EVPD */
+-        assert(r->len < sizeof(r->buf));
++        assert(r->len < r->buf_len);
+         r->len = MIN(r->req.cmd.xfer, r->len);
+         return true;
+     }
+@@ -414,7 +418,7 @@
+     }
+
+     /* PAGE CODE == 0 */
+-    r->len = MIN(r->req.cmd.xfer, 36);
++    r->len = MIN(r->req.cmd.xfer, SCSI_INQUIRY_LEN);
+     memset(r->buf, 0, r->len);
+     if (r->req.lun != 0) {
+         r->buf[0] = TYPE_NO_LUN;
+@@ -447,8 +451,9 @@
+         }
+         break;
+     case REQUEST_SENSE:
++        scsi_target_alloc_buf(&r->req, SCSI_SENSE_LEN);
+         r->len = scsi_device_get_sense(r->req.dev, r->buf,
+-                                       MIN(req->cmd.xfer, sizeof r->buf),
++                                       MIN(req->cmd.xfer, r->buf_len),
+                                        (req->cmd.buf[1] & 1) == 0);
+         if (r->req.dev->sense_is_ua) {
+             scsi_device_unit_attention_reported(req->dev);
+@@ -493,11 +498,29 @@
+     return r->buf;
+ }
+
++static uint8_t *scsi_target_alloc_buf(SCSIRequest *req, size_t len)
++{
++    SCSITargetReq *r = DO_UPCAST(SCSITargetReq, req, req);
++
++    r->buf = g_malloc(len);
++    r->buf_len = len;
++
++    return r->buf;
++}
++
++static void scsi_target_free_buf(SCSIRequest *req)
++{
++    SCSITargetReq *r = DO_UPCAST(SCSITargetReq, req, req);
++
++    g_free(r->buf);
++}
++
+ static const struct SCSIReqOps reqops_target_command = {
+     .size         = sizeof(SCSITargetReq),
+     .send_command = scsi_target_send_command,
+     .read_data    = scsi_target_read_data,
+     .get_buf      = scsi_target_get_buf,
++    .free_req     = scsi_target_free_buf,
+ };
+
+
+@@ -1353,7 +1376,7 @@
+         buf[7] = 10;
+         buf[12] = sense.asc;
+         buf[13] = sense.ascq;
+-        return MIN(len, 18);
++        return MIN(len, SCSI_SENSE_LEN);
+     } else {
+         /* Return descriptor format sense buffer */
+         buf[0] = 0x72;
+Index: qemu-1.5.0+dfsg/include/hw/scsi/scsi.h
+===================================================================
+--- qemu-1.5.0+dfsg.orig/include/hw/scsi/scsi.h        2014-01-28 
05:40:46.424948492 -0500
++++ qemu-1.5.0+dfsg/include/hw/scsi/scsi.h     2014-01-28 05:40:46.420948492 
-0500
+@@ -9,6 +9,8 @@
+ #define MAX_SCSI_DEVS 255
+
+ #define SCSI_CMD_BUF_SIZE     16
++#define SCSI_SENSE_LEN      18
++#define SCSI_INQUIRY_LEN    36
+
+ typedef struct SCSIBus SCSIBus;
+ typedef struct SCSIBusInfo SCSIBusInfo;
diff --git a/source/xapps-extra/qemu/CVE-2013-4375.patch 
b/source/xapps-extra/qemu/CVE-2013-4375.patch
new file mode 100644
index 0000000..39b7340
--- /dev/null
+++ b/source/xapps-extra/qemu/CVE-2013-4375.patch
@@ -0,0 +1,37 @@
+From a76f48e53382e6f039db6278443e3ce437653302 Mon Sep 17 00:00:00 2001
+From: Matthew Daley <[email protected]>
+Date: Thu, 10 Oct 2013 14:10:48 +0000
+Subject: [PATCH] xen_disk: mark ioreq as mapped before unmapping in error case
+
+Commit 4472beae modified the semantics of ioreq_{un,}map so that they are
+idempotent if called when they're not needed (ie., twice in a row). However,
+it neglected to handle the case where batch mapping is not being used (the
+default), and one of the grants fails to map. In this case, ioreq_unmap will
+be called to unwind and unmap any mappings already performed, but ioreq_unmap
+simply returns due to the aforementioned change (the ioreq has not already
+been marked as mapped).
+
+The frontend user can therefore force xen_disk to leak grant mappings, a
+per-domain limited resource.
+
+Fix by marking the ioreq as mapped before calling ioreq_unmap in this
+situation.
+
+Signed-off-by: Matthew Daley <[email protected]>
+Signed-off-by: Stefano Stabellini <[email protected]>
+---
+ hw/block/xen_disk.c |    1 +
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+
+Index: qemu-1.5.0+dfsg/hw/block/xen_disk.c
+===================================================================
+--- qemu-1.5.0+dfsg.orig/hw/block/xen_disk.c   2014-01-28 05:41:30.460949671 
-0500
++++ qemu-1.5.0+dfsg/hw/block/xen_disk.c        2014-01-28 05:41:30.456949671 
-0500
+@@ -404,6 +404,7 @@
+                 xen_be_printf(&ioreq->blkdev->xendev, 0,
+                               "can't map grant ref %d (%s, %d maps)\n",
+                               refs[i], strerror(errno), 
ioreq->blkdev->cnt_map);
++                ioreq->mapped = 1;
+                 ioreq_unmap(ioreq);
+                 return -1;
+             }
diff --git a/source/xapps-extra/qemu/CVE-2013-4377.patch 
b/source/xapps-extra/qemu/CVE-2013-4377.patch
new file mode 100644
index 0000000..d579b38
--- /dev/null
+++ b/source/xapps-extra/qemu/CVE-2013-4377.patch
@@ -0,0 +1,1276 @@
+Description: fix denial of service via virtio device hot-plugging
+Origin: backport, 
http://git.qemu.org/?p=qemu.git;a=commit;h=92304bf3998cedcf3b1026a795edba7e1fd17c74
+Origin: backport, 
http://git.qemu.org/?p=qemu.git;a=commit;h=0b81c1ef5c677c2a07be5f8bf0dfe2c62ef52115
+Origin: backport, 
http://git.qemu.org/?p=qemu.git;a=commit;h=06d3dff0723c712a4b109ced4243edf49ef850af
+Origin: backport, 
http://git.qemu.org/?p=qemu.git;a=commit;h=f24a684073bcdaf4e9d3c592345744ba3356d9e3
+Origin: backport, 
http://git.qemu.org/?p=qemu.git;a=commit;h=a3fc66d9fd37acbfcee013692246a8ae42bd93bb
+Origin: backport, 
http://git.qemu.org/?p=qemu.git;a=commit;h=5e96f5d2f8d2696ef7d2d8d7282c18fa6023470b
+Origin: backport, 
http://git.qemu.org/?p=qemu.git;a=commit;h=40dfc16f5fe0afb66f9436718781264dfadb6c61
+Origin: backport, 
http://git.qemu.org/?p=qemu.git;a=commit;h=0e86c13fe2058adb8c792ebb7c51a6a7ca9d3d55
+Origin: backport, 
http://git.qemu.org/?p=qemu.git;a=commit;h=3786cff5eb384d058395a2729af627fa3253d056
+Origin: backport, 
http://git.qemu.org/?p=qemu.git;a=commit;h=e3c9d76acc984218264bbc6435b0c09f959ed9b8
+Origin: backport, 
http://git.qemu.org/?p=qemu.git;a=commit;h=baa61b9870dd7e0bb07e0ae61c6ec805db13f699
+Origin: backport, 
http://git.qemu.org/?p=qemu.git;a=commit;h=7bb6edb0e3dd78d74e0ac980cf6c0a07307f61bf
+Origin: backport, 
http://git.qemu.org/?p=qemu.git;a=commit;h=06a1307379fcd6c551185ad87679cd7ed896b9ea
+
+Index: qemu-1.5.0+dfsg/hw/9pfs/virtio-9p-device.c
+===================================================================
+--- qemu-1.5.0+dfsg.orig/hw/9pfs/virtio-9p-device.c    2013-05-20 
11:34:39.000000000 -0400
++++ qemu-1.5.0+dfsg/hw/9pfs/virtio-9p-device.c 2014-01-28 05:04:47.832890687 
-0500
+@@ -68,14 +68,14 @@
+         fprintf(stderr, "Virtio-9p device couldn't find fsdev with the "
+                 "id = %s\n",
+                 s->fsconf.fsdev_id ? s->fsconf.fsdev_id : "NULL");
+-        return -1;
++        goto out;
+     }
+
+     if (!s->fsconf.tag) {
+         /* we haven't specified a mount_tag */
+         fprintf(stderr, "fsdev with id %s needs mount_tag arguments\n",
+                 s->fsconf.fsdev_id);
+-        return -1;
++        goto out;
+     }
+
+     s->ctx.export_flags = fse->export_flags;
+@@ -85,10 +85,10 @@
+     if (len > MAX_TAG_LEN - 1) {
+         fprintf(stderr, "mount tag '%s' (%d bytes) is longer than "
+                 "maximum (%d bytes)", s->fsconf.tag, len, MAX_TAG_LEN - 1);
+-        return -1;
++        goto out;
+     }
+
+-    s->tag = strdup(s->fsconf.tag);
++    s->tag = g_strdup(s->fsconf.tag);
+     s->ctx.uid = -1;
+
+     s->ops = fse->ops;
+@@ -99,11 +99,11 @@
+     if (s->ops->init(&s->ctx) < 0) {
+         fprintf(stderr, "Virtio-9p Failed to initialize fs-driver with id:%s"
+                 " and export path:%s\n", s->fsconf.fsdev_id, s->ctx.fs_root);
+-        return -1;
++        goto out;
+     }
+     if (v9fs_init_worker_threads() < 0) {
+         fprintf(stderr, "worker thread initialization failed\n");
+-        return -1;
++        goto out;
+     }
+
+     /*
+@@ -115,18 +115,26 @@
+     if (s->ops->name_to_path(&s->ctx, NULL, "/", &path) < 0) {
+         fprintf(stderr,
+                 "error in converting name to path %s", strerror(errno));
+-        return -1;
++        goto out;
+     }
+     if (s->ops->lstat(&s->ctx, &path, &stat)) {
+         fprintf(stderr, "share path %s does not exist\n", fse->path);
+-        return -1;
++        goto out;
+     } else if (!S_ISDIR(stat.st_mode)) {
+         fprintf(stderr, "share path %s is not a directory\n", fse->path);
+-        return -1;
++        goto out;
+     }
+     v9fs_path_free(&path);
+
+     return 0;
++out:
++    g_free(s->ctx.fs_root);
++    g_free(s->tag);
++    virtio_cleanup(vdev);
++    v9fs_path_free(&path);
++
++    return -1;
++
+ }
+
+ /* virtio-9p device */
+Index: qemu-1.5.0+dfsg/hw/block/virtio-blk.c
+===================================================================
+--- qemu-1.5.0+dfsg.orig/hw/block/virtio-blk.c 2013-05-20 11:34:39.000000000 
-0400
++++ qemu-1.5.0+dfsg/hw/block/virtio-blk.c      2014-01-28 05:31:42.916933937 
-0500
+@@ -678,19 +678,17 @@
+     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
+     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[] = {
+@@ -702,9 +700,9 @@
+ {
+     DeviceClass *dc = DEVICE_CLASS(klass);
+     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+-    dc->exit = virtio_blk_device_exit;
+     dc->props = virtio_blk_properties;
+     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;
+Index: qemu-1.5.0+dfsg/hw/char/virtio-serial-bus.c
+===================================================================
+--- qemu-1.5.0+dfsg.orig/hw/char/virtio-serial-bus.c   2013-05-20 
11:34:39.000000000 -0400
++++ qemu-1.5.0+dfsg/hw/char/virtio-serial-bus.c        2014-01-28 
05:32:32.592935268 -0500
+@@ -986,12 +986,11 @@
+     .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);
+@@ -1003,7 +1002,6 @@
+         g_free(vser->post_load);
+     }
+     virtio_cleanup(vdev);
+-    return 0;
+ }
+
+ static Property virtio_serial_properties[] = {
+@@ -1015,9 +1013,9 @@
+ {
+     DeviceClass *dc = DEVICE_CLASS(klass);
+     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+-    dc->exit = virtio_serial_device_exit;
+     dc->props = virtio_serial_properties;
+     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;
+Index: qemu-1.5.0+dfsg/hw/net/virtio-net.c
+===================================================================
+--- qemu-1.5.0+dfsg.orig/hw/net/virtio-net.c   2013-05-20 11:34:39.000000000 
-0400
++++ qemu-1.5.0+dfsg/hw/net/virtio-net.c        2014-01-28 05:33:17.808936479 
-0500
+@@ -1378,16 +1378,15 @@
+     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);
+@@ -1418,8 +1417,6 @@
+     g_free(n->vqs);
+     qemu_del_nic(n->nic);
+     virtio_cleanup(vdev);
+-
+-    return 0;
+ }
+
+ static void virtio_net_instance_init(Object *obj)
+@@ -1446,9 +1443,9 @@
+ {
+     DeviceClass *dc = DEVICE_CLASS(klass);
+     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+-    dc->exit = virtio_net_device_exit;
+     dc->props = virtio_net_properties;
+     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;
+Index: qemu-1.5.0+dfsg/hw/s390x/virtio-ccw.c
+===================================================================
+--- qemu-1.5.0+dfsg.orig/hw/s390x/virtio-ccw.c 2014-01-28 05:04:10.000000000 
-0500
++++ qemu-1.5.0+dfsg/hw/s390x/virtio-ccw.c      2014-01-28 05:23:43.104921089 
-0500
+@@ -56,9 +56,10 @@
+ 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;
+ }
+@@ -105,7 +106,7 @@
+ 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;
+@@ -116,23 +117,23 @@
+         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;
+ }
+
+@@ -146,6 +147,7 @@
+     hwaddr indicators;
+     VqConfigBlock vq_config;
+     VirtioCcwDevice *dev = sch->driver_data;
++    VirtIODevice *vdev = virtio_ccw_get_vdev(sch);
+     bool check_len;
+     int len;
+     hwaddr hw_len;
+@@ -187,7 +189,7 @@
+         }
+         break;
+     case CCW_CMD_VDEV_RESET:
+-        virtio_reset(dev->vdev);
++        virtio_reset(vdev);
+         ret = 0;
+         break;
+     case CCW_CMD_READ_FEAT:
+@@ -234,7 +236,7 @@
+             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
+@@ -252,30 +254,30 @@
+         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;
+@@ -286,9 +288,9 @@
+             } 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;
+             }
+@@ -309,9 +311,9 @@
+             ret = -EFAULT;
+         } else {
+             status = ldub_phys(ccw.cda);
+-            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);
+             }
+             sch->curr_status.scsw.count = ccw.count - sizeof(status);
+             ret = 0;
+@@ -372,7 +374,7 @@
+             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);
+@@ -404,7 +406,6 @@
+     sch->driver_data = dev;
+     dev->sch = sch;
+
+-    dev->vdev = vdev;
+     dev->indicators = 0;
+
+     /* Initialize subchannel structure. */
+@@ -517,7 +518,7 @@
+     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,
+@@ -800,8 +801,9 @@
+ static void virtio_ccw_reset(DeviceState *d)
+ {
+     VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
++    VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
+
+-    virtio_reset(dev->vdev);
++    virtio_reset(vdev);
+     css_reset_sch(dev->sch);
+ }
+
+Index: qemu-1.5.0+dfsg/hw/s390x/virtio-ccw.h
+===================================================================
+--- qemu-1.5.0+dfsg.orig/hw/s390x/virtio-ccw.h 2013-05-20 11:34:39.000000000 
-0400
++++ qemu-1.5.0+dfsg/hw/s390x/virtio-ccw.h      2014-01-28 05:15:03.272907168 
-0500
+@@ -72,7 +72,6 @@
+ struct VirtioCcwDevice {
+     DeviceState parent_obj;
+     SubchDev *sch;
+-    VirtIODevice *vdev;
+     char *bus_id;
+     uint32_t host_features[VIRTIO_CCW_FEATURE_SIZE];
+     VirtioBusState bus;
+Index: qemu-1.5.0+dfsg/hw/scsi/vhost-scsi.c
+===================================================================
+--- qemu-1.5.0+dfsg.orig/hw/scsi/vhost-scsi.c  2013-05-20 11:34:39.000000000 
-0400
++++ qemu-1.5.0+dfsg/hw/scsi/vhost-scsi.c       2014-01-28 05:34:01.376937645 
-0500
+@@ -240,11 +240,10 @@
+     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 @@
+     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,9 +264,9 @@
+ {
+     DeviceClass *dc = DEVICE_CLASS(klass);
+     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+-    dc->exit = vhost_scsi_exit;
+     dc->props = vhost_scsi_properties;
+     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;
+Index: qemu-1.5.0+dfsg/hw/scsi/virtio-scsi.c
+===================================================================
+--- qemu-1.5.0+dfsg.orig/hw/scsi/virtio-scsi.c 2013-05-20 11:34:39.000000000 
-0400
++++ qemu-1.5.0+dfsg/hw/scsi/virtio-scsi.c      2014-01-28 05:34:23.052938226 
-0500
+@@ -636,22 +636,21 @@
+     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[] = {
+@@ -670,9 +669,9 @@
+ {
+     DeviceClass *dc = DEVICE_CLASS(klass);
+     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+-    dc->exit = virtio_scsi_device_exit;
+     dc->props = virtio_scsi_properties;
+     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;
+Index: qemu-1.5.0+dfsg/hw/virtio/virtio-balloon.c
+===================================================================
+--- qemu-1.5.0+dfsg.orig/hw/virtio/virtio-balloon.c    2013-05-20 
11:34:39.000000000 -0400
++++ qemu-1.5.0+dfsg/hw/virtio/virtio-balloon.c 2014-01-28 05:35:11.280939517 
-0500
+@@ -369,16 +369,14 @@
+     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[] = {
+@@ -389,9 +387,9 @@
+ {
+     DeviceClass *dc = DEVICE_CLASS(klass);
+     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+-    dc->exit = virtio_balloon_device_exit;
+     dc->props = virtio_balloon_properties;
+     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;
+Index: qemu-1.5.0+dfsg/hw/virtio/virtio-bus.c
+===================================================================
+--- qemu-1.5.0+dfsg.orig/hw/virtio/virtio-bus.c        2013-05-20 
11:34:39.000000000 -0400
++++ qemu-1.5.0+dfsg/hw/virtio/virtio-bus.c     2014-01-28 05:29:16.020930004 
-0500
+@@ -37,8 +37,8 @@
+ #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));
+@@ -46,8 +46,6 @@
+     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,83 @@
+ /* 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)
++/* A VirtIODevice is being unplugged */
++void virtio_bus_device_unplugged(VirtIODevice *vdev)
+ {
+-    DeviceState *qdev;
+-    BusState *qbus = BUS(bus);
+-    VirtioBusClass *klass = VIRTIO_BUS_GET_CLASS(bus);
++    DeviceState *qdev = DEVICE(vdev);
++    BusState *qbus = BUS(qdev_get_parent_bus(qdev));
++    VirtioBusClass *klass = VIRTIO_BUS_GET_CLASS(qbus);
++
+     DPRINTF("%s: remove device.\n", qbus->name);
+
+-    if (bus->vdev != NULL) {
+-        if (klass->device_unplug != NULL) {
+-            klass->device_unplug(qbus->parent);
++    if (vdev != NULL) {
++        if (klass->device_unplugged != NULL) {
++            klass->device_unplugged(qbus->parent);
+         }
+-        qdev = DEVICE(bus->vdev);
+-        qdev_free(qdev);
+-        bus->vdev = NULL;
+     }
+ }
+
+ /* 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 +141,26 @@
+ /* 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);
+     }
+ }
+
+Index: qemu-1.5.0+dfsg/hw/virtio/virtio-pci.c
+===================================================================
+--- qemu-1.5.0+dfsg.orig/hw/virtio/virtio-pci.c        2014-01-28 
05:04:10.000000000 -0500
++++ qemu-1.5.0+dfsg/hw/virtio/virtio-pci.c     2014-01-28 05:36:42.092941949 
-0500
+@@ -118,31 +118,40 @@
+ static void virtio_pci_notify(DeviceState *d, uint16_t vector)
+ {
+     VirtIOPCIProxy *proxy = to_virtio_pci_proxy_fast(d);
++
+     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);
++    else {
++        VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
++        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) {
+@@ -151,12 +160,12 @@
+     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;
+ }
+@@ -164,13 +173,15 @@
+ 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);
+     }
+@@ -180,7 +191,8 @@
+ 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;
+
+@@ -205,6 +217,7 @@
+
+ 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) ||
+@@ -214,7 +227,7 @@
+     }
+
+     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;
+         }
+
+@@ -228,7 +241,7 @@
+
+ assign_error:
+     while (--n >= 0) {
+-        if (!virtio_queue_get_num(proxy->vdev, n)) {
++        if (!virtio_queue_get_num(vdev, n)) {
+             continue;
+         }
+
+@@ -241,6 +254,7 @@
+
+ static void virtio_pci_stop_ioeventfd(VirtIOPCIProxy *proxy)
+ {
++    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+     int r;
+     int n;
+
+@@ -249,7 +263,7 @@
+     }
+
+     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;
+         }
+
+@@ -262,7 +276,7 @@
+ 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) {
+@@ -277,7 +291,7 @@
+         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
+@@ -304,7 +318,7 @@
+         }
+
+         if (vdev->status == 0) {
+-            virtio_reset(proxy->vdev);
++            virtio_reset(vdev);
+             msix_unuse_all_vectors(&proxy->pci_dev);
+         }
+
+@@ -340,7 +354,7 @@
+
+ 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) {
+@@ -386,6 +400,7 @@
+                                        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) {
+@@ -395,16 +410,16 @@
+
+     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);
+         }
+@@ -418,6 +433,7 @@
+ {
+     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;
+@@ -429,19 +445,19 @@
+      */
+     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;
+     }
+ }
+@@ -460,6 +476,7 @@
+                                 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);
+
+@@ -467,8 +484,7 @@
+         !(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);
+     }
+ }
+
+@@ -511,7 +527,8 @@
+                                  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);
+@@ -522,7 +539,8 @@
+                                       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;
+@@ -534,7 +552,7 @@
+ 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;
+@@ -583,7 +601,7 @@
+ 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);
+@@ -611,8 +629,9 @@
+                                        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;
+@@ -631,10 +650,10 @@
+      * 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 {
+@@ -647,13 +666,14 @@
+                                              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);
+     }
+@@ -663,7 +683,7 @@
+                                     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++) {
+@@ -693,7 +713,7 @@
+ 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++) {
+@@ -712,7 +732,7 @@
+                                    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;
+@@ -744,8 +764,9 @@
+                                          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) {
+@@ -760,7 +781,7 @@
+     }
+
+     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;
+@@ -775,7 +796,7 @@
+ 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) &&
+@@ -870,11 +891,12 @@
+ 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;
+         }
+@@ -948,8 +970,6 @@
+     uint8_t *config;
+     uint32_t size;
+
+-    proxy->vdev = bus->vdev;
+-
+     config = proxy->pci_dev.config;
+     if (proxy->class_code) {
+         pci_config_set_class(config, proxy->class_code);
+@@ -987,6 +1007,15 @@
+                                                       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);
+@@ -1001,9 +1030,7 @@
+ 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)
+@@ -1530,6 +1557,7 @@
+     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 = {
+Index: qemu-1.5.0+dfsg/hw/virtio/virtio-pci.h
+===================================================================
+--- qemu-1.5.0+dfsg.orig/hw/virtio/virtio-pci.h        2013-05-20 
11:34:39.000000000 -0400
++++ qemu-1.5.0+dfsg/hw/virtio/virtio-pci.h     2014-01-28 05:24:21.848922126 
-0500
+@@ -82,7 +82,6 @@
+
+ struct VirtIOPCIProxy {
+     PCIDevice pci_dev;
+-    VirtIODevice *vdev;
+     MemoryRegion bar;
+     uint32_t flags;
+     uint32_t class_code;
+Index: qemu-1.5.0+dfsg/hw/virtio/virtio-rng.c
+===================================================================
+--- qemu-1.5.0+dfsg.orig/hw/virtio/virtio-rng.c        2013-05-20 
11:34:39.000000000 -0400
++++ qemu-1.5.0+dfsg/hw/virtio/virtio-rng.c     2014-01-28 05:36:30.144941629 
-0500
+@@ -184,16 +184,14 @@
+     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,9 +203,9 @@
+ {
+     DeviceClass *dc = DEVICE_CLASS(klass);
+     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+-    dc->exit = virtio_rng_device_exit;
+     dc->props = virtio_rng_properties;
+     vdc->init = virtio_rng_device_init;
++    vdc->exit = virtio_rng_device_exit;
+     vdc->get_features = get_features;
+ }
+
+Index: qemu-1.5.0+dfsg/hw/virtio/virtio.c
+===================================================================
+--- qemu-1.5.0+dfsg.orig/hw/virtio/virtio.c    2013-05-20 11:34:39.000000000 
-0400
++++ qemu-1.5.0+dfsg/hw/virtio/virtio.c 2014-01-28 05:27:30.140927168 -0500
+@@ -1113,14 +1113,19 @@
+     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;
+Index: qemu-1.5.0+dfsg/include/hw/virtio/virtio-bus.h
+===================================================================
+--- qemu-1.5.0+dfsg.orig/include/hw/virtio/virtio-bus.h        2013-05-20 
11:34:39.000000000 -0400
++++ qemu-1.5.0+dfsg/include/hw/virtio/virtio-bus.h     2014-01-28 
05:29:32.312930440 -0500
+@@ -61,20 +61,16 @@
+      * 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);
+ } VirtioBusClass;
+
+ struct VirtioBusState {
+     BusState parent_obj;
+-    /*
+-     * Only one VirtIODevice can be plugged on the bus.
+-     */
+-    VirtIODevice *vdev;
+ };
+
+-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. */
+@@ -92,4 +88,16 @@
+ /* 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 */
+Index: qemu-1.5.0+dfsg/include/hw/virtio/virtio-scsi.h
+===================================================================
+--- qemu-1.5.0+dfsg.orig/include/hw/virtio/virtio-scsi.h       2013-05-20 
11:34:39.000000000 -0400
++++ qemu-1.5.0+dfsg/include/hw/virtio/virtio-scsi.h    2014-01-28 
05:33:30.284936813 -0500
+@@ -187,6 +187,6 @@
+                                             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 */
+Index: qemu-1.5.0+dfsg/include/hw/virtio/virtio.h
+===================================================================
+--- qemu-1.5.0+dfsg.orig/include/hw/virtio/virtio.h    2013-05-20 
11:34:39.000000000 -0400
++++ qemu-1.5.0+dfsg/include/hw/virtio/virtio.h 2014-01-28 05:27:30.140927168 
-0500
+@@ -125,6 +125,7 @@
+     /* 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/source/xapps-extra/qemu/FrugalBuild 
b/source/xapps-extra/qemu/FrugalBuild
index 5ee8a62..5e97a6a 100644
--- a/source/xapps-extra/qemu/FrugalBuild
+++ b/source/xapps-extra/qemu/FrugalBuild
@@ -9,7 +9,7 @@ USE_DEVEL=${USE_DEVEL:-"n"}
pkgname=qemu
pkgver=1.5.2
Fuse $USE_DEVEL && pkgver=svn6369
-pkgrel=2
+pkgrel=3arcturus1
Fuse $USE_DEVEL && pkgrel=1
pkgdesc="QEMU is a FAST! processor emulator"
url="http://www.nongnu.org/qemu/";
@@ -47,6 +47,13 @@ subdepends=('glib2' 'glib2 nss')

TARGETS="i386-softmmu x86_64-softmmu arm-softmmu"

+# FSA fix ***
+source=(${source[@]} CVE-2013-4344.patch CVE-2013-4375.patch 
CVE-2013-4377.patch)
+sha1sums=(${sha1sums[@]} '24acdb676d4bea695e7b0a2cb75efdebca92bb0f' \
+                        '761b353dbbd110fd8e75e0e5f471effdc8e37beb' \
+                        'b50f8d0fcb307220ec670685835808dbd387fc7e')
+# ***********
+
build()
{
if Fuse $USE_DEVEL; then
_______________________________________________
Frugalware-git mailing list
[email protected]
http://frugalware.org/mailman/listinfo/frugalware-git

Reply via email to