aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/vhost/vhost.c
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2010-06-24 09:59:59 -0400
committerMichael S. Tsirkin <mst@redhat.com>2010-06-27 04:52:25 -0400
commitd5675bd204efd87a174eeea592de23c4c4e7f908 (patch)
tree11ec7e455d21285da68fa7db40af07ebf45f9d0e /drivers/vhost/vhost.c
parent38000a94a902e94ca8b5498f7871c6316de8957a (diff)
vhost: break out of polling loop on error
When ring parsing fails, we currently handle this as ring empty condition. This means that we enable kicks and recheck ring empty: if this not empty, we re-start polling which of course will fail again. Instead, let's return a negative error code and stop polling. Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'drivers/vhost/vhost.c')
-rw-r--r--drivers/vhost/vhost.c33
1 files changed, 17 insertions, 16 deletions
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 3b83382e06eb..5ccd384ec0be 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -873,12 +873,13 @@ static unsigned get_indirect(struct vhost_dev *dev, struct vhost_virtqueue *vq,
873 * number of output then some number of input descriptors, it's actually two 873 * number of output then some number of input descriptors, it's actually two
874 * iovecs, but we pack them into one and note how many of each there were. 874 * iovecs, but we pack them into one and note how many of each there were.
875 * 875 *
876 * This function returns the descriptor number found, or vq->num (which 876 * This function returns the descriptor number found, or vq->num (which is
877 * is never a valid descriptor number) if none was found. */ 877 * never a valid descriptor number) if none was found. A negative code is
878unsigned vhost_get_vq_desc(struct vhost_dev *dev, struct vhost_virtqueue *vq, 878 * returned on error. */
879 struct iovec iov[], unsigned int iov_size, 879int vhost_get_vq_desc(struct vhost_dev *dev, struct vhost_virtqueue *vq,
880 unsigned int *out_num, unsigned int *in_num, 880 struct iovec iov[], unsigned int iov_size,
881 struct vhost_log *log, unsigned int *log_num) 881 unsigned int *out_num, unsigned int *in_num,
882 struct vhost_log *log, unsigned int *log_num)
882{ 883{
883 struct vring_desc desc; 884 struct vring_desc desc;
884 unsigned int i, head, found = 0; 885 unsigned int i, head, found = 0;
@@ -890,13 +891,13 @@ unsigned vhost_get_vq_desc(struct vhost_dev *dev, struct vhost_virtqueue *vq,
890 if (get_user(vq->avail_idx, &vq->avail->idx)) { 891 if (get_user(vq->avail_idx, &vq->avail->idx)) {
891 vq_err(vq, "Failed to access avail idx at %p\n", 892 vq_err(vq, "Failed to access avail idx at %p\n",
892 &vq->avail->idx); 893 &vq->avail->idx);
893 return vq->num; 894 return -EFAULT;
894 } 895 }
895 896
896 if ((u16)(vq->avail_idx - last_avail_idx) > vq->num) { 897 if ((u16)(vq->avail_idx - last_avail_idx) > vq->num) {
897 vq_err(vq, "Guest moved used index from %u to %u", 898 vq_err(vq, "Guest moved used index from %u to %u",
898 last_avail_idx, vq->avail_idx); 899 last_avail_idx, vq->avail_idx);
899 return vq->num; 900 return -EFAULT;
900 } 901 }
901 902
902 /* If there's nothing new since last we looked, return invalid. */ 903 /* If there's nothing new since last we looked, return invalid. */
@@ -912,14 +913,14 @@ unsigned vhost_get_vq_desc(struct vhost_dev *dev, struct vhost_virtqueue *vq,
912 vq_err(vq, "Failed to read head: idx %d address %p\n", 913 vq_err(vq, "Failed to read head: idx %d address %p\n",
913 last_avail_idx, 914 last_avail_idx,
914 &vq->avail->ring[last_avail_idx % vq->num]); 915 &vq->avail->ring[last_avail_idx % vq->num]);
915 return vq->num; 916 return -EFAULT;
916 } 917 }
917 918
918 /* If their number is silly, that's an error. */ 919 /* If their number is silly, that's an error. */
919 if (head >= vq->num) { 920 if (head >= vq->num) {
920 vq_err(vq, "Guest says index %u > %u is available", 921 vq_err(vq, "Guest says index %u > %u is available",
921 head, vq->num); 922 head, vq->num);
922 return vq->num; 923 return -EINVAL;
923 } 924 }
924 925
925 /* When we start there are none of either input nor output. */ 926 /* When we start there are none of either input nor output. */
@@ -933,19 +934,19 @@ unsigned vhost_get_vq_desc(struct vhost_dev *dev, struct vhost_virtqueue *vq,
933 if (i >= vq->num) { 934 if (i >= vq->num) {
934 vq_err(vq, "Desc index is %u > %u, head = %u", 935 vq_err(vq, "Desc index is %u > %u, head = %u",
935 i, vq->num, head); 936 i, vq->num, head);
936 return vq->num; 937 return -EINVAL;
937 } 938 }
938 if (++found > vq->num) { 939 if (++found > vq->num) {
939 vq_err(vq, "Loop detected: last one at %u " 940 vq_err(vq, "Loop detected: last one at %u "
940 "vq size %u head %u\n", 941 "vq size %u head %u\n",
941 i, vq->num, head); 942 i, vq->num, head);
942 return vq->num; 943 return -EINVAL;
943 } 944 }
944 ret = copy_from_user(&desc, vq->desc + i, sizeof desc); 945 ret = copy_from_user(&desc, vq->desc + i, sizeof desc);
945 if (ret) { 946 if (ret) {
946 vq_err(vq, "Failed to get descriptor: idx %d addr %p\n", 947 vq_err(vq, "Failed to get descriptor: idx %d addr %p\n",
947 i, vq->desc + i); 948 i, vq->desc + i);
948 return vq->num; 949 return -EFAULT;
949 } 950 }
950 if (desc.flags & VRING_DESC_F_INDIRECT) { 951 if (desc.flags & VRING_DESC_F_INDIRECT) {
951 ret = get_indirect(dev, vq, iov, iov_size, 952 ret = get_indirect(dev, vq, iov, iov_size,
@@ -954,7 +955,7 @@ unsigned vhost_get_vq_desc(struct vhost_dev *dev, struct vhost_virtqueue *vq,
954 if (ret < 0) { 955 if (ret < 0) {
955 vq_err(vq, "Failure detected " 956 vq_err(vq, "Failure detected "
956 "in indirect descriptor at idx %d\n", i); 957 "in indirect descriptor at idx %d\n", i);
957 return vq->num; 958 return ret;
958 } 959 }
959 continue; 960 continue;
960 } 961 }
@@ -964,7 +965,7 @@ unsigned vhost_get_vq_desc(struct vhost_dev *dev, struct vhost_virtqueue *vq,
964 if (ret < 0) { 965 if (ret < 0) {
965 vq_err(vq, "Translation failure %d descriptor idx %d\n", 966 vq_err(vq, "Translation failure %d descriptor idx %d\n",
966 ret, i); 967 ret, i);
967 return vq->num; 968 return ret;
968 } 969 }
969 if (desc.flags & VRING_DESC_F_WRITE) { 970 if (desc.flags & VRING_DESC_F_WRITE) {
970 /* If this is an input descriptor, 971 /* If this is an input descriptor,
@@ -981,7 +982,7 @@ unsigned vhost_get_vq_desc(struct vhost_dev *dev, struct vhost_virtqueue *vq,
981 if (*in_num) { 982 if (*in_num) {
982 vq_err(vq, "Descriptor has out after in: " 983 vq_err(vq, "Descriptor has out after in: "
983 "idx %d\n", i); 984 "idx %d\n", i);
984 return vq->num; 985 return -EINVAL;
985 } 986 }
986 *out_num += ret; 987 *out_num += ret;
987 } 988 }