From 6d719f4240ad6bbd2ae434cad1d56c5b6c16b7f3 Mon Sep 17 00:00:00 2001 From: John Snow Date: Fri, 25 Jan 2019 22:50:05 +0100 Subject: [PATCH 05/23] virtio: update MemoryRegionCaches when guest negotiates features RH-Author: John Snow Message-id: <20190125225007.8197-6-jsnow@redhat.com> Patchwork-id: 84121 O-Subject: [RHEL-7.7 qemu-kvm-rhev PATCH v2 5/7] virtio: update MemoryRegionCaches when guest negotiates features Bugzilla: 1597482 RH-Acked-by: Paolo Bonzini RH-Acked-by: Peter Xu RH-Acked-by: Stefano Garzarella From: Paolo Bonzini Because the cache is sized to include the rings and the event indices, negotiating the VIRTIO_RING_F_EVENT_IDX feature will result in the size of the cache changing. And because MemoryRegionCache accesses are range-checked, if we skip this we end up with an assertion failure. This happens with OpenBSD 6.3. Reported-by: Fam Zheng Fixes: 97cd965c070152bc626c7507df9fb356bbe1cd81 Cc: qemu-stable@nongnu.org Signed-off-by: Paolo Bonzini Tested-by: Fam Zheng Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin (cherry picked from commit db812c4073c77c8a64db8d6663b3416a587c7b4a) Signed-off-by: John Snow Signed-off-by: Miroslav Rezanina --- hw/virtio/virtio.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 5549bb4..77eadaa 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -2021,14 +2021,25 @@ static int virtio_set_features_nocheck(VirtIODevice *vdev, uint64_t val) int virtio_set_features(VirtIODevice *vdev, uint64_t val) { - /* + int ret; + /* * The driver must not attempt to set features after feature negotiation * has finished. */ if (vdev->status & VIRTIO_CONFIG_S_FEATURES_OK) { return -EINVAL; } - return 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)) { + /* 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); + } + } + } + return ret; } int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id) -- 1.8.3.1