.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* Copyright (C) 2009 Red Hat, Inc. |
---|
2 | 3 | * Author: Michael S. Tsirkin <mst@redhat.com> |
---|
3 | | - * |
---|
4 | | - * This work is licensed under the terms of the GNU GPL, version 2. |
---|
5 | 4 | * |
---|
6 | 5 | * test virtio server in host kernel. |
---|
7 | 6 | */ |
---|
.. | .. |
---|
50 | 49 | void *private; |
---|
51 | 50 | |
---|
52 | 51 | mutex_lock(&vq->mutex); |
---|
53 | | - private = vq->private_data; |
---|
| 52 | + private = vhost_vq_get_backend(vq); |
---|
54 | 53 | if (!private) { |
---|
55 | 54 | mutex_unlock(&vq->mutex); |
---|
56 | 55 | return; |
---|
.. | .. |
---|
121 | 120 | vqs[VHOST_TEST_VQ] = &n->vqs[VHOST_TEST_VQ]; |
---|
122 | 121 | n->vqs[VHOST_TEST_VQ].handle_kick = handle_vq_kick; |
---|
123 | 122 | vhost_dev_init(dev, vqs, VHOST_TEST_VQ_MAX, UIO_MAXIOV, |
---|
124 | | - VHOST_TEST_PKT_WEIGHT, VHOST_TEST_WEIGHT); |
---|
| 123 | + VHOST_TEST_PKT_WEIGHT, VHOST_TEST_WEIGHT, true, NULL); |
---|
125 | 124 | |
---|
126 | 125 | f->private_data = n; |
---|
127 | 126 | |
---|
.. | .. |
---|
134 | 133 | void *private; |
---|
135 | 134 | |
---|
136 | 135 | mutex_lock(&vq->mutex); |
---|
137 | | - private = vq->private_data; |
---|
138 | | - vq->private_data = NULL; |
---|
| 136 | + private = vhost_vq_get_backend(vq); |
---|
| 137 | + vhost_vq_set_backend(vq, NULL); |
---|
139 | 138 | mutex_unlock(&vq->mutex); |
---|
140 | 139 | return private; |
---|
141 | 140 | } |
---|
.. | .. |
---|
199 | 198 | priv = test ? n : NULL; |
---|
200 | 199 | |
---|
201 | 200 | /* start polling new socket */ |
---|
202 | | - oldpriv = vq->private_data; |
---|
203 | | - vq->private_data = priv; |
---|
| 201 | + oldpriv = vhost_vq_get_backend(vq); |
---|
| 202 | + vhost_vq_set_backend(vq, priv); |
---|
204 | 203 | |
---|
205 | 204 | r = vhost_vq_init_access(&n->vqs[index]); |
---|
206 | 205 | |
---|
.. | .. |
---|
226 | 225 | { |
---|
227 | 226 | void *priv = NULL; |
---|
228 | 227 | long err; |
---|
229 | | - struct vhost_umem *umem; |
---|
| 228 | + struct vhost_iotlb *umem; |
---|
230 | 229 | |
---|
231 | 230 | mutex_lock(&n->dev.mutex); |
---|
232 | 231 | err = vhost_dev_check_owner(&n->dev); |
---|
.. | .. |
---|
264 | 263 | return 0; |
---|
265 | 264 | } |
---|
266 | 265 | |
---|
| 266 | +static long vhost_test_set_backend(struct vhost_test *n, unsigned index, int fd) |
---|
| 267 | +{ |
---|
| 268 | + static void *backend; |
---|
| 269 | + |
---|
| 270 | + const bool enable = fd != -1; |
---|
| 271 | + struct vhost_virtqueue *vq; |
---|
| 272 | + int r; |
---|
| 273 | + |
---|
| 274 | + mutex_lock(&n->dev.mutex); |
---|
| 275 | + r = vhost_dev_check_owner(&n->dev); |
---|
| 276 | + if (r) |
---|
| 277 | + goto err; |
---|
| 278 | + |
---|
| 279 | + if (index >= VHOST_TEST_VQ_MAX) { |
---|
| 280 | + r = -ENOBUFS; |
---|
| 281 | + goto err; |
---|
| 282 | + } |
---|
| 283 | + vq = &n->vqs[index]; |
---|
| 284 | + mutex_lock(&vq->mutex); |
---|
| 285 | + |
---|
| 286 | + /* Verify that ring has been setup correctly. */ |
---|
| 287 | + if (!vhost_vq_access_ok(vq)) { |
---|
| 288 | + r = -EFAULT; |
---|
| 289 | + goto err_vq; |
---|
| 290 | + } |
---|
| 291 | + if (!enable) { |
---|
| 292 | + vhost_poll_stop(&vq->poll); |
---|
| 293 | + backend = vhost_vq_get_backend(vq); |
---|
| 294 | + vhost_vq_set_backend(vq, NULL); |
---|
| 295 | + } else { |
---|
| 296 | + vhost_vq_set_backend(vq, backend); |
---|
| 297 | + r = vhost_vq_init_access(vq); |
---|
| 298 | + if (r == 0) |
---|
| 299 | + r = vhost_poll_start(&vq->poll, vq->kick); |
---|
| 300 | + } |
---|
| 301 | + |
---|
| 302 | + mutex_unlock(&vq->mutex); |
---|
| 303 | + |
---|
| 304 | + if (enable) { |
---|
| 305 | + vhost_test_flush_vq(n, index); |
---|
| 306 | + } |
---|
| 307 | + |
---|
| 308 | + mutex_unlock(&n->dev.mutex); |
---|
| 309 | + return 0; |
---|
| 310 | + |
---|
| 311 | +err_vq: |
---|
| 312 | + mutex_unlock(&vq->mutex); |
---|
| 313 | +err: |
---|
| 314 | + mutex_unlock(&n->dev.mutex); |
---|
| 315 | + return r; |
---|
| 316 | +} |
---|
| 317 | + |
---|
267 | 318 | static long vhost_test_ioctl(struct file *f, unsigned int ioctl, |
---|
268 | 319 | unsigned long arg) |
---|
269 | 320 | { |
---|
| 321 | + struct vhost_vring_file backend; |
---|
270 | 322 | struct vhost_test *n = f->private_data; |
---|
271 | 323 | void __user *argp = (void __user *)arg; |
---|
272 | 324 | u64 __user *featurep = argp; |
---|
.. | .. |
---|
278 | 330 | if (copy_from_user(&test, argp, sizeof test)) |
---|
279 | 331 | return -EFAULT; |
---|
280 | 332 | return vhost_test_run(n, test); |
---|
| 333 | + case VHOST_TEST_SET_BACKEND: |
---|
| 334 | + if (copy_from_user(&backend, argp, sizeof backend)) |
---|
| 335 | + return -EFAULT; |
---|
| 336 | + return vhost_test_set_backend(n, backend.index, backend.fd); |
---|
281 | 337 | case VHOST_GET_FEATURES: |
---|
282 | 338 | features = VHOST_FEATURES; |
---|
283 | 339 | if (copy_to_user(featurep, &features, sizeof features)) |
---|
.. | .. |
---|
305 | 361 | } |
---|
306 | 362 | } |
---|
307 | 363 | |
---|
308 | | -#ifdef CONFIG_COMPAT |
---|
309 | | -static long vhost_test_compat_ioctl(struct file *f, unsigned int ioctl, |
---|
310 | | - unsigned long arg) |
---|
311 | | -{ |
---|
312 | | - return vhost_test_ioctl(f, ioctl, (unsigned long)compat_ptr(arg)); |
---|
313 | | -} |
---|
314 | | -#endif |
---|
315 | | - |
---|
316 | 364 | static const struct file_operations vhost_test_fops = { |
---|
317 | 365 | .owner = THIS_MODULE, |
---|
318 | 366 | .release = vhost_test_release, |
---|
319 | 367 | .unlocked_ioctl = vhost_test_ioctl, |
---|
320 | | -#ifdef CONFIG_COMPAT |
---|
321 | | - .compat_ioctl = vhost_test_compat_ioctl, |
---|
322 | | -#endif |
---|
| 368 | + .compat_ioctl = compat_ptr_ioctl, |
---|
323 | 369 | .open = vhost_test_open, |
---|
324 | 370 | .llseek = noop_llseek, |
---|
325 | 371 | }; |
---|