vhost: fix overflow on shadow used ring
The shadow used ring's size is the same as the vq's size, so we shouldn't try more than "vq size" times. Besides, the element pointed by avail->idx isn't available to the device, so we will return error when try "vq size" times. Fixes:24e4844048
("vhost: unify Rx mergeable and non-mergeable paths") Fixes:a922401f35
("vhost: add Rx support for packed ring") Signed-off-by: Tiwei Bie <tiwei.bie@intel.com> Reviewed-by: Jens Freimann <jfreimann@redhat.com>
This commit is contained in:
parent
6e2fad861a
commit
14962a9c4f
@ -415,13 +415,20 @@ reserve_avail_buf_split(struct virtio_net *dev, struct vhost_virtqueue *vq,
|
||||
cur_idx = vq->last_avail_idx;
|
||||
|
||||
if (rxvq_is_mergeable(dev))
|
||||
max_tries = vq->size;
|
||||
max_tries = vq->size - 1;
|
||||
else
|
||||
max_tries = 1;
|
||||
|
||||
while (size > 0) {
|
||||
if (unlikely(cur_idx == avail_head))
|
||||
return -1;
|
||||
/*
|
||||
* if we tried all available ring items, and still
|
||||
* can't get enough buf, it means something abnormal
|
||||
* happened.
|
||||
*/
|
||||
if (unlikely(++tries > max_tries))
|
||||
return -1;
|
||||
|
||||
if (unlikely(fill_vec_buf_split(dev, vq, cur_idx,
|
||||
&vec_idx, buf_vec,
|
||||
@ -433,16 +440,7 @@ reserve_avail_buf_split(struct virtio_net *dev, struct vhost_virtqueue *vq,
|
||||
size -= len;
|
||||
|
||||
cur_idx++;
|
||||
tries++;
|
||||
*num_buffers += 1;
|
||||
|
||||
/*
|
||||
* if we tried all available ring items, and still
|
||||
* can't get enough buf, it means something abnormal
|
||||
* happened.
|
||||
*/
|
||||
if (unlikely(tries > max_tries))
|
||||
return -1;
|
||||
}
|
||||
|
||||
*nr_vec = vec_idx;
|
||||
@ -582,11 +580,19 @@ reserve_avail_buf_packed(struct virtio_net *dev, struct vhost_virtqueue *vq,
|
||||
avail_idx = vq->last_avail_idx;
|
||||
|
||||
if (rxvq_is_mergeable(dev))
|
||||
max_tries = vq->size;
|
||||
max_tries = vq->size - 1;
|
||||
else
|
||||
max_tries = 1;
|
||||
|
||||
while (size > 0) {
|
||||
/*
|
||||
* if we tried all available ring items, and still
|
||||
* can't get enough buf, it means something abnormal
|
||||
* happened.
|
||||
*/
|
||||
if (unlikely(++tries > max_tries))
|
||||
return -1;
|
||||
|
||||
if (unlikely(fill_vec_buf_packed(dev, vq,
|
||||
avail_idx, &desc_count,
|
||||
buf_vec, &vec_idx,
|
||||
@ -603,16 +609,7 @@ reserve_avail_buf_packed(struct virtio_net *dev, struct vhost_virtqueue *vq,
|
||||
avail_idx -= vq->size;
|
||||
|
||||
*nr_descs += desc_count;
|
||||
tries++;
|
||||
*num_buffers += 1;
|
||||
|
||||
/*
|
||||
* if we tried all available ring items, and still
|
||||
* can't get enough buf, it means something abnormal
|
||||
* happened.
|
||||
*/
|
||||
if (unlikely(tries > max_tries))
|
||||
return -1;
|
||||
}
|
||||
|
||||
*nr_vec = vec_idx;
|
||||
|
Loading…
Reference in New Issue
Block a user