diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2013-12-10 13:26:59 +0100 |
---|---|---|
committer | Stefan Hajnoczi <stefanha@redhat.com> | 2013-12-20 09:11:57 +0100 |
commit | 781c117f3758bdb21e982d2aebba81febceccfe5 (patch) | |
tree | 32679852eae31ecb454478d7d43c9abade95947f /hw | |
parent | 4d684832e54afe971fd8f94cb830ec1e135648e7 (diff) | |
download | hqemu-781c117f3758bdb21e982d2aebba81febceccfe5.zip hqemu-781c117f3758bdb21e982d2aebba81febceccfe5.tar.gz |
vring: factor common code for error exits
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/block/dataplane/virtio-blk.c | 1 | ||||
-rw-r--r-- | hw/virtio/dataplane/vring.c | 34 |
2 files changed, 22 insertions, 13 deletions
diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c index 1e57f3a..2b4a773 100644 --- a/hw/block/dataplane/virtio-blk.c +++ b/hw/block/dataplane/virtio-blk.c @@ -308,6 +308,7 @@ static void handle_notify(EventNotifier *e) if (process_request(&s->ioqueue, iov, out_num, in_num, head) < 0) { vring_set_broken(&s->vring); + ret = -EFAULT; break; } iov += out_num + in_num; diff --git a/hw/virtio/dataplane/vring.c b/hw/virtio/dataplane/vring.c index 8294f36..d81b653 100644 --- a/hw/virtio/dataplane/vring.c +++ b/hw/virtio/dataplane/vring.c @@ -244,7 +244,8 @@ int vring_pop(VirtIODevice *vdev, Vring *vring, /* If there was a fatal error then refuse operation */ if (vring->broken) { - return -EFAULT; + ret = -EFAULT; + goto out; } /* Check it isn't doing very strange things with descriptor numbers. */ @@ -255,13 +256,14 @@ int vring_pop(VirtIODevice *vdev, Vring *vring, if (unlikely((uint16_t)(avail_idx - last_avail_idx) > num)) { error_report("Guest moved used index from %u to %u", last_avail_idx, avail_idx); - vring->broken = true; - return -EFAULT; + ret = -EFAULT; + goto out; } /* If there's nothing new since last we looked. */ if (avail_idx == last_avail_idx) { - return -EAGAIN; + ret = -EAGAIN; + goto out; } /* Only get avail ring entries after they have been exposed by guest. */ @@ -274,8 +276,8 @@ int vring_pop(VirtIODevice *vdev, Vring *vring, /* If their number is silly, that's an error. */ if (unlikely(head >= num)) { error_report("Guest says index %u > %u is available", head, num); - vring->broken = true; - return -EFAULT; + ret = -EFAULT; + goto out; } if (vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) { @@ -289,14 +291,14 @@ int vring_pop(VirtIODevice *vdev, Vring *vring, do { if (unlikely(i >= num)) { error_report("Desc index is %u > %u, head = %u", i, num, head); - vring->broken = true; - return -EFAULT; + ret = -EFAULT; + goto out; } if (unlikely(++found > num)) { error_report("Loop detected: last one at %u vq size %u head %u", i, num, head); - vring->broken = true; - return -EFAULT; + ret = -EFAULT; + goto out; } desc = vring->vr.desc[i]; @@ -306,15 +308,14 @@ int vring_pop(VirtIODevice *vdev, Vring *vring, if (desc.flags & VRING_DESC_F_INDIRECT) { int ret = get_indirect(vring, iov, iov_end, out_num, in_num, &desc); if (ret < 0) { - return ret; + goto out; } continue; } ret = get_desc(vring, iov, iov_end, out_num, in_num, &desc); if (ret < 0) { - vring->broken |= (ret == -EFAULT); - return ret; + goto out; } i = desc.next; @@ -323,6 +324,13 @@ int vring_pop(VirtIODevice *vdev, Vring *vring, /* On success, increment avail index. */ vring->last_avail_idx++; return head; + +out: + assert(ret < 0); + if (ret == -EFAULT) { + vring->broken = true; + } + return ret; } /* After we've used one of their buffers, we tell them about it. |