diff options
-rw-r--r-- | VERSION | 2 | ||||
-rw-r--r-- | block/block-backend.c | 24 | ||||
-rw-r--r-- | block/parallels.c | 2 | ||||
-rw-r--r-- | blockjob.c | 63 | ||||
-rwxr-xr-x | configure | 51 | ||||
-rw-r--r-- | hw/9pfs/9p-proxy.c | 22 | ||||
-rw-r--r-- | hw/9pfs/9p.c | 12 | ||||
-rw-r--r-- | hw/acpi/vmgenid.c | 22 | ||||
-rw-r--r-- | hw/display/Makefile.objs | 6 | ||||
-rw-r--r-- | hw/virtio/virtio-bus.c | 20 | ||||
-rw-r--r-- | hw/virtio/virtio.c | 13 | ||||
-rw-r--r-- | include/hw/acpi/vmgenid.h | 2 | ||||
-rw-r--r-- | include/hw/compat.h | 4 | ||||
-rw-r--r-- | include/sysemu/block-backend.h | 8 | ||||
-rw-r--r-- | ui/Makefile.objs | 7 |
15 files changed, 208 insertions, 50 deletions
@@ -1 +1 @@ -2.8.90 +2.8.91 diff --git a/block/block-backend.c b/block/block-backend.c index 5742c09c2c..0b6377332c 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -65,6 +65,8 @@ struct BlockBackend { bool allow_write_beyond_eof; NotifierList remove_bs_notifiers, insert_bs_notifiers; + + int quiesce_counter; }; typedef struct BlockBackendAIOCB { @@ -699,12 +701,17 @@ void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, void *opaque) { /* All drivers that use blk_set_dev_ops() are qdevified and we want to keep - * it that way, so we can assume blk->dev is a DeviceState if blk->dev_ops - * is set. */ + * it that way, so we can assume blk->dev, if present, is a DeviceState if + * blk->dev_ops is set. Non-device users may use dev_ops without device. */ assert(!blk->legacy_dev); blk->dev_ops = ops; blk->dev_opaque = opaque; + + /* Are we currently quiesced? Should we enforce this right now? */ + if (blk->quiesce_counter && ops->drained_begin) { + ops->drained_begin(opaque); + } } /* @@ -1870,6 +1877,12 @@ static void blk_root_drained_begin(BdrvChild *child) { BlockBackend *blk = child->opaque; + if (++blk->quiesce_counter == 1) { + if (blk->dev_ops && blk->dev_ops->drained_begin) { + blk->dev_ops->drained_begin(blk->dev_opaque); + } + } + /* Note that blk->root may not be accessible here yet if we are just * attaching to a BlockDriverState that is drained. Use child instead. */ @@ -1881,7 +1894,14 @@ static void blk_root_drained_begin(BdrvChild *child) static void blk_root_drained_end(BdrvChild *child) { BlockBackend *blk = child->opaque; + assert(blk->quiesce_counter); assert(blk->public.io_limits_disabled); --blk->public.io_limits_disabled; + + if (--blk->quiesce_counter == 0) { + if (blk->dev_ops && blk->dev_ops->drained_end) { + blk->dev_ops->drained_end(blk->dev_opaque); + } + } } diff --git a/block/parallels.c b/block/parallels.c index 19935e29a9..6bf93753e8 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -114,7 +114,7 @@ static QemuOptsList parallels_runtime_opts = { .name = PARALLELS_OPT_PREALLOC_SIZE, .type = QEMU_OPT_SIZE, .help = "Preallocation size on image expansion", - .def_value_str = "128MiB", + .def_value_str = "128M", }, { .name = PARALLELS_OPT_PREALLOC_MODE, diff --git a/blockjob.c b/blockjob.c index 69126af97f..9b619f385a 100644 --- a/blockjob.c +++ b/blockjob.c @@ -68,6 +68,23 @@ static const BdrvChildRole child_job = { .stay_at_node = true, }; +static void block_job_drained_begin(void *opaque) +{ + BlockJob *job = opaque; + block_job_pause(job); +} + +static void block_job_drained_end(void *opaque) +{ + BlockJob *job = opaque; + block_job_resume(job); +} + +static const BlockDevOps block_job_dev_ops = { + .drained_begin = block_job_drained_begin, + .drained_end = block_job_drained_end, +}; + BlockJob *block_job_next(BlockJob *job) { if (!job) { @@ -205,11 +222,6 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver, } job = g_malloc0(driver->instance_size); - error_setg(&job->blocker, "block device is in use by block job: %s", - BlockJobType_lookup[driver->job_type]); - block_job_add_bdrv(job, "main node", bs, 0, BLK_PERM_ALL, &error_abort); - bdrv_op_unblock(bs, BLOCK_OP_TYPE_DATAPLANE, job->blocker); - job->driver = driver; job->id = g_strdup(job_id); job->blk = blk; @@ -219,8 +231,15 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver, job->paused = true; job->pause_count = 1; job->refcnt = 1; + + error_setg(&job->blocker, "block device is in use by block job: %s", + BlockJobType_lookup[driver->job_type]); + block_job_add_bdrv(job, "main node", bs, 0, BLK_PERM_ALL, &error_abort); bs->job = job; + blk_set_dev_ops(blk, &block_job_dev_ops, job); + bdrv_op_unblock(bs, BLOCK_OP_TYPE_DATAPLANE, job->blocker); + QLIST_INSERT_HEAD(&block_jobs, job, job_list); blk_add_aio_context_notifier(blk, block_job_attached_aio_context, @@ -250,16 +269,28 @@ static bool block_job_started(BlockJob *job) return job->co; } +/** + * All jobs must allow a pause point before entering their job proper. This + * ensures that jobs can be paused prior to being started, then resumed later. + */ +static void coroutine_fn block_job_co_entry(void *opaque) +{ + BlockJob *job = opaque; + + assert(job && job->driver && job->driver->start); + block_job_pause_point(job); + job->driver->start(job); +} + void block_job_start(BlockJob *job) { assert(job && !block_job_started(job) && job->paused && - !job->busy && job->driver->start); - job->co = qemu_coroutine_create(job->driver->start, job); - if (--job->pause_count == 0) { - job->paused = false; - job->busy = true; - qemu_coroutine_enter(job->co); - } + job->driver && job->driver->start); + job->co = qemu_coroutine_create(block_job_co_entry, job); + job->pause_count--; + job->busy = true; + job->paused = false; + qemu_coroutine_enter(job->co); } void block_job_ref(BlockJob *job) @@ -755,12 +786,16 @@ static void block_job_defer_to_main_loop_bh(void *opaque) /* Fetch BDS AioContext again, in case it has changed */ aio_context = blk_get_aio_context(data->job->blk); - aio_context_acquire(aio_context); + if (aio_context != data->aio_context) { + aio_context_acquire(aio_context); + } data->job->deferred_to_main_loop = false; data->fn(data->job, data->opaque); - aio_context_release(aio_context); + if (aio_context != data->aio_context) { + aio_context_release(aio_context); + } aio_context_release(data->aio_context); @@ -321,6 +321,9 @@ tcmalloc="no" jemalloc="no" replication="yes" +supported_cpu="no" +supported_os="no" + # parse CC options first for opt do optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)') @@ -517,23 +520,32 @@ ARCH= # Normalise host CPU name and set ARCH. # Note that this case should only have supported host CPUs, not guests. case "$cpu" in - ia64|ppc|ppc64|s390|s390x|sparc64|x32) + ppc|ppc64|s390|s390x|x32) + cpu="$cpu" + supported_cpu="yes" + ;; + ia64|sparc64) cpu="$cpu" ;; i386|i486|i586|i686|i86pc|BePC) cpu="i386" + supported_cpu="yes" ;; x86_64|amd64) cpu="x86_64" + supported_cpu="yes" ;; armv*b|armv*l|arm) cpu="arm" + supported_cpu="yes" ;; aarch64) cpu="aarch64" + supported_cpu="yes" ;; mips*) cpu="mips" + supported_cpu="yes" ;; sparc|sun4[cdmuv]) cpu="sparc" @@ -562,6 +574,7 @@ MINGW32*) else audio_drv_list="" fi + supported_os="yes" ;; GNU/kFreeBSD) bsd="yes" @@ -579,6 +592,7 @@ FreeBSD) libs_qga="-lutil $libs_qga" netmap="" # enable netmap autodetect HOST_VARIANT_DIR="freebsd" + supported_os="yes" ;; DragonFly) bsd="yes" @@ -620,6 +634,7 @@ Darwin) # won't work when we're compiling with gcc as a C compiler. QEMU_CFLAGS="-DOS_OBJECT_USE_OBJC=0 $QEMU_CFLAGS" HOST_VARIANT_DIR="darwin" + supported_os="yes" ;; SunOS) solaris="yes" @@ -666,7 +681,7 @@ Haiku) QEMU_CFLAGS="-DB_USE_POSITIVE_POSIX_ERRORS $QEMU_CFLAGS" LIBS="-lposix_error_mapper -lnetwork $LIBS" ;; -*) +Linux) audio_drv_list="oss" audio_possible_drivers="oss alsa sdl pa" linux="yes" @@ -676,6 +691,10 @@ Haiku) vhost_scsi="yes" vhost_vsock="yes" QEMU_INCLUDES="-I\$(SRC_PATH)/linux-headers -I$(pwd)/linux-headers $QEMU_INCLUDES" + supported_os="yes" +;; +*) + error_exit "Unsupported host OS $targetos" ;; esac @@ -3449,6 +3468,7 @@ if test "$opengl" != "no" ; then if test "$gtk" = "yes" && $pkg_config --exists "$gtkpackage >= 3.16"; then gtk_gl="yes" fi + QEMU_CFLAGS="$QEMU_CFLAGS $opengl_cflags" else if test "$opengl" = "yes" ; then feature_not_found "opengl" "Please install opengl (mesa) devel pkgs: $opengl_pkgs" @@ -5107,6 +5127,32 @@ if test "$sdl_too_old" = "yes"; then echo "-> Your SDL version is too old - please upgrade to have SDL support" fi +if test "$supported_cpu" = "no"; then + echo + echo "WARNING: SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!" + echo + echo "CPU host architecture $cpu support is not currently maintained." + echo "The QEMU project intends to remove support for this host CPU in" + echo "a future release if nobody volunteers to maintain it and to" + echo "provide a build host for our continuous integration setup." + echo "configure has succeeded and you can continue to build, but" + echo "if you care about QEMU on this platform you should contact" + echo "us upstream at qemu-devel@nongnu.org." +fi + +if test "$supported_os" = "no"; then + echo + echo "WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!" + echo + echo "CPU host OS $targetos support is not currently maintained." + echo "The QEMU project intends to remove support for this host CPU in" + echo "a future release if nobody volunteers to maintain it and to" + echo "provide a build host for our continuous integration setup." + echo "configure has succeeded and you can continue to build, but" + echo "if you care about QEMU on this platform you should contact" + echo "us upstream at qemu-devel@nongnu.org." +fi + config_host_mak="config-host.mak" echo "# Automatically generated by configure - do not modify" >config-all-disas.mak @@ -5503,7 +5549,6 @@ fi if test "$opengl" = "yes" ; then echo "CONFIG_OPENGL=y" >> $config_host_mak - echo "OPENGL_CFLAGS=$opengl_cflags" >> $config_host_mak echo "OPENGL_LIBS=$opengl_libs" >> $config_host_mak if test "$opengl_dmabuf" = "yes" ; then echo "CONFIG_OPENGL_DMABUF=y" >> $config_host_mak diff --git a/hw/9pfs/9p-proxy.c b/hw/9pfs/9p-proxy.c index f4aa7a9d70..28b20a7c3d 100644 --- a/hw/9pfs/9p-proxy.c +++ b/hw/9pfs/9p-proxy.c @@ -165,7 +165,8 @@ static int v9fs_receive_response(V9fsProxy *proxy, int type, return retval; } reply->iov_len = PROXY_HDR_SZ; - proxy_unmarshal(reply, 0, "dd", &header.type, &header.size); + retval = proxy_unmarshal(reply, 0, "dd", &header.type, &header.size); + assert(retval == 4 * 2); /* * if response size > PROXY_MAX_IO_SZ, read the response but ignore it and * return -ENOBUFS @@ -194,9 +195,7 @@ static int v9fs_receive_response(V9fsProxy *proxy, int type, if (header.type == T_ERROR) { int ret; ret = proxy_unmarshal(reply, PROXY_HDR_SZ, "d", status); - if (ret < 0) { - *status = ret; - } + assert(ret == 4); return 0; } @@ -213,6 +212,7 @@ static int v9fs_receive_response(V9fsProxy *proxy, int type, &prstat.st_atim_sec, &prstat.st_atim_nsec, &prstat.st_mtim_sec, &prstat.st_mtim_nsec, &prstat.st_ctim_sec, &prstat.st_ctim_nsec); + assert(retval == 8 * 3 + 4 * 3 + 8 * 10); prstat_to_stat(response, &prstat); break; } @@ -225,6 +225,7 @@ static int v9fs_receive_response(V9fsProxy *proxy, int type, &prstfs.f_files, &prstfs.f_ffree, &prstfs.f_fsid[0], &prstfs.f_fsid[1], &prstfs.f_namelen, &prstfs.f_frsize); + assert(retval == 8 * 11); prstatfs_to_statfs(response, &prstfs); break; } @@ -246,7 +247,8 @@ static int v9fs_receive_response(V9fsProxy *proxy, int type, break; } case T_GETVERSION: - proxy_unmarshal(reply, PROXY_HDR_SZ, "q", response); + retval = proxy_unmarshal(reply, PROXY_HDR_SZ, "q", response); + assert(retval == 8); break; default: return -1; @@ -274,18 +276,16 @@ static int v9fs_receive_status(V9fsProxy *proxy, return retval; } reply->iov_len = PROXY_HDR_SZ; - proxy_unmarshal(reply, 0, "dd", &header.type, &header.size); - if (header.size != sizeof(int)) { - *status = -ENOBUFS; - return 0; - } + retval = proxy_unmarshal(reply, 0, "dd", &header.type, &header.size); + assert(retval == 4 * 2); retval = socket_read(proxy->sockfd, reply->iov_base + PROXY_HDR_SZ, header.size); if (retval < 0) { return retval; } reply->iov_len += header.size; - proxy_unmarshal(reply, PROXY_HDR_SZ, "d", status); + retval = proxy_unmarshal(reply, PROXY_HDR_SZ, "d", status); + assert(retval == 4); return 0; } diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c index 76c9247c77..b8c0b99358 100644 --- a/hw/9pfs/9p.c +++ b/hw/9pfs/9p.c @@ -2353,7 +2353,7 @@ static void coroutine_fn v9fs_flush(void *opaque) ssize_t err; int16_t tag; size_t offset = 7; - V9fsPDU *cancel_pdu; + V9fsPDU *cancel_pdu = NULL; V9fsPDU *pdu = opaque; V9fsState *s = pdu->s; @@ -2364,9 +2364,13 @@ static void coroutine_fn v9fs_flush(void *opaque) } trace_v9fs_flush(pdu->tag, pdu->id, tag); - QLIST_FOREACH(cancel_pdu, &s->active_list, next) { - if (cancel_pdu->tag == tag) { - break; + if (pdu->tag == tag) { + error_report("Warning: the guest sent a self-referencing 9P flush request"); + } else { + QLIST_FOREACH(cancel_pdu, &s->active_list, next) { + if (cancel_pdu->tag == tag) { + break; + } } } if (cancel_pdu) { diff --git a/hw/acpi/vmgenid.c b/hw/acpi/vmgenid.c index 7a3ad17d66..a32b847fe0 100644 --- a/hw/acpi/vmgenid.c +++ b/hw/acpi/vmgenid.c @@ -205,9 +205,30 @@ static void vmgenid_handle_reset(void *opaque) memset(vms->vmgenid_addr_le, 0, ARRAY_SIZE(vms->vmgenid_addr_le)); } +static Property vmgenid_properties[] = { + DEFINE_PROP_BOOL("x-write-pointer-available", VmGenIdState, + write_pointer_available, true), + DEFINE_PROP_END_OF_LIST(), +}; + static void vmgenid_realize(DeviceState *dev, Error **errp) { VmGenIdState *vms = VMGENID(dev); + + if (!vms->write_pointer_available) { + error_setg(errp, "%s requires DMA write support in fw_cfg, " + "which this machine type does not provide", VMGENID_DEVICE); + return; + } + + /* Given that this function is executing, there is at least one VMGENID + * device. Check if there are several. + */ + if (!find_vmgenid_dev()) { + error_setg(errp, "at most one %s device is permitted", VMGENID_DEVICE); + return; + } + qemu_register_reset(vmgenid_handle_reset, vms); } @@ -218,6 +239,7 @@ static void vmgenid_device_class_init(ObjectClass *klass, void *data) dc->vmsd = &vmstate_vmgenid; dc->realize = vmgenid_realize; dc->hotpluggable = false; + dc->props = vmgenid_properties; object_class_property_add_str(klass, VMGENID_GUID, NULL, vmgenid_set_guid, NULL); diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs index 3d02e8bfc5..551c050a6a 100644 --- a/hw/display/Makefile.objs +++ b/hw/display/Makefile.objs @@ -18,11 +18,7 @@ common-obj-$(CONFIG_FRAMEBUFFER) += framebuffer.o common-obj-$(CONFIG_MILKYMIST) += milkymist-vgafb.o common-obj-$(CONFIG_ZAURUS) += tc6393xb.o -ifeq ($(CONFIG_MILKYMIST_TMU2),y) -common-obj-y += milkymist-tmu2.o -milkymist-tmu2.o-cflags := $(OPENGL_CFLAGS) -milkymist-tmu2.o-libs += $(OPENGL_LIBS) -endif +common-obj-$(CONFIG_MILKYMIST_TMU2) += milkymist-tmu2.o obj-$(CONFIG_OMAP) += omap_dss.o obj-$(CONFIG_OMAP) += omap_lcdc.o diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c index a886011e75..3042232daf 100644 --- a/hw/virtio/virtio-bus.c +++ b/hw/virtio/virtio-bus.c @@ -25,6 +25,7 @@ #include "qemu/osdep.h" #include "hw/hw.h" #include "qemu/error-report.h" +#include "qapi/error.h" #include "hw/qdev.h" #include "hw/virtio/virtio-bus.h" #include "hw/virtio/virtio.h" @@ -48,20 +49,33 @@ void virtio_bus_device_plugged(VirtIODevice *vdev, Error **errp) VirtioBusClass *klass = VIRTIO_BUS_GET_CLASS(bus); VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev); bool has_iommu = virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM); + Error *local_err = NULL; DPRINTF("%s: plug device.\n", qbus->name); if (klass->pre_plugged != NULL) { - klass->pre_plugged(qbus->parent, errp); + klass->pre_plugged(qbus->parent, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } } /* Get the features of the plugged device. */ assert(vdc->get_features != NULL); vdev->host_features = vdc->get_features(vdev, vdev->host_features, - errp); + &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } if (klass->device_plugged != NULL) { - klass->device_plugged(qbus->parent, errp); + klass->device_plugged(qbus->parent, &local_err); + } + if (local_err) { + error_propagate(errp, local_err); + return; } if (klass->get_dma_as != NULL && has_iommu) { diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 82b6060b2a..03592c542a 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -1528,7 +1528,18 @@ static void virtio_queue_notify_vq(VirtQueue *vq) void virtio_queue_notify(VirtIODevice *vdev, int n) { - virtio_queue_notify_vq(&vdev->vq[n]); + VirtQueue *vq = &vdev->vq[n]; + + if (unlikely(!vq->vring.desc || vdev->broken)) { + return; + } + + trace_virtio_queue_notify(vdev, vq - vdev->vq, vq); + if (vq->handle_aio_output) { + event_notifier_set(&vq->host_notifier); + } else if (vq->handle_output) { + vq->handle_output(vdev, vq); + } } uint16_t virtio_queue_vector(VirtIODevice *vdev, int n) diff --git a/include/hw/acpi/vmgenid.h b/include/hw/acpi/vmgenid.h index db7fa0e633..7beb9592fb 100644 --- a/include/hw/acpi/vmgenid.h +++ b/include/hw/acpi/vmgenid.h @@ -21,8 +21,10 @@ typedef struct VmGenIdState { DeviceClass parent_obj; QemuUUID guid; /* The 128-bit GUID seen by the guest */ uint8_t vmgenid_addr_le[8]; /* Address of the GUID (little-endian) */ + bool write_pointer_available; } VmGenIdState; +/* returns NULL unless there is exactly one device */ static inline Object *find_vmgenid_dev(void) { return object_resolve_path_type("", VMGENID_DEVICE, NULL); diff --git a/include/hw/compat.h b/include/hw/compat.h index fc8c3e0600..5d5be91daf 100644 --- a/include/hw/compat.h +++ b/include/hw/compat.h @@ -131,6 +131,10 @@ .driver = "fw_cfg_io",\ .property = "dma_enabled",\ .value = "off",\ + },{\ + .driver = "vmgenid",\ + .property = "x-write-pointer-available",\ + .value = "off",\ }, #define HW_COMPAT_2_3 \ diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h index 096c17fce0..7462228ac1 100644 --- a/include/sysemu/block-backend.h +++ b/include/sysemu/block-backend.h @@ -58,6 +58,14 @@ typedef struct BlockDevOps { * Runs when the size changed (e.g. monitor command block_resize) */ void (*resize_cb)(void *opaque); + /* + * Runs when the backend receives a drain request. + */ + void (*drained_begin)(void *opaque); + /* + * Runs when the backend's last drain request ends. + */ + void (*drained_end)(void *opaque); } BlockDevOps; /* This struct is embedded in (the private) BlockBackend struct and contains diff --git a/ui/Makefile.objs b/ui/Makefile.objs index dc936f150e..27566b32f1 100644 --- a/ui/Makefile.objs +++ b/ui/Makefile.objs @@ -41,11 +41,8 @@ endif endif gtk.o-cflags := $(GTK_CFLAGS) $(VTE_CFLAGS) -gtk-egl.o-cflags := $(GTK_CFLAGS) $(VTE_CFLAGS) $(OPENGL_CFLAGS) -gtk-gl-area.o-cflags := $(GTK_CFLAGS) $(VTE_CFLAGS) $(OPENGL_CFLAGS) -shader.o-cflags += $(OPENGL_CFLAGS) -console-gl.o-cflags += $(OPENGL_CFLAGS) -egl-helpers.o-cflags += $(OPENGL_CFLAGS) +gtk-egl.o-cflags := $(GTK_CFLAGS) $(VTE_CFLAGS) +gtk-gl-area.o-cflags := $(GTK_CFLAGS) $(VTE_CFLAGS) gtk-egl.o-libs += $(OPENGL_LIBS) shader.o-libs += $(OPENGL_LIBS) |