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 <cornelia.huck@de.ibm.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
Jason Wang 2017-03-15 19:48:30 +08:00 committed by Michael S. Tsirkin
parent 72d9196f1e
commit 168e4af3c1

View file

@ -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;