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
