diff options
| -rw-r--r-- | drivers/vhost/test.c | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c index 9b71a577f7bd..a73ea217f24d 100644 --- a/drivers/vhost/test.c +++ b/drivers/vhost/test.c | |||
| @@ -38,17 +38,19 @@ struct vhost_test { | |||
| 38 | * read-size critical section for our kind of RCU. */ | 38 | * read-size critical section for our kind of RCU. */ |
| 39 | static void handle_vq(struct vhost_test *n) | 39 | static void handle_vq(struct vhost_test *n) |
| 40 | { | 40 | { |
| 41 | struct vhost_virtqueue *vq = &n->dev.vqs[VHOST_TEST_VQ]; | 41 | struct vhost_virtqueue *vq = &n->vqs[VHOST_TEST_VQ]; |
| 42 | unsigned out, in; | 42 | unsigned out, in; |
| 43 | int head; | 43 | int head; |
| 44 | size_t len, total_len = 0; | 44 | size_t len, total_len = 0; |
| 45 | void *private; | 45 | void *private; |
| 46 | 46 | ||
| 47 | private = rcu_dereference_check(vq->private_data, 1); | 47 | mutex_lock(&vq->mutex); |
| 48 | if (!private) | 48 | private = vq->private_data; |
| 49 | if (!private) { | ||
| 50 | mutex_unlock(&vq->mutex); | ||
| 49 | return; | 51 | return; |
| 52 | } | ||
| 50 | 53 | ||
| 51 | mutex_lock(&vq->mutex); | ||
| 52 | vhost_disable_notify(&n->dev, vq); | 54 | vhost_disable_notify(&n->dev, vq); |
| 53 | 55 | ||
| 54 | for (;;) { | 56 | for (;;) { |
| @@ -102,15 +104,23 @@ static int vhost_test_open(struct inode *inode, struct file *f) | |||
| 102 | { | 104 | { |
| 103 | struct vhost_test *n = kmalloc(sizeof *n, GFP_KERNEL); | 105 | struct vhost_test *n = kmalloc(sizeof *n, GFP_KERNEL); |
| 104 | struct vhost_dev *dev; | 106 | struct vhost_dev *dev; |
| 107 | struct vhost_virtqueue **vqs; | ||
| 105 | int r; | 108 | int r; |
| 106 | 109 | ||
| 107 | if (!n) | 110 | if (!n) |
| 108 | return -ENOMEM; | 111 | return -ENOMEM; |
| 112 | vqs = kmalloc(VHOST_TEST_VQ_MAX * sizeof(*vqs), GFP_KERNEL); | ||
| 113 | if (!vqs) { | ||
| 114 | kfree(n); | ||
| 115 | return -ENOMEM; | ||
| 116 | } | ||
| 109 | 117 | ||
| 110 | dev = &n->dev; | 118 | dev = &n->dev; |
| 119 | vqs[VHOST_TEST_VQ] = &n->vqs[VHOST_TEST_VQ]; | ||
| 111 | n->vqs[VHOST_TEST_VQ].handle_kick = handle_vq_kick; | 120 | n->vqs[VHOST_TEST_VQ].handle_kick = handle_vq_kick; |
| 112 | r = vhost_dev_init(dev, n->vqs, VHOST_TEST_VQ_MAX); | 121 | r = vhost_dev_init(dev, vqs, VHOST_TEST_VQ_MAX); |
| 113 | if (r < 0) { | 122 | if (r < 0) { |
| 123 | kfree(vqs); | ||
| 114 | kfree(n); | 124 | kfree(n); |
| 115 | return r; | 125 | return r; |
| 116 | } | 126 | } |
| @@ -126,9 +136,8 @@ static void *vhost_test_stop_vq(struct vhost_test *n, | |||
| 126 | void *private; | 136 | void *private; |
| 127 | 137 | ||
| 128 | mutex_lock(&vq->mutex); | 138 | mutex_lock(&vq->mutex); |
| 129 | private = rcu_dereference_protected(vq->private_data, | 139 | private = vq->private_data; |
| 130 | lockdep_is_held(&vq->mutex)); | 140 | vq->private_data = NULL; |
| 131 | rcu_assign_pointer(vq->private_data, NULL); | ||
| 132 | mutex_unlock(&vq->mutex); | 141 | mutex_unlock(&vq->mutex); |
| 133 | return private; | 142 | return private; |
| 134 | } | 143 | } |
| @@ -140,7 +149,7 @@ static void vhost_test_stop(struct vhost_test *n, void **privatep) | |||
| 140 | 149 | ||
| 141 | static void vhost_test_flush_vq(struct vhost_test *n, int index) | 150 | static void vhost_test_flush_vq(struct vhost_test *n, int index) |
| 142 | { | 151 | { |
| 143 | vhost_poll_flush(&n->dev.vqs[index].poll); | 152 | vhost_poll_flush(&n->vqs[index].poll); |
| 144 | } | 153 | } |
| 145 | 154 | ||
| 146 | static void vhost_test_flush(struct vhost_test *n) | 155 | static void vhost_test_flush(struct vhost_test *n) |
| @@ -268,14 +277,14 @@ static long vhost_test_ioctl(struct file *f, unsigned int ioctl, | |||
| 268 | return -EFAULT; | 277 | return -EFAULT; |
| 269 | return vhost_test_run(n, test); | 278 | return vhost_test_run(n, test); |
| 270 | case VHOST_GET_FEATURES: | 279 | case VHOST_GET_FEATURES: |
| 271 | features = VHOST_NET_FEATURES; | 280 | features = VHOST_FEATURES; |
| 272 | if (copy_to_user(featurep, &features, sizeof features)) | 281 | if (copy_to_user(featurep, &features, sizeof features)) |
| 273 | return -EFAULT; | 282 | return -EFAULT; |
| 274 | return 0; | 283 | return 0; |
| 275 | case VHOST_SET_FEATURES: | 284 | case VHOST_SET_FEATURES: |
| 276 | if (copy_from_user(&features, featurep, sizeof features)) | 285 | if (copy_from_user(&features, featurep, sizeof features)) |
| 277 | return -EFAULT; | 286 | return -EFAULT; |
| 278 | if (features & ~VHOST_NET_FEATURES) | 287 | if (features & ~VHOST_FEATURES) |
| 279 | return -EOPNOTSUPP; | 288 | return -EOPNOTSUPP; |
| 280 | return vhost_test_set_features(n, features); | 289 | return vhost_test_set_features(n, features); |
| 281 | case VHOST_RESET_OWNER: | 290 | case VHOST_RESET_OWNER: |
