virtio: update MemoryRegionCaches when guest negotiates features
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 <famz@redhat.com>
Fixes: 97cd965c07
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Tested-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
dbb6da8ba7
commit
db812c4073
@ -2006,6 +2006,7 @@ 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.
|
||||
@ -2013,7 +2014,17 @@ int virtio_set_features(VirtIODevice *vdev, uint64_t val)
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user