On 19/09/20 10:27, Li Qiang wrote:
> Current the 'virtio_set_features' only update the 'MemorRegionCaches'
> when the 'virtio_set_features_nocheck' return '0' which means it is
> not bad features. However the guest can still trigger the access of the
> used vring after set bad features. In this situation it will cause assert
> failure in 'ADDRESS_SPACE_ST_CACHED'.
> 
> Buglink: https://bugs.launchpad.net/qemu/+bug/1890333
> Fixes: db812c4073c7 ("virtio: update MemoryRegionCaches when guest negotiates 
> features")
> Reported-by: Alexander Bulekov <alx...@bu.edu>
> Signed-off-by: Li Qiang <liq...@163.com>
> ---
>  hw/virtio/virtio.c | 17 ++++++++---------
>  1 file changed, 8 insertions(+), 9 deletions(-)
> 
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index e983025217..4441ae5ed4 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -2963,17 +2963,16 @@ int virtio_set_features(VirtIODevice *vdev, uint64_t 
> val)
>          return -EINVAL;
>      }
>      ret = virtio_set_features_nocheck(vdev, val);
> -    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_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_device_started(vdev, vdev->status) &&
>              !virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) {
>              vdev->start_on_kick = true;
> 

Reviewed-by: Paolo Bonzini <pbonz...@redhat.com>


Reply via email to