summaryrefslogtreecommitdiff
path: root/hw/virtio/virtio.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/virtio/virtio.c')
-rw-r--r--hw/virtio/virtio.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 09f62c6c70..2f1e73bc75 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -377,8 +377,8 @@ void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes,
/* loop over the indirect descriptor table */
indirect = 1;
max = vring_desc_len(desc_pa, i) / sizeof(VRingDesc);
- num_bufs = i = 0;
desc_pa = vring_desc_addr(desc_pa, i);
+ num_bufs = i = 0;
}
do {
@@ -673,10 +673,16 @@ hwaddr virtio_queue_get_addr(VirtIODevice *vdev, int n)
void virtio_queue_set_num(VirtIODevice *vdev, int n, int num)
{
- if (num <= VIRTQUEUE_MAX_SIZE) {
- vdev->vq[n].vring.num = num;
- virtqueue_init(&vdev->vq[n]);
+ /* Don't allow guest to flip queue between existent and
+ * nonexistent states, or to set it to an invalid size.
+ */
+ if (!!num != !!vdev->vq[n].vring.num ||
+ num > VIRTQUEUE_MAX_SIZE ||
+ num < 0) {
+ return;
}
+ vdev->vq[n].vring.num = num;
+ virtqueue_init(&vdev->vq[n]);
}
int virtio_queue_get_num(VirtIODevice *vdev, int n)
@@ -1059,6 +1065,11 @@ void virtio_queue_set_last_avail_idx(VirtIODevice *vdev, int n, uint16_t idx)
vdev->vq[n].last_avail_idx = idx;
}
+void virtio_queue_invalidate_signalled_used(VirtIODevice *vdev, int n)
+{
+ vdev->vq[n].signalled_used_valid = false;
+}
+
VirtQueue *virtio_get_queue(VirtIODevice *vdev, int n)
{
return vdev->vq + n;