| .. | .. |
|---|
| 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 | }; |
|---|