From 168e4af3c129534ee7d81edc238a9aa9ca0dd474 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Wed, 15 Mar 2017 19:48:30 +0800 Subject: [PATCH] virtio: guard against NULL pfn To avoid access stale memory region cache after reset, this patch check the existence of virtqueue pfn for all exported virtqueue access helpers before trying to use them. Cc: Cornelia Huck Cc: Paolo Bonzini Reviewed-by: Cornelia Huck Signed-off-by: Jason Wang Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/virtio/virtio.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index efce4b343a..916457966c 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -318,6 +318,10 @@ int virtio_queue_ready(VirtQueue *vq) * Called within rcu_read_lock(). */ static int virtio_queue_empty_rcu(VirtQueue *vq) { + if (unlikely(!vq->vring.avail)) { + return 1; + } + if (vq->shadow_avail_idx != vq->last_avail_idx) { return 0; } @@ -329,6 +333,10 @@ int virtio_queue_empty(VirtQueue *vq) { bool empty; + if (unlikely(!vq->vring.avail)) { + return 1; + } + if (vq->shadow_avail_idx != vq->last_avail_idx) { return 0; } @@ -431,6 +439,10 @@ void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem, return; } + if (unlikely(!vq->vring.used)) { + return; + } + idx = (idx + vq->used_idx) % vq->vring.num; uelem.id = elem->index; @@ -448,6 +460,10 @@ void virtqueue_flush(VirtQueue *vq, unsigned int count) return; } + if (unlikely(!vq->vring.used)) { + return; + } + /* Make sure buffer is written before we update index. */ smp_wmb(); trace_virtqueue_flush(vq, count); @@ -546,6 +562,16 @@ void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes, int64_t len = 0; int rc; + if (unlikely(!vq->vring.desc)) { + if (in_bytes) { + *in_bytes = 0; + } + if (out_bytes) { + *out_bytes = 0; + } + return; + } + rcu_read_lock(); idx = vq->last_avail_idx; total_bufs = in_total = out_total = 0;