From 3e2b2a9c49f44926b995495be5e94e61e4f29f5e Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Sun, 19 Oct 2014 12:47:42 +0800 Subject: [PATCH 01/28] virtio-scsi-dataplane: Add op blocker We need this to protect dataplane thread from race conditions with block jobs until the latter is made dataplane-safe. Signed-off-by: Fam Zheng Signed-off-by: Paolo Bonzini --- hw/scsi/virtio-scsi-dataplane.c | 4 ++++ hw/scsi/virtio-scsi.c | 19 +++++++++++++++++-- include/hw/virtio/virtio-scsi.h | 1 + 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c index 48dcfd2852..1f77635774 100644 --- a/hw/scsi/virtio-scsi-dataplane.c +++ b/hw/scsi/virtio-scsi-dataplane.c @@ -155,6 +155,8 @@ void virtio_scsi_dataplane_start(VirtIOSCSI *s) s->dataplane_starting = true; + assert(!s->blocker); + error_setg(&s->blocker, "block device is in use by data plane"); /* Set up guest notifier (irq) */ rc = k->set_guest_notifiers(qbus->parent, vs->conf.num_queues + 2, true); if (rc != 0) { @@ -195,6 +197,8 @@ void virtio_scsi_dataplane_stop(VirtIOSCSI *s) if (!s->dataplane_started || s->dataplane_stopping) { return; } + error_free(s->blocker); + s->blocker = NULL; s->dataplane_stopping = true; assert(s->ctx == iothread_get_aio_context(vs->conf.iothread)); diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index a1725b8f48..2d2612bf05 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -742,9 +742,18 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { VirtIODevice *vdev = VIRTIO_DEVICE(hotplug_dev); + VirtIOSCSI *s = VIRTIO_SCSI(vdev); + SCSIDevice *sd = SCSI_DEVICE(dev); + + if (s->ctx && !s->dataplane_disabled) { + if (blk_op_is_blocked(sd->conf.blk, BLOCK_OP_TYPE_DATAPLANE, errp)) { + return; + } + blk_op_block_all(sd->conf.blk, s->blocker); + } if ((vdev->guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) { - virtio_scsi_push_event(VIRTIO_SCSI(hotplug_dev), SCSI_DEVICE(dev), + virtio_scsi_push_event(s, sd, VIRTIO_SCSI_T_TRANSPORT_RESET, VIRTIO_SCSI_EVT_RESET_RESCAN); } @@ -754,12 +763,18 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { VirtIODevice *vdev = VIRTIO_DEVICE(hotplug_dev); + VirtIOSCSI *s = VIRTIO_SCSI(vdev); + SCSIDevice *sd = SCSI_DEVICE(dev); if ((vdev->guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) { - virtio_scsi_push_event(VIRTIO_SCSI(hotplug_dev), SCSI_DEVICE(dev), + virtio_scsi_push_event(s, sd, VIRTIO_SCSI_T_TRANSPORT_RESET, VIRTIO_SCSI_EVT_RESET_REMOVED); } + + if (s->ctx) { + blk_op_unblock_all(sd->conf.blk, s->blocker); + } qdev_simple_device_unplug_cb(hotplug_dev, dev, errp); } diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h index d6e5e7935c..1ce08581ea 100644 --- a/include/hw/virtio/virtio-scsi.h +++ b/include/hw/virtio/virtio-scsi.h @@ -195,6 +195,7 @@ typedef struct VirtIOSCSI { bool dataplane_starting; bool dataplane_stopping; bool dataplane_disabled; + Error *blocker; Notifier migration_state_notifier; } VirtIOSCSI; From 6d2c83165bc981536f248dd9e3f25bf132b35867 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Wed, 15 Oct 2014 15:15:24 +0200 Subject: [PATCH 02/28] virtio-scsi: dataplane: print why starting failed Setting up guest or host notifiers may fail, but the user will have no idea why: Let's print the error returned by the callback. Signed-off-by: Cornelia Huck Signed-off-by: Paolo Bonzini --- hw/scsi/virtio-scsi-dataplane.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c index 1f77635774..999c783fa6 100644 --- a/hw/scsi/virtio-scsi-dataplane.c +++ b/hw/scsi/virtio-scsi-dataplane.c @@ -46,10 +46,13 @@ static VirtIOSCSIVring *virtio_scsi_vring_init(VirtIOSCSI *s, BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(s))); VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); VirtIOSCSIVring *r = g_slice_new(VirtIOSCSIVring); + int rc; /* Set up virtqueue notify */ - if (k->set_host_notifier(qbus->parent, n, true) != 0) { - fprintf(stderr, "virtio-scsi: Failed to set host notifier\n"); + rc = k->set_host_notifier(qbus->parent, n, true); + if (rc != 0) { + fprintf(stderr, "virtio-scsi: Failed to set host notifier (%d)\n", + rc); exit(1); } r->host_notifier = *virtio_queue_get_host_notifier(vq); @@ -160,8 +163,8 @@ void virtio_scsi_dataplane_start(VirtIOSCSI *s) /* Set up guest notifier (irq) */ rc = k->set_guest_notifiers(qbus->parent, vs->conf.num_queues + 2, true); if (rc != 0) { - fprintf(stderr, "virtio-scsi: Failed to set guest notifiers, " - "ensure -enable-kvm is set\n"); + fprintf(stderr, "virtio-scsi: Failed to set guest notifiers (%d), " + "ensure -enable-kvm is set\n", rc); exit(1); } From 361dcc790db8c87b2e46ab610739191ced894c44 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Wed, 15 Oct 2014 15:15:25 +0200 Subject: [PATCH 03/28] virtio-scsi: dataplane: fail setup gracefully The dataplane code is currently doing a hard exit on various setup failures. In practice, this may mean that a guest suddenly dies after a dataplane device failed to come up (e.g., when a file descriptor limit is hit for the nth device). Let's just try to unwind the setup instead and return. Signed-off-by: Cornelia Huck Signed-off-by: Paolo Bonzini --- hw/scsi/virtio-scsi-dataplane.c | 79 +++++++++++++++++++++++++++++---- 1 file changed, 70 insertions(+), 9 deletions(-) diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c index 999c783fa6..243a4765e9 100644 --- a/hw/scsi/virtio-scsi-dataplane.c +++ b/hw/scsi/virtio-scsi-dataplane.c @@ -53,7 +53,7 @@ static VirtIOSCSIVring *virtio_scsi_vring_init(VirtIOSCSI *s, if (rc != 0) { fprintf(stderr, "virtio-scsi: Failed to set host notifier (%d)\n", rc); - exit(1); + return NULL; } r->host_notifier = *virtio_queue_get_host_notifier(vq); r->guest_notifier = *virtio_queue_get_guest_notifier(vq); @@ -63,9 +63,15 @@ static VirtIOSCSIVring *virtio_scsi_vring_init(VirtIOSCSI *s, if (!vring_setup(&r->vring, VIRTIO_DEVICE(s), n)) { fprintf(stderr, "virtio-scsi: VRing setup failed\n"); - exit(1); + goto fail_vring; } return r; + +fail_vring: + aio_set_event_notifier(s->ctx, &r->host_notifier, NULL); + k->set_host_notifier(qbus->parent, n, false); + g_slice_free(VirtIOSCSIVring, r); + return NULL; } VirtIOSCSIReq *virtio_scsi_pop_req_vring(VirtIOSCSI *s, @@ -141,6 +147,46 @@ static void virtio_scsi_iothread_handle_cmd(EventNotifier *notifier) } } +/* assumes s->ctx held */ +static void virtio_scsi_clear_aio(VirtIOSCSI *s) +{ + VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s); + int i; + + if (s->ctrl_vring) { + aio_set_event_notifier(s->ctx, &s->ctrl_vring->host_notifier, NULL); + } + if (s->event_vring) { + aio_set_event_notifier(s->ctx, &s->event_vring->host_notifier, NULL); + } + if (s->cmd_vrings) { + for (i = 0; i < vs->conf.num_queues && s->cmd_vrings[i]; i++) { + aio_set_event_notifier(s->ctx, &s->cmd_vrings[i]->host_notifier, NULL); + } + } +} + +static void virtio_scsi_vring_teardown(VirtIOSCSI *s) +{ + VirtIODevice *vdev = VIRTIO_DEVICE(s); + VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s); + int i; + + if (s->ctrl_vring) { + vring_teardown(&s->ctrl_vring->vring, vdev, 0); + } + if (s->event_vring) { + vring_teardown(&s->event_vring->vring, vdev, 1); + } + if (s->cmd_vrings) { + for (i = 0; i < vs->conf.num_queues && s->cmd_vrings[i]; i++) { + vring_teardown(&s->cmd_vrings[i]->vring, vdev, 2 + i); + } + free(s->cmd_vrings); + s->cmd_vrings = NULL; + } +} + /* Context: QEMU global mutex held */ void virtio_scsi_dataplane_start(VirtIOSCSI *s) { @@ -165,27 +211,47 @@ void virtio_scsi_dataplane_start(VirtIOSCSI *s) if (rc != 0) { fprintf(stderr, "virtio-scsi: Failed to set guest notifiers (%d), " "ensure -enable-kvm is set\n", rc); - exit(1); + goto fail_guest_notifiers; } aio_context_acquire(s->ctx); s->ctrl_vring = virtio_scsi_vring_init(s, vs->ctrl_vq, virtio_scsi_iothread_handle_ctrl, 0); + if (!s->ctrl_vring) { + goto fail_vrings; + } s->event_vring = virtio_scsi_vring_init(s, vs->event_vq, virtio_scsi_iothread_handle_event, 1); + if (!s->event_vring) { + goto fail_vrings; + } s->cmd_vrings = g_malloc0(sizeof(VirtIOSCSIVring) * vs->conf.num_queues); for (i = 0; i < vs->conf.num_queues; i++) { s->cmd_vrings[i] = virtio_scsi_vring_init(s, vs->cmd_vqs[i], virtio_scsi_iothread_handle_cmd, i + 2); + if (!s->cmd_vrings[i]) { + goto fail_vrings; + } } aio_context_release(s->ctx); s->dataplane_starting = false; s->dataplane_started = true; + +fail_vrings: + virtio_scsi_clear_aio(s); + aio_context_release(s->ctx); + virtio_scsi_vring_teardown(s); + for (i = 0; i < vs->conf.num_queues + 2; i++) { + k->set_host_notifier(qbus->parent, i, false); + } + k->set_guest_notifiers(qbus->parent, vs->conf.num_queues + 2, false); +fail_guest_notifiers: + s->dataplane_starting = false; } /* Context: QEMU global mutex held */ @@ -193,7 +259,6 @@ void virtio_scsi_dataplane_stop(VirtIOSCSI *s) { BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(s))); VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); - VirtIODevice *vdev = VIRTIO_DEVICE(s); VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s); int i; @@ -220,11 +285,7 @@ void virtio_scsi_dataplane_stop(VirtIOSCSI *s) /* Sync vring state back to virtqueue so that non-dataplane request * processing can continue when we disable the host notifier below. */ - vring_teardown(&s->ctrl_vring->vring, vdev, 0); - vring_teardown(&s->event_vring->vring, vdev, 1); - for (i = 0; i < vs->conf.num_queues; i++) { - vring_teardown(&s->cmd_vrings[i]->vring, vdev, 2 + i); - } + virtio_scsi_vring_teardown(s); for (i = 0; i < vs->conf.num_queues + 2; i++) { k->set_host_notifier(qbus->parent, i, false); From 4adea8042f880dd9bd7cb5c191a781ec86fdc587 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Wed, 15 Oct 2014 15:15:26 +0200 Subject: [PATCH 04/28] virtio-scsi: dataplane: stop trying on notifier error There's no use to constantly trying to enable dataplane if we failed to set up guest or host notifiers, so fence it off in that case. We'll try again if the device is reinitialized. Signed-off-by: Cornelia Huck Signed-off-by: Paolo Bonzini --- hw/scsi/virtio-scsi-dataplane.c | 8 ++++++++ include/hw/virtio/virtio-scsi.h | 1 + 2 files changed, 9 insertions(+) diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c index 243a4765e9..3097d544b4 100644 --- a/hw/scsi/virtio-scsi-dataplane.c +++ b/hw/scsi/virtio-scsi-dataplane.c @@ -53,6 +53,7 @@ static VirtIOSCSIVring *virtio_scsi_vring_init(VirtIOSCSI *s, if (rc != 0) { fprintf(stderr, "virtio-scsi: Failed to set host notifier (%d)\n", rc); + s->dataplane_fenced = true; return NULL; } r->host_notifier = *virtio_queue_get_host_notifier(vq); @@ -198,6 +199,7 @@ void virtio_scsi_dataplane_start(VirtIOSCSI *s) if (s->dataplane_started || s->dataplane_starting || + s->dataplane_fenced || s->ctx != iothread_get_aio_context(vs->conf.iothread)) { return; } @@ -211,6 +213,7 @@ void virtio_scsi_dataplane_start(VirtIOSCSI *s) if (rc != 0) { fprintf(stderr, "virtio-scsi: Failed to set guest notifiers (%d), " "ensure -enable-kvm is set\n", rc); + s->dataplane_fenced = true; goto fail_guest_notifiers; } @@ -262,6 +265,11 @@ void virtio_scsi_dataplane_stop(VirtIOSCSI *s) VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s); int i; + /* Better luck next time. */ + if (s->dataplane_fenced) { + s->dataplane_fenced = false; + return; + } if (!s->dataplane_started || s->dataplane_stopping) { return; } diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h index 1ce08581ea..9e1a49c2c1 100644 --- a/include/hw/virtio/virtio-scsi.h +++ b/include/hw/virtio/virtio-scsi.h @@ -195,6 +195,7 @@ typedef struct VirtIOSCSI { bool dataplane_starting; bool dataplane_stopping; bool dataplane_disabled; + bool dataplane_fenced; Error *blocker; Notifier migration_state_notifier; } VirtIOSCSI; From d3c4931647c16c2ffc09a2c7c80d71c73cd026c6 Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 25 Sep 2014 22:19:19 -0700 Subject: [PATCH 05/28] qom: Allow clearing of a Link property By passing in "" to object_property_set_link. The lead user of this is the QDEV GPIO framework which will implement GPIO disconnects via an "unlink". GPIO disconnection is used by qtest's irq_intercept_out command. Reviewed-by: Alexander Graf Signed-off-by: Peter Crosthwaite Signed-off-by: Paolo Bonzini --- qom/object.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/qom/object.c b/qom/object.c index a751367e61..c7ef776b4e 100644 --- a/qom/object.c +++ b/qom/object.c @@ -872,9 +872,13 @@ char *object_property_get_str(Object *obj, const char *name, void object_property_set_link(Object *obj, Object *value, const char *name, Error **errp) { - gchar *path = object_get_canonical_path(value); - object_property_set_str(obj, path, name, errp); - g_free(path); + if (value) { + gchar *path = object_get_canonical_path(value); + object_property_set_str(obj, path, name, errp); + g_free(path); + } else { + object_property_set_str(obj, "", name, errp); + } } Object *object_property_get_link(Object *obj, const char *name, From 8faa2f8571e399ba486bad00e25b6c9b22b6fd9a Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 25 Sep 2014 22:19:52 -0700 Subject: [PATCH 06/28] qom: Demote already-has-a-parent to a regular error Rather than an abort(). This allows callers to decide whether parenting an already-parented object is a fatal error condition. Useful for providing a default value for an object's parent in the case where you want to set one iff it doesn't already have one. Reviewed-by: Alexander Graf Signed-off-by: Peter Crosthwaite Signed-off-by: Paolo Bonzini --- qom/object.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/qom/object.c b/qom/object.c index c7ef776b4e..1812c73327 100644 --- a/qom/object.c +++ b/qom/object.c @@ -1089,6 +1089,11 @@ void object_property_add_child(Object *obj, const char *name, gchar *type; ObjectProperty *op; + if (child->parent != NULL) { + error_setg(errp, "child object is already parented"); + return; + } + type = g_strdup_printf("child<%s>", object_get_typename(OBJECT(child))); op = object_property_add(obj, name, type, object_get_child_property, NULL, @@ -1100,7 +1105,6 @@ void object_property_add_child(Object *obj, const char *name, op->resolve = object_resolve_child_property; object_ref(child); - g_assert(child->parent == NULL); child->parent = obj; out: From 02757df2ad2d5dfc96482e2cdfa046f439dafc3d Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 25 Sep 2014 22:20:25 -0700 Subject: [PATCH 07/28] qdev: gpio: Re-implement qdev_connect_gpio QOM style Re-implement as a link setter. This should allow the QOM framework to keep track of ref counts properly etc. We need to add a default parent for the connecting input incase it's coming from a non-qdev source. We simply parent the IRQ to the machine in this case. Reviewed-by: Alexander Graf Signed-off-by: Peter Crosthwaite Signed-off-by: Paolo Bonzini --- hw/core/qdev.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index a1e9247772..fc7860f0bb 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -440,10 +440,19 @@ qemu_irq qdev_get_gpio_in(DeviceState *dev, int n) void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n, qemu_irq pin) { - NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name); - - assert(n >= 0 && n < gpio_list->num_out); - gpio_list->out[n] = pin; + char *propname = g_strdup_printf("%s[%d]", + name ? name : "unnamed-gpio-out", n); + if (pin) { + /* We need a name for object_property_set_link to work. If the + * object has a parent, object_property_add_child will come back + * with an error without doing anything. If it has none, it will + * never fail. So we can just call it with a NULL Error pointer. + */ + object_property_add_child(qdev_get_machine(), "non-qdev-gpio[*]", + OBJECT(pin), NULL); + } + object_property_set_link(OBJECT(dev), OBJECT(pin), propname, &error_abort); + g_free(propname); } void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin) From 0c24db2b8c60cb578d7af6fb50c0ad60a723a02d Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 25 Sep 2014 22:20:58 -0700 Subject: [PATCH 08/28] qdev: gpio: Add API for intercepting a GPIO To replace the old qemu_irq intercept API (which had users reaching into qdev private state for GPIOs). Reviewed-by: Alexander Graf Signed-off-by: Peter Crosthwaite Signed-off-by: Paolo Bonzini --- hw/core/qdev.c | 25 +++++++++++++++++++++++++ include/hw/qdev-core.h | 2 ++ 2 files changed, 27 insertions(+) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index fc7860f0bb..92f88f6698 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -455,6 +455,31 @@ void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n, g_free(propname); } +/* disconnect a GPIO ouput, returning the disconnected input (if any) */ + +static qemu_irq qdev_disconnect_gpio_out_named(DeviceState *dev, + const char *name, int n) +{ + char *propname = g_strdup_printf("%s[%d]", + name ? name : "unnamed-gpio-out", n); + + qemu_irq ret = (qemu_irq)object_property_get_link(OBJECT(dev), propname, + NULL); + if (ret) { + object_property_set_link(OBJECT(dev), NULL, propname, NULL); + } + g_free(propname); + return ret; +} + +qemu_irq qdev_intercept_gpio_out(DeviceState *dev, qemu_irq icpt, + const char *name, int n) +{ + qemu_irq disconnected = qdev_disconnect_gpio_out_named(dev, name, n); + qdev_connect_gpio_out_named(dev, name, n, icpt); + return disconnected; +} + void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin) { qdev_connect_gpio_out_named(dev, NULL, n, pin); diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 1fca75c591..cf27e6564a 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -273,6 +273,8 @@ qemu_irq qdev_get_gpio_in_named(DeviceState *dev, const char *name, int n); void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin); void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n, qemu_irq pin); +qemu_irq qdev_intercept_gpio_out(DeviceState *dev, qemu_irq icpt, + const char *name, int n); BusState *qdev_get_child_bus(DeviceState *dev, const char *name); From 60a79016aed70c4ebcd45a8006c46dc9c397685a Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 25 Sep 2014 22:21:31 -0700 Subject: [PATCH 09/28] qtest/irq: Rework IRQ interception Change the qtest intercept handler to accept just the individual IRQ being intercepted as opaque. n is still expected to be correctly set as for the original intercepted irq. qemu_intercept_irq_in is updated accordingly. Then covert the qemu_irq_intercept_out call to use qdev intercept version. This stops qtest from having to mess with the raw IRQ pointers (still has to mess with names and counts but a step in the right direction). Reviewed-by: Alexander Graf Signed-off-by: Peter Crosthwaite Signed-off-by: Paolo Bonzini --- hw/core/irq.c | 2 +- qtest.c | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/hw/core/irq.c b/hw/core/irq.c index cffced040f..4a580a22f3 100644 --- a/hw/core/irq.c +++ b/hw/core/irq.c @@ -140,7 +140,7 @@ void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n) for (i = 0; i < n; i++) { *old_irqs[i] = *gpio_in[i]; gpio_in[i]->handler = handler; - gpio_in[i]->opaque = old_irqs; + gpio_in[i]->opaque = &old_irqs[i]; } } diff --git a/qtest.c b/qtest.c index 4b85995de0..946b560d6a 100644 --- a/qtest.c +++ b/qtest.c @@ -201,8 +201,8 @@ static void GCC_FMT_ATTR(2, 3) qtest_send(CharDriverState *chr, static void qtest_irq_handler(void *opaque, int n, int level) { - qemu_irq *old_irqs = opaque; - qemu_set_irq(old_irqs[n], level); + qemu_irq old_irq = *(qemu_irq *)opaque; + qemu_set_irq(old_irq, level); if (irq_levels[n] != level) { CharDriverState *chr = qtest_chr; @@ -264,8 +264,15 @@ static void qtest_process_command(CharDriverState *chr, gchar **words) continue; } if (words[0][14] == 'o') { - qemu_irq_intercept_out(&ngl->out, qtest_irq_handler, - ngl->num_out); + int i; + for (i = 0; i < ngl->num_out; ++i) { + qemu_irq *disconnected = g_new0(qemu_irq, 1); + qemu_irq icpt = qemu_allocate_irq(qtest_irq_handler, + disconnected, i); + + *disconnected = qdev_intercept_gpio_out(dev, icpt, + ngl->name, i); + } } else { qemu_irq_intercept_in(ngl->in, qtest_irq_handler, ngl->num_in); From b58c303590c3d56cbe7435f7e2abe605e4983b8d Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 25 Sep 2014 22:22:04 -0700 Subject: [PATCH 10/28] irq: Remove qemu_irq_intercept_out No more users left and obsoleted by qdev_intercept_gpio_out. Reviewed-by: Alexander Graf Signed-off-by: Peter Crosthwaite Signed-off-by: Paolo Bonzini --- hw/core/irq.c | 6 ------ include/hw/irq.h | 1 - 2 files changed, 7 deletions(-) diff --git a/hw/core/irq.c b/hw/core/irq.c index 4a580a22f3..8a62a36d5e 100644 --- a/hw/core/irq.c +++ b/hw/core/irq.c @@ -144,12 +144,6 @@ void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n) } } -void qemu_irq_intercept_out(qemu_irq **gpio_out, qemu_irq_handler handler, int n) -{ - qemu_irq *old_irqs = *gpio_out; - *gpio_out = qemu_allocate_irqs(handler, old_irqs, n); -} - static const TypeInfo irq_type_info = { .name = TYPE_IRQ, .parent = TYPE_OBJECT, diff --git a/include/hw/irq.h b/include/hw/irq.h index 6f874f5ac0..4c4c2eaf9a 100644 --- a/include/hw/irq.h +++ b/include/hw/irq.h @@ -61,6 +61,5 @@ qemu_irq *qemu_irq_proxy(qemu_irq **target, int n); /* For internal use in qtest. Similar to qemu_irq_split, but operating on an existing vector of qemu_irq. */ void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n); -void qemu_irq_intercept_out(qemu_irq **gpio_out, qemu_irq_handler handler, int n); #endif From 15942b65697c7016a8ca836ecbfd9777d959187c Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 25 Sep 2014 22:22:36 -0700 Subject: [PATCH 11/28] qdev: gpio: delete NamedGPIOList::out All users of GPIO outputs are fully QOMified, using QOM properties to access the GPIO data. Delete. Reviewed-by: Alexander Graf Signed-off-by: Peter Crosthwaite Signed-off-by: Paolo Bonzini --- hw/core/qdev.c | 1 - include/hw/qdev-core.h | 1 - 2 files changed, 2 deletions(-) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 92f88f6698..efbaa99117 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -406,7 +406,6 @@ void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins, assert(gpio_list->num_in == 0 || !name); assert(gpio_list->num_out == 0); gpio_list->num_out = n; - gpio_list->out = pins; for (i = 0; i < n; ++i) { memset(&pins[i], 0, sizeof(*pins)); diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index cf27e6564a..86d341f083 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -136,7 +136,6 @@ struct NamedGPIOList { char *name; qemu_irq *in; int num_in; - qemu_irq *out; int num_out; QLIST_ENTRY(NamedGPIOList) node; }; From aef0869e8ed83ec201488020a9a1cc44d85d72bf Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 25 Sep 2014 22:23:09 -0700 Subject: [PATCH 12/28] qdev: gpio: Remove qdev_init_gpio_out x1 restriction Previously this was restricted to a single call per-dev/per-name. With the conversion of the GPIO output state to QOM the implementation can now handle repeated calls. Remove the restriction. Reviewed-by: Alexander Graf Signed-off-by: Peter Crosthwaite Signed-off-by: Paolo Bonzini --- hw/core/qdev.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index efbaa99117..31014e8769 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -404,8 +404,7 @@ void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins, char *propname = g_strdup_printf("%s[*]", name ? name : "unnamed-gpio-out"); assert(gpio_list->num_in == 0 || !name); - assert(gpio_list->num_out == 0); - gpio_list->num_out = n; + gpio_list->num_out += n; for (i = 0; i < n; ++i) { memset(&pins[i], 0, sizeof(*pins)); From 17a96a146cb5195ab1f6b5cf48645f9f6450539f Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 25 Sep 2014 22:23:42 -0700 Subject: [PATCH 13/28] qdev: gpio: Define qdev_pass_gpios() Allows a container to take ownership of GPIOs in a contained device and automatically connect them as GPIOs to the container. This prepares for deprecation of the SYSBUS IRQ functionality, which has this feature. We push it up to the device level instead of sysbus level. There's nothing sysbus specific about passing GPIOs to containers so its a legitimate device-level generic feature. Reviewed-by: Alexander Graf Signed-off-by: Peter Crosthwaite Signed-off-by: Paolo Bonzini --- hw/core/qdev.c | 26 ++++++++++++++++++++++++++ include/hw/qdev-core.h | 3 +++ 2 files changed, 29 insertions(+) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 31014e8769..c247fffd7f 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -483,6 +483,32 @@ void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin) qdev_connect_gpio_out_named(dev, NULL, n, pin); } +void qdev_pass_gpios(DeviceState *dev, DeviceState *container, + const char *name) +{ + int i; + NamedGPIOList *ngl = qdev_get_named_gpio_list(dev, name); + + for (i = 0; i < ngl->num_in; i++) { + const char *nm = ngl->name ? ngl->name : "unnamed-gpio-in"; + char *propname = g_strdup_printf("%s[%d]", nm, i); + + object_property_add_alias(OBJECT(container), propname, + OBJECT(dev), propname, + &error_abort); + } + for (i = 0; i < ngl->num_out; i++) { + const char *nm = ngl->name ? ngl->name : "unnamed-gpio-out"; + char *propname = g_strdup_printf("%s[%d]", nm, i); + + object_property_add_alias(OBJECT(container), propname, + OBJECT(dev), propname, + &error_abort); + } + QLIST_REMOVE(ngl, node); + QLIST_INSERT_HEAD(&container->gpios, ngl, node); +} + BusState *qdev_get_child_bus(DeviceState *dev, const char *name) { BusState *bus; diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 86d341f083..a7327fd122 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -288,6 +288,9 @@ void qdev_init_gpio_in_named(DeviceState *dev, qemu_irq_handler handler, void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins, const char *name, int n); +void qdev_pass_gpios(DeviceState *dev, DeviceState *container, + const char *name); + BusState *qdev_get_parent_bus(DeviceState *dev); /*** BUS API. ***/ From b5917219090d14065196fc2dca15562e13c23a26 Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 25 Sep 2014 22:24:15 -0700 Subject: [PATCH 14/28] sysbus: Use TYPE_DEVICE GPIO functionality Re-implement the Sysbus GPIOs to use the existing TYPE_DEVICE GPIO named framework. A constant string name is chosen to avoid conflicts with existing unnamed GPIOs. This unifies GPIOs are IRQs for sysbus devices and allows removal of all Sysbus state for GPIOs. Any existing and future-added functionality for GPIOs is now also available for sysbus IRQs. Reviewed-by: Alexander Graf Signed-off-by: Peter Crosthwaite Signed-off-by: Paolo Bonzini --- hw/core/sysbus.c | 20 +++----------------- include/hw/sysbus.h | 7 +++---- 2 files changed, 6 insertions(+), 21 deletions(-) diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c index 414e2a1921..e55c3c1d6d 100644 --- a/hw/core/sysbus.c +++ b/hw/core/sysbus.c @@ -41,11 +41,7 @@ static const TypeInfo system_bus_info = { void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq) { - assert(n >= 0 && n < dev->num_irq); - dev->irqs[n] = NULL; - if (dev->irqp[n]) { - *dev->irqp[n] = irq; - } + qdev_connect_gpio_out_named(DEVICE(dev), SYSBUS_DEVICE_GPIO_IRQ, n, irq); } static void sysbus_mmio_map_common(SysBusDevice *dev, int n, hwaddr addr, @@ -89,22 +85,13 @@ void sysbus_mmio_map_overlap(SysBusDevice *dev, int n, hwaddr addr, /* Request an IRQ source. The actual IRQ object may be populated later. */ void sysbus_init_irq(SysBusDevice *dev, qemu_irq *p) { - int n; - - assert(dev->num_irq < QDEV_MAX_IRQ); - n = dev->num_irq++; - dev->irqp[n] = p; + qdev_init_gpio_out_named(DEVICE(dev), p, SYSBUS_DEVICE_GPIO_IRQ, 1); } /* Pass IRQs from a target device. */ void sysbus_pass_irq(SysBusDevice *dev, SysBusDevice *target) { - int i; - assert(dev->num_irq == 0); - dev->num_irq = target->num_irq; - for (i = 0; i < dev->num_irq; i++) { - dev->irqp[i] = target->irqp[i]; - } + qdev_pass_gpios(DEVICE(target), DEVICE(dev), SYSBUS_DEVICE_GPIO_IRQ); } void sysbus_init_mmio(SysBusDevice *dev, MemoryRegion *memory) @@ -210,7 +197,6 @@ static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent) hwaddr size; int i; - monitor_printf(mon, "%*sirq %d\n", indent, "", s->num_irq); for (i = 0; i < s->num_mmio; i++) { size = memory_region_size(s->mmio[i].memory); monitor_printf(mon, "%*smmio " TARGET_FMT_plx "/" TARGET_FMT_plx "\n", diff --git a/include/hw/sysbus.h b/include/hw/sysbus.h index 0bb91a8824..9fb1782d7b 100644 --- a/include/hw/sysbus.h +++ b/include/hw/sysbus.h @@ -8,7 +8,6 @@ #define QDEV_MAX_MMIO 32 #define QDEV_MAX_PIO 32 -#define QDEV_MAX_IRQ 512 #define TYPE_SYSTEM_BUS "System" #define SYSTEM_BUS(obj) OBJECT_CHECK(IDEBus, (obj), TYPE_IDE_BUS) @@ -33,6 +32,9 @@ typedef struct SysBusDevice SysBusDevice; * SysBusDeviceClass is not overriding #DeviceClass.realize, so derived * classes overriding it are not required to invoke its implementation. */ + +#define SYSBUS_DEVICE_GPIO_IRQ "sysbus-irq" + typedef struct SysBusDeviceClass { /*< private >*/ DeviceClass parent_class; @@ -46,9 +48,6 @@ struct SysBusDevice { DeviceState parent_obj; /*< public >*/ - int num_irq; - qemu_irq irqs[QDEV_MAX_IRQ]; - qemu_irq *irqp[QDEV_MAX_IRQ]; int num_mmio; struct { hwaddr addr; From e48638fdb31bb79de964cd8bbd4621648f5d38c6 Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Tue, 21 Oct 2014 11:00:45 -0400 Subject: [PATCH 15/28] target-i386: warns users when CPU threads>1 for non-Intel CPUs Only Intel CPUs support hyperthreading. When users select threads>1 in -smp option, QEMU fixes it by adjusting CPUID_0000_0001_EBX and CPUID_8000_0008_ECX based on inputs (sockets, cores, threads); so guest VM can boot correctly. However it is still better to gives users a warning when such case happens. Signed-off-by: Wei Huang [As suggested by Eduardo, check for !IS_INTEL instead of AMD. - Paolo] Signed-off-by: Paolo Bonzini --- target-i386/cpu.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/target-i386/cpu.c b/target-i386/cpu.c index e7bf9de80f..69a2bd39c5 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2696,6 +2696,13 @@ static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp) } #endif + +#define IS_INTEL_CPU(env) ((env)->cpuid_vendor1 == CPUID_VENDOR_INTEL_1 && \ + (env)->cpuid_vendor2 == CPUID_VENDOR_INTEL_2 && \ + (env)->cpuid_vendor3 == CPUID_VENDOR_INTEL_3) +#define IS_AMD_CPU(env) ((env)->cpuid_vendor1 == CPUID_VENDOR_AMD_1 && \ + (env)->cpuid_vendor2 == CPUID_VENDOR_AMD_2 && \ + (env)->cpuid_vendor3 == CPUID_VENDOR_AMD_3) static void x86_cpu_realizefn(DeviceState *dev, Error **errp) { CPUState *cs = CPU(dev); @@ -2703,6 +2710,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) X86CPUClass *xcc = X86_CPU_GET_CLASS(dev); CPUX86State *env = &cpu->env; Error *local_err = NULL; + static bool ht_warned; if (env->features[FEAT_7_0_EBX] && env->cpuid_level < 7) { env->cpuid_level = 7; @@ -2711,9 +2719,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) /* On AMD CPUs, some CPUID[8000_0001].EDX bits must match the bits on * CPUID[1].EDX. */ - if (env->cpuid_vendor1 == CPUID_VENDOR_AMD_1 && - env->cpuid_vendor2 == CPUID_VENDOR_AMD_2 && - env->cpuid_vendor3 == CPUID_VENDOR_AMD_3) { + if (IS_AMD_CPU(env)) { env->features[FEAT_8000_0001_EDX] &= ~CPUID_EXT2_AMD_ALIASES; env->features[FEAT_8000_0001_EDX] |= (env->features[FEAT_1_EDX] & CPUID_EXT2_AMD_ALIASES); @@ -2742,6 +2748,20 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) mce_init(cpu); qemu_init_vcpu(cs); + /* Only Intel CPUs support hyperthreading. Even though QEMU fixes this + * issue by adjusting CPUID_0000_0001_EBX and CPUID_8000_0008_ECX + * based on inputs (sockets,cores,threads), it is still better to gives + * users a warning. + * + * NOTE: the following code has to follow qemu_init_vcpu(). Otherwise + * cs->nr_threads hasn't be populated yet and the checking is incorrect. + */ + if (!IS_INTEL_CPU(env) && cs->nr_threads > 1 && !ht_warned) { + error_report("AMD CPU doesn't support hyperthreading. Please configure" + " -smp options properly."); + ht_warned = true; + } + x86_cpu_apic_realize(cpu, &local_err); if (local_err != NULL) { goto out; From da26f37a3eca3c88e0b24a21810321fcfb4ec01f Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 21 Oct 2014 15:12:57 +0200 Subject: [PATCH 16/28] MAINTAINERS: grab more files from Anthony's pile I am picking up character devices and the main loop, as agreed during QEMU Summit. Signed-off-by: Paolo Bonzini --- MAINTAINERS | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 8eed800a37..4045561375 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -720,8 +720,12 @@ T: git git://github.com/stefanha/qemu.git block Character Devices M: Anthony Liguori +M: Paolo Bonzini S: Maintained F: qemu-char.c +F: backends/baum.c +F: backends/msmouse.c +F: backends/testdev.c CPU M: Andreas Färber @@ -780,7 +784,11 @@ F: ui/cocoa.m Main loop M: Anthony Liguori -S: Supported +M: Paolo Bonzini +S: Maintained +F: cpus.c +F: main-loop.c +F: qemu-timer.c F: vl.c Human Monitor (HMP) From e26082fd0be51bb32daec39b0279f337d8ebb510 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 22 Oct 2014 14:53:32 +0200 Subject: [PATCH 17/28] MAINTAINERS: add Samuel Thibault as usb-serial.c and baum.c maintainer He wrote "I've written mostly all of usb-serial.c and baum.c, and keep maintaining them, since I use them regularly." Cc: Samuel Thibault Signed-off-by: Paolo Bonzini --- MAINTAINERS | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 4045561375..65358426b3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -626,6 +626,12 @@ S: Maintained F: hw/usb/* F: tests/usb-*-test.c +USB (serial adapter) +M: Gerd Hoffmann +M: Samuel Thibault +S: Maintained +F: hw/usb/dev-serial.c + VFIO M: Alex Williamson S: Supported @@ -723,10 +729,14 @@ M: Anthony Liguori M: Paolo Bonzini S: Maintained F: qemu-char.c -F: backends/baum.c F: backends/msmouse.c F: backends/testdev.c +Character Devices (Braille) +M: Samuel Thibault +S: Maintained +F: backends/baum.c + CPU M: Andreas Färber S: Supported From d46d72fd1030e8315190f83023e4fe6959c5cfde Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 21 Oct 2014 15:16:06 +0200 Subject: [PATCH 18/28] MAINTAINERS: add myself for X86 Still not moving it beyond "Odd fixes". Richard Henderson also has reviewed a bunch of X86 TCG patches, so add him as well. All we want is to avoid that patches fall on the floor. Signed-off-by: Paolo Bonzini --- MAINTAINERS | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 65358426b3..6519d67efa 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -149,7 +149,8 @@ F: target-unicore32/ F: hw/unicore32/ X86 -M: qemu-devel@nongnu.org +M: Paolo Bonzini +M: Richard Henderson S: Odd Fixes F: target-i386/ F: hw/i386/ @@ -203,6 +204,7 @@ F: hw/intc/s390_flic_kvm.c F: include/hw/s390x/s390_flic.h X86 +M: Paolo Bonzini M: Marcelo Tosatti L: kvm@vger.kernel.org S: Supported From 486bbe5f14f182f39eb13feb0b29c64e4a6dcc8d Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 22 Oct 2014 00:18:01 +0200 Subject: [PATCH 19/28] MAINTAINERS: Add more TCG files Unfortunately, TCG files do not really have a maintainer yet. But at least there will be fewer unmaintained files. Signed-off-by: Paolo Bonzini --- MAINTAINERS | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 6519d67efa..3f371f6179 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -61,6 +61,17 @@ L: secalert@redhat.com Guest CPU cores (TCG): ---------------------- +Overall +M: qemu-devel@nongnu.org +S: Odd fixes +F: cpu-exec.c +F: cputlb.c +F: softmmu_template.h +F: translate-all.c +F: include/exec/cpu_ldst.h +F: include/exec/cpu_ldst_template.h +F: include/exec/helper*.h + Alpha M: Richard Henderson S: Maintained @@ -897,6 +908,12 @@ F: include/sysemu/seccomp.h Usermode Emulation ------------------ +Overall +M: Riku Voipio +S: Maintained +F: thunk.c +F: user-exec.c + BSD user M: Blue Swirl S: Maintained From c0bd0b509b398efe7f0b5d98f404763f77a86f07 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 22 Oct 2014 00:31:28 +0200 Subject: [PATCH 20/28] MAINTAINERS: add some tests directories Low-hanging fruit... Signed-off-by: Paolo Bonzini --- MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 3f371f6179..b1d229f52b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -77,6 +77,7 @@ M: Richard Henderson S: Maintained F: target-alpha/ F: hw/alpha/ +F: tests/tcg/alpha/ ARM M: Peter Maydell @@ -90,6 +91,7 @@ M: Edgar E. Iglesias S: Maintained F: target-cris/ F: hw/cris/ +F: tests/tcg/cris/ LM32 M: Michael Walle @@ -97,6 +99,7 @@ S: Maintained F: target-lm32/ F: hw/lm32/ F: hw/char/lm32_* +F: tests/tcg/lm32/ M68K S: Orphan @@ -114,6 +117,7 @@ M: Aurelien Jarno S: Odd Fixes F: target-mips/ F: hw/mips/ +F: tests/tcg/mips/ Moxie M: Anthony Green @@ -125,6 +129,7 @@ M: Jia Liu S: Maintained F: target-openrisc/ F: hw/openrisc/ +F: tests/tcg/openrisc/ PowerPC M: Alexander Graf @@ -172,6 +177,7 @@ W: http://wiki.osll.spb.ru/doku.php?id=etc:users:jcmvbkbc:qemu-target-xtensa S: Maintained F: target-xtensa/ F: hw/xtensa/ +F: tests/tcg/xtensa/ TriCore M: Bastian Koppelmann @@ -850,6 +856,7 @@ M: Luiz Capitulino M: Michael Roth S: Maintained F: qapi/ +F: tests/qapi-schema/ T: git git://repo.or.cz/qemu/qmp-unstable.git queue/qmp QAPI Schema From 5dd4a88c37f93f525828a8592168fb5d03f9e842 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 22 Oct 2014 10:53:22 +0200 Subject: [PATCH 21/28] MAINTAINERS: avoid M entries that point to mailing lists "L" entries that point to qemu-devel are not much better either, but at least the get_maintainer.pl output is clearer. Signed-off-by: Paolo Bonzini --- MAINTAINERS | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index b1d229f52b..82f21c5e2e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -62,7 +62,7 @@ L: secalert@redhat.com Guest CPU cores (TCG): ---------------------- Overall -M: qemu-devel@nongnu.org +L: qemu-devel@nongnu.org S: Odd fixes F: cpu-exec.c F: cputlb.c @@ -287,7 +287,7 @@ F: include/hw/arm/digic.h F: hw/*/digic* Gumstix -M: qemu-devel@nongnu.org +L: qemu-devel@nongnu.org S: Orphan F: hw/arm/gumstix.c @@ -303,7 +303,7 @@ S: Maintained F: hw/arm/integratorcp.c Mainstone -M: qemu-devel@nongnu.org +L: qemu-devel@nongnu.org S: Orphan F: hw/arm/mainstone.c @@ -409,7 +409,7 @@ S: Maintained F: hw/mips/mips_malta.c Mipssim -M: qemu-devel@nongnu.org +L: qemu-devel@nongnu.org S: Orphan F: hw/mips/mips_mipssim.c @@ -776,7 +776,7 @@ S: Maintained F: device_tree.[ch] GDB stub -M: qemu-devel@nongnu.org +L: qemu-devel@nongnu.org S: Odd Fixes F: gdbstub* F: gdb-xml/ @@ -934,7 +934,6 @@ F: linux-user/ Tiny Code Generator (TCG) ------------------------- Common code -M: qemu-devel@nongnu.org M: Richard Henderson S: Maintained F: tcg/ @@ -951,7 +950,7 @@ S: Maintained F: tcg/arm/ i386 target -M: qemu-devel@nongnu.org +L: qemu-devel@nongnu.org S: Maintained F: tcg/i386/ From 107684c05d80c457aa6e81d090b36a1a294110ec Mon Sep 17 00:00:00 2001 From: Li Liu Date: Wed, 22 Oct 2014 10:26:47 +0800 Subject: [PATCH 22/28] qtest: fix qtest log fd should be initialized before qtest chardev qtest_log_fp should be inited before qemu_chr_add_handlers. If not the log dumped from callback functions may be lost. easy to reproduce it by command: "QTEST_LOG=1 QTEST_QEMU_BINARY=x86_64-softmmu/qemu-system-x86_64 gtester -k --verbose -m=quick tests/qdev-monitor-test" The log "[I xxxxxx] OPENED" should be printed out by qtest_event, but does not. Signed-off-by: Li Liu Reviewed-by: Stefan Hajnoczi Signed-off-by: Paolo Bonzini --- qtest.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/qtest.c b/qtest.c index 946b560d6a..2bca04ed4c 100644 --- a/qtest.c +++ b/qtest.c @@ -545,11 +545,6 @@ void qtest_init(const char *qtest_chrdev, const char *qtest_log, Error **errp) return; } - qemu_chr_add_handlers(chr, qtest_can_read, qtest_read, qtest_event, chr); - qemu_chr_fe_set_echo(chr, true); - - inbuf = g_string_new(""); - if (qtest_log) { if (strcmp(qtest_log, "none") != 0) { qtest_log_fp = fopen(qtest_log, "w+"); @@ -558,6 +553,10 @@ void qtest_init(const char *qtest_chrdev, const char *qtest_log, Error **errp) qtest_log_fp = stderr; } + qemu_chr_add_handlers(chr, qtest_can_read, qtest_read, qtest_event, chr); + qemu_chr_fe_set_echo(chr, true); + + inbuf = g_string_new(""); qtest_chr = chr; } From 8ad2c0f0f8996fe71826c1cc79e509ad6a94d2d4 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 22 Oct 2014 10:38:27 +0200 Subject: [PATCH 23/28] get_maintainer.pl: move git loop under "if ($email) {" All checks in the loop are guarded by that condition, and there is a handy "if" just below. Simplify the code. Reviewed-by: Markus Armbruster Signed-off-by: Paolo Bonzini --- scripts/get_maintainer.pl | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index 38334de875..906dcbe468 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -651,18 +651,17 @@ sub get_maintainers { $email->[0] = deduplicate_email($email->[0]); } - foreach my $file (@files) { - if ($email && - ($email_git || ($email_git_fallback && - !$exact_pattern_match_hash{$file}))) { - vcs_file_signoffs($file); - } - if ($email && $email_git_blame) { - vcs_file_blame($file); - } - } - if ($email) { + foreach my $file (@files) { + if ($email_git || ($email_git_fallback && + !$exact_pattern_match_hash{$file})) { + vcs_file_signoffs($file); + } + if ($email_git_blame) { + vcs_file_blame($file); + } + } + foreach my $chief (@penguin_chief) { if ($chief =~ m/^(.*):(.*)/) { my $email_address; From c6561586f0f858635ccda0bfa97046e4e82af276 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 22 Oct 2014 10:41:16 +0200 Subject: [PATCH 24/28] get_maintainer.pl: restrict cases where it falls back to --git The list emitted by --git-fallback often leads inexperienced contributors to add pointless CCs. While not discouraging usage of --git-fallback, we want to: 1) disable the fallback if only some files lack a maintainer $ scripts/get_maintainer.pl -f util/cutils.c hw/ide/core.c Kevin Wolf (odd fixer:IDE) Stefan Hajnoczi (odd fixer:IDE) This behavior is taken even if --git-fallback is specified. 2) warn the contributors about what we're doing, asking them to use their common sense: $ scripts/get_maintainer.pl -f util/cutils.c get_maintainer.pl: No maintainers found, printing recent contributors. get_maintainer.pl: Do not blindly cc: them on patches! Use common sense. Luiz Capitulino (commit_signer:1/2=50%) ... $ Explicitly disabling the fallback will not result in the warning message: $ scripts/get_maintainer.pl -f util/cutils.c --no-git-fallback $ echo $? 0 (Returning 1 would break usage of scripts/get_maintainer.pl as a cccmd for git-send-email). Reviewed-by: Markus Armbruster Signed-off-by: Paolo Bonzini --- scripts/get_maintainer.pl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index 906dcbe468..af68c6c92d 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -652,6 +652,15 @@ sub get_maintainers { } if ($email) { + if (! $interactive) { + $email_git_fallback = 0 if @email_to > 0 || @list_to > 0 || $email_git || $email_git_blame; + if ($email_git_fallback) { + print STDERR "get_maintainer.pl: No maintainers found, printing recent contributors.\n"; + print STDERR "get_maintainer.pl: Do not blindly cc: them on patches! Use common sense.\n"; + print STDERR "\n"; + } + } + foreach my $file (@files) { if ($email_git || ($email_git_fallback && !$exact_pattern_match_hash{$file})) { From 9aecd6f8aef653cea58932f06a2740299dbe5fd3 Mon Sep 17 00:00:00 2001 From: Chao Peng Date: Thu, 23 Oct 2014 11:02:43 +0800 Subject: [PATCH 25/28] target-i386: add Intel AVX-512 support Add AVX512 feature bits, register definition and corresponding xsave/vmstate support. Reviewed-by: Eduardo Habkost Signed-off-by: Chao Peng Signed-off-by: Paolo Bonzini --- target-i386/cpu.c | 10 ++++- target-i386/cpu.h | 61 ++++++++++++++++++++++++++++++ target-i386/kvm.c | 19 ++++++++++ target-i386/machine.c | 87 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 175 insertions(+), 2 deletions(-) diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 69a2bd39c5..e1946016ad 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -259,8 +259,8 @@ static const char *svm_feature_name[] = { static const char *cpuid_7_0_ebx_feature_name[] = { "fsgsbase", "tsc_adjust", NULL, "bmi1", "hle", "avx2", NULL, "smep", "bmi2", "erms", "invpcid", "rtm", NULL, NULL, "mpx", NULL, - NULL, NULL, "rdseed", "adx", "smap", NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + "avx512f", NULL, "rdseed", "adx", "smap", NULL, NULL, NULL, + NULL, NULL, "avx512pf", "avx512er", "avx512cd", NULL, NULL, NULL, }; static const char *cpuid_apm_edx_feature_name[] = { @@ -426,6 +426,12 @@ static const ExtSaveArea ext_save_areas[] = { .offset = 0x3c0, .size = 0x40 }, [4] = { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX, .offset = 0x400, .size = 0x40 }, + [5] = { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F, + .offset = 0x440, .size = 0x40 }, + [6] = { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F, + .offset = 0x480, .size = 0x200 }, + [7] = { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F, + .offset = 0x680, .size = 0x400 }, }; const char *get_register_name_32(unsigned int reg) diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 2968749578..9f018312b0 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -395,6 +395,9 @@ #define XSTATE_YMM (1ULL << 2) #define XSTATE_BNDREGS (1ULL << 3) #define XSTATE_BNDCSR (1ULL << 4) +#define XSTATE_OPMASK (1ULL << 5) +#define XSTATE_ZMM_Hi256 (1ULL << 6) +#define XSTATE_Hi16_ZMM (1ULL << 7) /* CPUID feature words */ @@ -560,9 +563,13 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS]; #define CPUID_7_0_EBX_INVPCID (1U << 10) #define CPUID_7_0_EBX_RTM (1U << 11) #define CPUID_7_0_EBX_MPX (1U << 14) +#define CPUID_7_0_EBX_AVX512F (1U << 16) /* AVX-512 Foundation */ #define CPUID_7_0_EBX_RDSEED (1U << 18) #define CPUID_7_0_EBX_ADX (1U << 19) #define CPUID_7_0_EBX_SMAP (1U << 20) +#define CPUID_7_0_EBX_AVX512PF (1U << 26) /* AVX-512 Prefetch */ +#define CPUID_7_0_EBX_AVX512ER (1U << 27) /* AVX-512 Exponential and Reciprocal */ +#define CPUID_7_0_EBX_AVX512CD (1U << 28) /* AVX-512 Conflict Detection */ /* CPUID[0x80000007].EDX flags: */ #define CPUID_APM_INVTSC (1U << 8) @@ -706,6 +713,24 @@ typedef union { float64 _d[2]; } XMMReg; +typedef union { + uint8_t _b[32]; + uint16_t _w[16]; + uint32_t _l[8]; + uint64_t _q[4]; + float32 _s[8]; + float64 _d[4]; +} YMMReg; + +typedef union { + uint8_t _b[64]; + uint16_t _w[32]; + uint32_t _l[16]; + uint64_t _q[8]; + float32 _s[16]; + float64 _d[8]; +} ZMMReg; + typedef union { uint8_t _b[8]; uint16_t _w[4]; @@ -725,6 +750,20 @@ typedef struct BNDCSReg { } BNDCSReg; #ifdef HOST_WORDS_BIGENDIAN +#define ZMM_B(n) _b[63 - (n)] +#define ZMM_W(n) _w[31 - (n)] +#define ZMM_L(n) _l[15 - (n)] +#define ZMM_S(n) _s[15 - (n)] +#define ZMM_Q(n) _q[7 - (n)] +#define ZMM_D(n) _d[7 - (n)] + +#define YMM_B(n) _b[31 - (n)] +#define YMM_W(n) _w[15 - (n)] +#define YMM_L(n) _l[7 - (n)] +#define YMM_S(n) _s[7 - (n)] +#define YMM_Q(n) _q[3 - (n)] +#define YMM_D(n) _d[3 - (n)] + #define XMM_B(n) _b[15 - (n)] #define XMM_W(n) _w[7 - (n)] #define XMM_L(n) _l[3 - (n)] @@ -737,6 +776,20 @@ typedef struct BNDCSReg { #define MMX_L(n) _l[1 - (n)] #define MMX_S(n) _s[1 - (n)] #else +#define ZMM_B(n) _b[n] +#define ZMM_W(n) _w[n] +#define ZMM_L(n) _l[n] +#define ZMM_S(n) _s[n] +#define ZMM_Q(n) _q[n] +#define ZMM_D(n) _d[n] + +#define YMM_B(n) _b[n] +#define YMM_W(n) _w[n] +#define YMM_L(n) _l[n] +#define YMM_S(n) _s[n] +#define YMM_Q(n) _q[n] +#define YMM_D(n) _d[n] + #define XMM_B(n) _b[n] #define XMM_W(n) _w[n] #define XMM_L(n) _l[n] @@ -775,6 +828,8 @@ typedef struct { #define NB_MMU_MODES 3 +#define NB_OPMASK_REGS 8 + typedef enum TPRAccess { TPR_ACCESS_READ, TPR_ACCESS_WRITE, @@ -839,6 +894,12 @@ typedef struct CPUX86State { XMMReg ymmh_regs[CPU_NB_REGS]; + uint64_t opmask_regs[NB_OPMASK_REGS]; + YMMReg zmmh_regs[CPU_NB_REGS]; +#ifdef TARGET_X86_64 + ZMMReg hi16_zmm_regs[CPU_NB_REGS]; +#endif + /* sysenter registers */ uint32_t sysenter_cs; target_ulong sysenter_esp; diff --git a/target-i386/kvm.c b/target-i386/kvm.c index ddedc735ff..ccf36e8719 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -1031,6 +1031,9 @@ static int kvm_put_fpu(X86CPU *cpu) #define XSAVE_YMMH_SPACE 144 #define XSAVE_BNDREGS 240 #define XSAVE_BNDCSR 256 +#define XSAVE_OPMASK 272 +#define XSAVE_ZMM_Hi256 288 +#define XSAVE_Hi16_ZMM 416 static int kvm_put_xsave(X86CPU *cpu) { @@ -1067,6 +1070,14 @@ static int kvm_put_xsave(X86CPU *cpu) sizeof env->bnd_regs); memcpy(&xsave->region[XSAVE_BNDCSR], &env->bndcs_regs, sizeof(env->bndcs_regs)); + memcpy(&xsave->region[XSAVE_OPMASK], env->opmask_regs, + sizeof env->opmask_regs); + memcpy(&xsave->region[XSAVE_ZMM_Hi256], env->zmmh_regs, + sizeof env->zmmh_regs); +#ifdef TARGET_X86_64 + memcpy(&xsave->region[XSAVE_Hi16_ZMM], env->hi16_zmm_regs, + sizeof env->hi16_zmm_regs); +#endif r = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_XSAVE, xsave); return r; } @@ -1402,6 +1413,14 @@ static int kvm_get_xsave(X86CPU *cpu) sizeof env->bnd_regs); memcpy(&env->bndcs_regs, &xsave->region[XSAVE_BNDCSR], sizeof(env->bndcs_regs)); + memcpy(env->opmask_regs, &xsave->region[XSAVE_OPMASK], + sizeof env->opmask_regs); + memcpy(env->zmmh_regs, &xsave->region[XSAVE_ZMM_Hi256], + sizeof env->zmmh_regs); +#ifdef TARGET_X86_64 + memcpy(env->hi16_zmm_regs, &xsave->region[XSAVE_Hi16_ZMM], + sizeof env->hi16_zmm_regs); +#endif return 0; } diff --git a/target-i386/machine.c b/target-i386/machine.c index 0dd49f0005..1c13b14352 100644 --- a/target-i386/machine.c +++ b/target-i386/machine.c @@ -60,6 +60,44 @@ static const VMStateDescription vmstate_ymmh_reg = { #define VMSTATE_YMMH_REGS_VARS(_field, _state, _n, _v) \ VMSTATE_STRUCT_ARRAY(_field, _state, _n, _v, vmstate_ymmh_reg, XMMReg) +static const VMStateDescription vmstate_zmmh_reg = { + .name = "zmmh_reg", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT64(YMM_Q(0), YMMReg), + VMSTATE_UINT64(YMM_Q(1), YMMReg), + VMSTATE_UINT64(YMM_Q(2), YMMReg), + VMSTATE_UINT64(YMM_Q(3), YMMReg), + VMSTATE_END_OF_LIST() + } +}; + +#define VMSTATE_ZMMH_REGS_VARS(_field, _state, _n) \ + VMSTATE_STRUCT_ARRAY(_field, _state, _n, 0, vmstate_zmmh_reg, YMMReg) + +#ifdef TARGET_X86_64 +static const VMStateDescription vmstate_hi16_zmm_reg = { + .name = "hi16_zmm_reg", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT64(ZMM_Q(0), ZMMReg), + VMSTATE_UINT64(ZMM_Q(1), ZMMReg), + VMSTATE_UINT64(ZMM_Q(2), ZMMReg), + VMSTATE_UINT64(ZMM_Q(3), ZMMReg), + VMSTATE_UINT64(ZMM_Q(4), ZMMReg), + VMSTATE_UINT64(ZMM_Q(5), ZMMReg), + VMSTATE_UINT64(ZMM_Q(6), ZMMReg), + VMSTATE_UINT64(ZMM_Q(7), ZMMReg), + VMSTATE_END_OF_LIST() + } +}; + +#define VMSTATE_Hi16_ZMM_REGS_VARS(_field, _state, _n) \ + VMSTATE_STRUCT_ARRAY(_field, _state, _n, 0, vmstate_hi16_zmm_reg, ZMMReg) +#endif + static const VMStateDescription vmstate_bnd_regs = { .name = "bnd_regs", .version_id = 1, @@ -603,6 +641,52 @@ static const VMStateDescription vmstate_msr_hyperv_time = { } }; +static bool avx512_needed(void *opaque) +{ + X86CPU *cpu = opaque; + CPUX86State *env = &cpu->env; + unsigned int i; + + for (i = 0; i < NB_OPMASK_REGS; i++) { + if (env->opmask_regs[i]) { + return true; + } + } + + for (i = 0; i < CPU_NB_REGS; i++) { +#define ENV_ZMMH(reg, field) (env->zmmh_regs[reg].YMM_Q(field)) + if (ENV_ZMMH(i, 0) || ENV_ZMMH(i, 1) || + ENV_ZMMH(i, 2) || ENV_ZMMH(i, 3)) { + return true; + } +#ifdef TARGET_X86_64 +#define ENV_Hi16_ZMM(reg, field) (env->hi16_zmm_regs[reg].ZMM_Q(field)) + if (ENV_Hi16_ZMM(i, 0) || ENV_Hi16_ZMM(i, 1) || + ENV_Hi16_ZMM(i, 2) || ENV_Hi16_ZMM(i, 3) || + ENV_Hi16_ZMM(i, 4) || ENV_Hi16_ZMM(i, 5) || + ENV_Hi16_ZMM(i, 6) || ENV_Hi16_ZMM(i, 7)) { + return true; + } +#endif + } + + return false; +} + +static const VMStateDescription vmstate_avx512 = { + .name = "cpu/avx512", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT64_ARRAY(env.opmask_regs, X86CPU, NB_OPMASK_REGS), + VMSTATE_ZMMH_REGS_VARS(env.zmmh_regs, X86CPU, CPU_NB_REGS), +#ifdef TARGET_X86_64 + VMSTATE_Hi16_ZMM_REGS_VARS(env.hi16_zmm_regs, X86CPU, CPU_NB_REGS), +#endif + VMSTATE_END_OF_LIST() + } +}; + VMStateDescription vmstate_x86_cpu = { .name = "cpu", .version_id = 12, @@ -745,6 +829,9 @@ VMStateDescription vmstate_x86_cpu = { }, { .vmsd = &vmstate_msr_hyperv_time, .needed = hyperv_time_enable_needed, + }, { + .vmsd = &vmstate_avx512, + .needed = avx512_needed, } , { /* empty */ } From b7890c40e557f4733b6fcd1eb79af79b70dc8c05 Mon Sep 17 00:00:00 2001 From: Ting Wang Date: Mon, 27 Oct 2014 16:51:41 +0800 Subject: [PATCH 26/28] virtio-scsi: sense in virtio_scsi_command_complete If req->resp.cmd.status is not GOOD, the address of sense for qemu_iovec_from_buf should be modified from &req->resp to sense. Cc: qemu-stable@nongnu.org Signed-off-by: Ting Wang Signed-off-by: Paolo Bonzini --- hw/scsi/virtio-scsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 2d2612bf05..85cd91e6c6 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -448,7 +448,7 @@ static void virtio_scsi_command_complete(SCSIRequest *r, uint32_t status, sense_len = scsi_req_get_sense(r, sense, sizeof(sense)); sense_len = MIN(sense_len, req->resp_iov.size - sizeof(req->resp.cmd)); qemu_iovec_from_buf(&req->resp_iov, sizeof(req->resp.cmd), - &req->resp, sense_len); + sense, sense_len); req->resp.cmd.sense_len = virtio_tswap32(vdev, sense_len); } virtio_scsi_complete_cmd_req(req); From 024d9adc79651f8fd96078461a7e4dfb8bb83e16 Mon Sep 17 00:00:00 2001 From: Bin Wu Date: Sat, 25 Oct 2014 02:43:44 +0000 Subject: [PATCH 27/28] hw/scsi/virtio-scsi.c: fix the "type" use error in virtio_scsi_handle_ctrl The local variable "type" in virtio_scsi_handle_ctl represents the tmf command type from the guest and it has the same meaning as the req->req.tmf.type. However, before the invoking of virtio_scsi_parse_req the req->req.tmf.type doesn't has the correct value(just initialized to zero). Therefore, we need to use the "type" variable to judge the case. Cc: qemu-stable@nongnu.org Signed-off-by: Bin Wu [Actually make it compile, "type" must be uint32_t in order to pass it to virtio_tswap32s. - Paolo] Signed-off-by: Paolo Bonzini --- hw/scsi/virtio-scsi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 85cd91e6c6..7d40eccb0c 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -369,7 +369,7 @@ fail: void virtio_scsi_handle_ctrl_req(VirtIOSCSI *s, VirtIOSCSIReq *req) { VirtIODevice *vdev = (VirtIODevice *)s; - int type; + uint32_t type; int r = 0; if (iov_to_buf(req->elem.out_sg, req->elem.out_num, 0, @@ -378,8 +378,8 @@ void virtio_scsi_handle_ctrl_req(VirtIOSCSI *s, VirtIOSCSIReq *req) return; } - virtio_tswap32s(vdev, &req->req.tmf.type); - if (req->req.tmf.type == VIRTIO_SCSI_T_TMF) { + virtio_tswap32s(vdev, &type); + if (type == VIRTIO_SCSI_T_TMF) { if (virtio_scsi_parse_req(req, sizeof(VirtIOSCSICtrlTMFReq), sizeof(VirtIOSCSICtrlTMFResp)) < 0) { virtio_scsi_bad_req(); @@ -387,8 +387,8 @@ void virtio_scsi_handle_ctrl_req(VirtIOSCSI *s, VirtIOSCSIReq *req) r = virtio_scsi_do_tmf(s, req); } - } else if (req->req.tmf.type == VIRTIO_SCSI_T_AN_QUERY || - req->req.tmf.type == VIRTIO_SCSI_T_AN_SUBSCRIBE) { + } else if (type == VIRTIO_SCSI_T_AN_QUERY || + type == VIRTIO_SCSI_T_AN_SUBSCRIBE) { if (virtio_scsi_parse_req(req, sizeof(VirtIOSCSICtrlANReq), sizeof(VirtIOSCSICtrlANResp)) < 0) { virtio_scsi_bad_req(); From e218052f9288609bb8c53b31cae3bed7d7516728 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 6 Oct 2014 16:19:07 +0200 Subject: [PATCH 28/28] aio / timers: De-document -clock Commit 6d32717 "aio / timers: Remove alarm timers" has issues: 1. It silently ignores -clock for backward compatibility. Incompatible change: -clock help no longer terminates the program. Tolerable. 2. Failed to update option documentation. In particular, -help still advises users to try -clock help for available timers. Drop all documentation on -clock. 3. The 'query-alarm-clock' example in docs/writing-commands.txt no longer works, and needs to be redone. Can't do that right now, so I just stick in a FIXME. Signed-off-by: Markus Armbruster Signed-off-by: Paolo Bonzini --- docs/writing-qmp-commands.txt | 2 ++ qemu-options.hx | 12 ++---------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/docs/writing-qmp-commands.txt b/docs/writing-qmp-commands.txt index 4d86c2477b..f3df2066a4 100644 --- a/docs/writing-qmp-commands.txt +++ b/docs/writing-qmp-commands.txt @@ -365,6 +365,8 @@ documentation for information about the other types. === User Defined Types === +FIXME This example needs to be redone after commit 6d32717 + For this example we will write the query-alarm-clock command, which returns information about QEMU's timer alarm. For more information about it, please check the "-clock" command-line option. diff --git a/qemu-options.hx b/qemu-options.hx index 22cf3b94ce..1e7d5b8362 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -2989,16 +2989,8 @@ Load the contents of @var{file} as an option ROM. This option is useful to load things like EtherBoot. ETEXI -DEF("clock", HAS_ARG, QEMU_OPTION_clock, \ - "-clock force the use of the given methods for timer alarm.\n" \ - " To see what timers are available use '-clock help'\n", - QEMU_ARCH_ALL) -STEXI -@item -clock @var{method} -@findex -clock -Force the use of the given methods for timer alarm. To see what timers -are available use @code{-clock help}. -ETEXI +HXCOMM Silently ignored for compatibility +DEF("clock", HAS_ARG, QEMU_OPTION_clock, "", QEMU_ARCH_ALL) HXCOMM Options deprecated by -rtc DEF("localtime", 0, QEMU_OPTION_localtime, "", QEMU_ARCH_ALL)