summaryrefslogtreecommitdiffstats
path: root/hw/virtio/virtio.c
diff options
context:
space:
mode:
authorXie Yongji2019-06-26 04:31:28 +0200
committerMichael S. Tsirkin2019-07-04 23:00:32 +0200
commit868a8f44f57f15670b30631a95e3e31e5cf268d0 (patch)
tree4a5c6c7aad32564c8abb11ba7e20e8d0e9519895 /hw/virtio/virtio.c
parentvirtio: Set "start_on_kick" for legacy devices (diff)
downloadqemu-868a8f44f57f15670b30631a95e3e31e5cf268d0.tar.gz
qemu-868a8f44f57f15670b30631a95e3e31e5cf268d0.tar.xz
qemu-868a8f44f57f15670b30631a95e3e31e5cf268d0.zip
virtio: Set "start_on_kick" on virtio_set_features()
The guest feature is not set correctly on virtio_reset() and virtio_init(). So we should not use it to set "start_on_kick" at that point. This patch set "start_on_kick" on virtio_set_features() instead. Fixes: badaf79cfdbd3 ("virtio: Introduce started flag to VirtioDevice") Signed-off-by: Xie Yongji <xieyongji@baidu.com> Reviewed-by: Greg Kurz <groug@kaod.org> Message-Id: <20190626023130.31315-4-xieyongji@baidu.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/virtio/virtio.c')
-rw-r--r--hw/virtio/virtio.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index f7504d1395..5fd25d98a9 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -1212,7 +1212,7 @@ void virtio_reset(void *opaque)
k->reset(vdev);
}
- vdev->start_on_kick = !virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1);
+ vdev->start_on_kick = false;
vdev->started = false;
vdev->broken = false;
vdev->guest_features = 0;
@@ -2063,14 +2063,21 @@ int virtio_set_features(VirtIODevice *vdev, uint64_t val)
return -EINVAL;
}
ret = virtio_set_features_nocheck(vdev, val);
- if (!ret && virtio_vdev_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
- /* VIRTIO_RING_F_EVENT_IDX changes the size of the caches. */
- int i;
- for (i = 0; i < VIRTIO_QUEUE_MAX; i++) {
- if (vdev->vq[i].vring.num != 0) {
- virtio_init_region_cache(vdev, i);
+ if (!ret) {
+ if (virtio_vdev_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
+ /* VIRTIO_RING_F_EVENT_IDX changes the size of the caches. */
+ int i;
+ for (i = 0; i < VIRTIO_QUEUE_MAX; i++) {
+ if (vdev->vq[i].vring.num != 0) {
+ virtio_init_region_cache(vdev, i);
+ }
}
}
+
+ if (!virtio_device_started(vdev, vdev->status) &&
+ !virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) {
+ vdev->start_on_kick = true;
+ }
}
return ret;
}
@@ -2222,6 +2229,11 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
}
}
+ if (!virtio_device_started(vdev, vdev->status) &&
+ !virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) {
+ vdev->start_on_kick = true;
+ }
+
rcu_read_lock();
for (i = 0; i < num; i++) {
if (vdev->vq[i].vring.desc) {
@@ -2324,7 +2336,7 @@ void virtio_init(VirtIODevice *vdev, const char *name,
g_malloc0(sizeof(*vdev->vector_queues) * nvectors);
}
- vdev->start_on_kick = !virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1);
+ vdev->start_on_kick = false;
vdev->started = false;
vdev->device_id = device_id;
vdev->status = 0;