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: badaf79cfd ("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>
This commit is contained in:
Xie Yongji 2019-06-26 10:31:28 +08:00 committed by Michael S. Tsirkin
parent 7abccd088c
commit 868a8f44f5
1 changed files with 20 additions and 8 deletions

View File

@ -1212,7 +1212,7 @@ void virtio_reset(void *opaque)
k->reset(vdev); 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->started = false;
vdev->broken = false; vdev->broken = false;
vdev->guest_features = 0; vdev->guest_features = 0;
@ -2063,14 +2063,21 @@ int virtio_set_features(VirtIODevice *vdev, uint64_t val)
return -EINVAL; return -EINVAL;
} }
ret = virtio_set_features_nocheck(vdev, val); ret = virtio_set_features_nocheck(vdev, val);
if (!ret && virtio_vdev_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) { if (!ret) {
/* VIRTIO_RING_F_EVENT_IDX changes the size of the caches. */ if (virtio_vdev_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
int i; /* VIRTIO_RING_F_EVENT_IDX changes the size of the caches. */
for (i = 0; i < VIRTIO_QUEUE_MAX; i++) { int i;
if (vdev->vq[i].vring.num != 0) { for (i = 0; i < VIRTIO_QUEUE_MAX; i++) {
virtio_init_region_cache(vdev, 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; 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(); rcu_read_lock();
for (i = 0; i < num; i++) { for (i = 0; i < num; i++) {
if (vdev->vq[i].vring.desc) { 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); 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->started = false;
vdev->device_id = device_id; vdev->device_id = device_id;
vdev->status = 0; vdev->status = 0;