From 868a8f44f57f15670b30631a95e3e31e5cf268d0 Mon Sep 17 00:00:00 2001 From: Xie Yongji Date: Wed, 26 Jun 2019 10:31:28 +0800 Subject: [PATCH] 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 Reviewed-by: Greg Kurz Message-Id: <20190626023130.31315-4-xieyongji@baidu.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/virtio/virtio.c | 28 ++++++++++++++++++++-------- 1 file 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; -- 2.39.2