vring: factor common code for error exits

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Paolo Bonzini 2013-12-10 13:26:59 +01:00 committed by Stefan Hajnoczi
parent 4d684832e5
commit 781c117f37
2 changed files with 22 additions and 13 deletions

View File

@ -308,6 +308,7 @@ static void handle_notify(EventNotifier *e)
if (process_request(&s->ioqueue, iov, out_num, in_num, head) < 0) { if (process_request(&s->ioqueue, iov, out_num, in_num, head) < 0) {
vring_set_broken(&s->vring); vring_set_broken(&s->vring);
ret = -EFAULT;
break; break;
} }
iov += out_num + in_num; iov += out_num + in_num;

View File

@ -244,7 +244,8 @@ int vring_pop(VirtIODevice *vdev, Vring *vring,
/* If there was a fatal error then refuse operation */ /* If there was a fatal error then refuse operation */
if (vring->broken) { if (vring->broken) {
return -EFAULT; ret = -EFAULT;
goto out;
} }
/* Check it isn't doing very strange things with descriptor numbers. */ /* 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)) { if (unlikely((uint16_t)(avail_idx - last_avail_idx) > num)) {
error_report("Guest moved used index from %u to %u", error_report("Guest moved used index from %u to %u",
last_avail_idx, avail_idx); last_avail_idx, avail_idx);
vring->broken = true; ret = -EFAULT;
return -EFAULT; goto out;
} }
/* If there's nothing new since last we looked. */ /* If there's nothing new since last we looked. */
if (avail_idx == last_avail_idx) { if (avail_idx == last_avail_idx) {
return -EAGAIN; ret = -EAGAIN;
goto out;
} }
/* Only get avail ring entries after they have been exposed by guest. */ /* 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 their number is silly, that's an error. */
if (unlikely(head >= num)) { if (unlikely(head >= num)) {
error_report("Guest says index %u > %u is available", head, num); error_report("Guest says index %u > %u is available", head, num);
vring->broken = true; ret = -EFAULT;
return -EFAULT; goto out;
} }
if (vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) { if (vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
@ -289,14 +291,14 @@ int vring_pop(VirtIODevice *vdev, Vring *vring,
do { do {
if (unlikely(i >= num)) { if (unlikely(i >= num)) {
error_report("Desc index is %u > %u, head = %u", i, num, head); error_report("Desc index is %u > %u, head = %u", i, num, head);
vring->broken = true; ret = -EFAULT;
return -EFAULT; goto out;
} }
if (unlikely(++found > num)) { if (unlikely(++found > num)) {
error_report("Loop detected: last one at %u vq size %u head %u", error_report("Loop detected: last one at %u vq size %u head %u",
i, num, head); i, num, head);
vring->broken = true; ret = -EFAULT;
return -EFAULT; goto out;
} }
desc = vring->vr.desc[i]; desc = vring->vr.desc[i];
@ -306,15 +308,14 @@ int vring_pop(VirtIODevice *vdev, Vring *vring,
if (desc.flags & VRING_DESC_F_INDIRECT) { if (desc.flags & VRING_DESC_F_INDIRECT) {
int ret = get_indirect(vring, iov, iov_end, out_num, in_num, &desc); int ret = get_indirect(vring, iov, iov_end, out_num, in_num, &desc);
if (ret < 0) { if (ret < 0) {
return ret; goto out;
} }
continue; continue;
} }
ret = get_desc(vring, iov, iov_end, out_num, in_num, &desc); ret = get_desc(vring, iov, iov_end, out_num, in_num, &desc);
if (ret < 0) { if (ret < 0) {
vring->broken |= (ret == -EFAULT); goto out;
return ret;
} }
i = desc.next; i = desc.next;
@ -323,6 +324,13 @@ int vring_pop(VirtIODevice *vdev, Vring *vring,
/* On success, increment avail index. */ /* On success, increment avail index. */
vring->last_avail_idx++; vring->last_avail_idx++;
return head; 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. /* After we've used one of their buffers, we tell them about it.