1 /* 2 * Copyright (C) 2015 Red Hat, Inc. 3 * All Rights Reserved. 4 * 5 * Authors: 6 * Dave Airlie 7 * Alon Levy 8 * 9 * Permission is hereby granted, free of charge, to any person obtaining a 10 * copy of this software and associated documentation files (the "Software"), 11 * to deal in the Software without restriction, including without limitation 12 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 13 * and/or sell copies of the Software, and to permit persons to whom the 14 * Software is furnished to do so, subject to the following conditions: 15 * 16 * The above copyright notice and this permission notice shall be included in 17 * all copies or substantial portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 * OTHER DEALINGS IN THE SOFTWARE. 26 */ 27 28 #include <linux/file.h> 29 #include <linux/sync_file.h> 30 #include <linux/uaccess.h> 31 32 #include <drm/drm_file.h> 33 #include <drm/virtgpu_drm.h> 34 35 #include "virtgpu_drv.h" 36 37 #define VIRTGPU_BLOB_FLAG_USE_MASK (VIRTGPU_BLOB_FLAG_USE_MAPPABLE | \ 38 VIRTGPU_BLOB_FLAG_USE_SHAREABLE | \ 39 VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE) 40 41 /* Must be called with &virtio_gpu_fpriv.struct_mutex held. */ 42 static void virtio_gpu_create_context_locked(struct virtio_gpu_device *vgdev, 43 struct virtio_gpu_fpriv *vfpriv) 44 { 45 if (vfpriv->explicit_debug_name) { 46 virtio_gpu_cmd_context_create(vgdev, vfpriv->ctx_id, 47 vfpriv->context_init, 48 strlen(vfpriv->debug_name), 49 vfpriv->debug_name); 50 } else { 51 char dbgname[TASK_COMM_LEN]; 52 53 get_task_comm(dbgname, current); 54 virtio_gpu_cmd_context_create(vgdev, vfpriv->ctx_id, 55 vfpriv->context_init, strlen(dbgname), 56 dbgname); 57 } 58 59 vfpriv->context_created = true; 60 } 61 62 void virtio_gpu_create_context(struct drm_device *dev, struct drm_file *file) 63 { 64 struct virtio_gpu_device *vgdev = dev->dev_private; 65 struct virtio_gpu_fpriv *vfpriv = file->driver_priv; 66 67 mutex_lock(&vfpriv->context_lock); 68 if (vfpriv->context_created) 69 goto out_unlock; 70 71 virtio_gpu_create_context_locked(vgdev, vfpriv); 72 73 out_unlock: 74 mutex_unlock(&vfpriv->context_lock); 75 } 76 77 static int virtio_gpu_map_ioctl(struct drm_device *dev, void *data, 78 struct drm_file *file) 79 { 80 struct virtio_gpu_device *vgdev = dev->dev_private; 81 struct drm_virtgpu_map *virtio_gpu_map = data; 82 83 return drm_gem_dumb_map_offset(file, vgdev->ddev, 84 virtio_gpu_map->handle, 85 &virtio_gpu_map->offset); 86 } 87 88 static int virtio_gpu_getparam_ioctl(struct drm_device *dev, void *data, 89 struct drm_file *file) 90 { 91 struct virtio_gpu_device *vgdev = dev->dev_private; 92 struct drm_virtgpu_getparam *param = data; 93 int value; 94 95 switch (param->param) { 96 case VIRTGPU_PARAM_3D_FEATURES: 97 value = vgdev->has_virgl_3d ? 1 : 0; 98 break; 99 case VIRTGPU_PARAM_CAPSET_QUERY_FIX: 100 value = 1; 101 break; 102 case VIRTGPU_PARAM_RESOURCE_BLOB: 103 value = vgdev->has_resource_blob ? 1 : 0; 104 break; 105 case VIRTGPU_PARAM_HOST_VISIBLE: 106 value = vgdev->has_host_visible ? 1 : 0; 107 break; 108 case VIRTGPU_PARAM_CROSS_DEVICE: 109 value = vgdev->has_resource_assign_uuid ? 1 : 0; 110 break; 111 case VIRTGPU_PARAM_CONTEXT_INIT: 112 value = vgdev->has_context_init ? 1 : 0; 113 break; 114 case VIRTGPU_PARAM_SUPPORTED_CAPSET_IDs: 115 value = vgdev->capset_id_mask; 116 break; 117 case VIRTGPU_PARAM_EXPLICIT_DEBUG_NAME: 118 value = vgdev->has_context_init ? 1 : 0; 119 break; 120 case VIRTGPU_PARAM_BLOB_ALIGNMENT: 121 if (!vgdev->has_blob_alignment) 122 return -ENOENT; 123 value = vgdev->blob_alignment; 124 break; 125 default: 126 return -EINVAL; 127 } 128 if (copy_to_user(u64_to_user_ptr(param->value), &value, sizeof(int))) 129 return -EFAULT; 130 131 return 0; 132 } 133 134 static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data, 135 struct drm_file *file) 136 { 137 struct virtio_gpu_device *vgdev = dev->dev_private; 138 struct drm_virtgpu_resource_create *rc = data; 139 struct virtio_gpu_fence *fence; 140 int ret; 141 struct virtio_gpu_object *qobj; 142 struct drm_gem_object *obj; 143 uint32_t handle = 0; 144 struct virtio_gpu_object_params params = { 0 }; 145 146 if (vgdev->has_virgl_3d) { 147 virtio_gpu_create_context(dev, file); 148 params.virgl = true; 149 params.target = rc->target; 150 params.bind = rc->bind; 151 params.depth = rc->depth; 152 params.array_size = rc->array_size; 153 params.last_level = rc->last_level; 154 params.nr_samples = rc->nr_samples; 155 params.flags = rc->flags; 156 } else { 157 if (rc->depth > 1) 158 return -EINVAL; 159 if (rc->nr_samples > 1) 160 return -EINVAL; 161 if (rc->last_level > 1) 162 return -EINVAL; 163 if (rc->target != 2) 164 return -EINVAL; 165 if (rc->array_size > 1) 166 return -EINVAL; 167 } 168 169 params.format = rc->format; 170 params.width = rc->width; 171 params.height = rc->height; 172 params.size = rc->size; 173 /* allocate a single page size object */ 174 if (params.size == 0) 175 params.size = PAGE_SIZE; 176 177 fence = virtio_gpu_fence_alloc(vgdev, vgdev->fence_drv.context, 0); 178 if (!fence) 179 return -ENOMEM; 180 ret = virtio_gpu_object_create(vgdev, ¶ms, &qobj, fence); 181 dma_fence_put(&fence->f); 182 if (ret < 0) 183 return ret; 184 obj = &qobj->base.base; 185 186 ret = drm_gem_handle_create(file, obj, &handle); 187 if (ret) { 188 drm_gem_object_release(obj); 189 return ret; 190 } 191 192 rc->res_handle = qobj->hw_res_handle; /* similiar to a VM address */ 193 rc->bo_handle = handle; 194 195 /* 196 * The handle owns the reference now. But we must drop our 197 * remaining reference *after* we no longer need to dereference 198 * the obj. Otherwise userspace could guess the handle and 199 * race closing it from another thread. 200 */ 201 drm_gem_object_put(obj); 202 203 return 0; 204 } 205 206 static int virtio_gpu_resource_info_ioctl(struct drm_device *dev, void *data, 207 struct drm_file *file) 208 { 209 struct drm_virtgpu_resource_info *ri = data; 210 struct drm_gem_object *gobj = NULL; 211 struct virtio_gpu_object *qobj = NULL; 212 213 gobj = drm_gem_object_lookup(file, ri->bo_handle); 214 if (gobj == NULL) 215 return -ENOENT; 216 217 qobj = gem_to_virtio_gpu_obj(gobj); 218 219 ri->size = qobj->base.base.size; 220 ri->res_handle = qobj->hw_res_handle; 221 if (qobj->host3d_blob || qobj->guest_blob) 222 ri->blob_mem = qobj->blob_mem; 223 224 drm_gem_object_put(gobj); 225 return 0; 226 } 227 228 static int virtio_gpu_transfer_from_host_ioctl(struct drm_device *dev, 229 void *data, 230 struct drm_file *file) 231 { 232 struct virtio_gpu_device *vgdev = dev->dev_private; 233 struct virtio_gpu_fpriv *vfpriv = file->driver_priv; 234 struct drm_virtgpu_3d_transfer_from_host *args = data; 235 struct virtio_gpu_object *bo; 236 struct virtio_gpu_object_array *objs; 237 struct virtio_gpu_fence *fence; 238 int ret; 239 u32 offset = args->offset; 240 241 if (vgdev->has_virgl_3d == false) 242 return -ENOSYS; 243 244 virtio_gpu_create_context(dev, file); 245 objs = virtio_gpu_array_from_handles(file, &args->bo_handle, 1); 246 if (objs == NULL) 247 return -ENOENT; 248 249 bo = gem_to_virtio_gpu_obj(objs->objs[0]); 250 if (bo->guest_blob && !bo->host3d_blob) { 251 ret = -EINVAL; 252 goto err_put_free; 253 } 254 255 if (!bo->host3d_blob && (args->stride || args->layer_stride)) { 256 ret = -EINVAL; 257 goto err_put_free; 258 } 259 260 ret = virtio_gpu_array_lock_resv(objs); 261 if (ret != 0) 262 goto err_put_free; 263 264 fence = virtio_gpu_fence_alloc(vgdev, vgdev->fence_drv.context, 0); 265 if (!fence) { 266 ret = -ENOMEM; 267 goto err_unlock; 268 } 269 270 virtio_gpu_cmd_transfer_from_host_3d 271 (vgdev, vfpriv->ctx_id, offset, args->level, args->stride, 272 args->layer_stride, &args->box, objs, fence); 273 dma_fence_put(&fence->f); 274 virtio_gpu_notify(vgdev); 275 return 0; 276 277 err_unlock: 278 virtio_gpu_array_unlock_resv(objs); 279 err_put_free: 280 virtio_gpu_array_put_free(objs); 281 return ret; 282 } 283 284 static int virtio_gpu_transfer_to_host_ioctl(struct drm_device *dev, void *data, 285 struct drm_file *file) 286 { 287 struct virtio_gpu_device *vgdev = dev->dev_private; 288 struct virtio_gpu_fpriv *vfpriv = file->driver_priv; 289 struct drm_virtgpu_3d_transfer_to_host *args = data; 290 struct virtio_gpu_object *bo; 291 struct virtio_gpu_object_array *objs; 292 struct virtio_gpu_fence *fence; 293 int ret; 294 u32 offset = args->offset; 295 296 objs = virtio_gpu_array_from_handles(file, &args->bo_handle, 1); 297 if (objs == NULL) 298 return -ENOENT; 299 300 bo = gem_to_virtio_gpu_obj(objs->objs[0]); 301 if (bo->guest_blob && !bo->host3d_blob) { 302 ret = -EINVAL; 303 goto err_put_free; 304 } 305 306 if (!vgdev->has_virgl_3d) { 307 virtio_gpu_cmd_transfer_to_host_2d 308 (vgdev, offset, 309 args->box.w, args->box.h, args->box.x, args->box.y, 310 objs, NULL); 311 } else { 312 virtio_gpu_create_context(dev, file); 313 314 if (!bo->host3d_blob && (args->stride || args->layer_stride)) { 315 ret = -EINVAL; 316 goto err_put_free; 317 } 318 319 ret = virtio_gpu_array_lock_resv(objs); 320 if (ret != 0) 321 goto err_put_free; 322 323 ret = -ENOMEM; 324 fence = virtio_gpu_fence_alloc(vgdev, vgdev->fence_drv.context, 325 0); 326 if (!fence) 327 goto err_unlock; 328 329 virtio_gpu_cmd_transfer_to_host_3d 330 (vgdev, 331 vfpriv ? vfpriv->ctx_id : 0, offset, args->level, 332 args->stride, args->layer_stride, &args->box, objs, 333 fence); 334 dma_fence_put(&fence->f); 335 } 336 virtio_gpu_notify(vgdev); 337 return 0; 338 339 err_unlock: 340 virtio_gpu_array_unlock_resv(objs); 341 err_put_free: 342 virtio_gpu_array_put_free(objs); 343 return ret; 344 } 345 346 static int virtio_gpu_wait_ioctl(struct drm_device *dev, void *data, 347 struct drm_file *file) 348 { 349 struct drm_virtgpu_3d_wait *args = data; 350 struct drm_gem_object *obj; 351 long timeout = 15 * HZ; 352 int ret; 353 354 obj = drm_gem_object_lookup(file, args->handle); 355 if (obj == NULL) 356 return -ENOENT; 357 358 if (args->flags & VIRTGPU_WAIT_NOWAIT) { 359 ret = dma_resv_test_signaled(obj->resv, DMA_RESV_USAGE_READ); 360 } else { 361 ret = dma_resv_wait_timeout(obj->resv, DMA_RESV_USAGE_READ, 362 true, timeout); 363 } 364 if (ret == 0) 365 ret = -EBUSY; 366 else if (ret > 0) 367 ret = 0; 368 369 drm_gem_object_put(obj); 370 return ret; 371 } 372 373 static int virtio_gpu_get_caps_ioctl(struct drm_device *dev, 374 void *data, struct drm_file *file) 375 { 376 struct virtio_gpu_device *vgdev = dev->dev_private; 377 struct drm_virtgpu_get_caps *args = data; 378 unsigned size, host_caps_size; 379 int i; 380 int found_valid = -1; 381 int ret; 382 struct virtio_gpu_drv_cap_cache *cache_ent; 383 void *ptr; 384 385 if (vgdev->num_capsets == 0) 386 return -ENOSYS; 387 388 /* don't allow userspace to pass 0 */ 389 if (args->size == 0) 390 return -EINVAL; 391 392 spin_lock(&vgdev->display_info_lock); 393 for (i = 0; i < vgdev->num_capsets; i++) { 394 if (vgdev->capsets[i].id == args->cap_set_id) { 395 if (vgdev->capsets[i].max_version >= args->cap_set_ver) { 396 found_valid = i; 397 break; 398 } 399 } 400 } 401 402 if (found_valid == -1) { 403 spin_unlock(&vgdev->display_info_lock); 404 return -EINVAL; 405 } 406 407 host_caps_size = vgdev->capsets[found_valid].max_size; 408 /* only copy to user the minimum of the host caps size or the guest caps size */ 409 size = min(args->size, host_caps_size); 410 411 list_for_each_entry(cache_ent, &vgdev->cap_cache, head) { 412 if (cache_ent->id == args->cap_set_id && 413 cache_ent->version == args->cap_set_ver) { 414 spin_unlock(&vgdev->display_info_lock); 415 goto copy_exit; 416 } 417 } 418 spin_unlock(&vgdev->display_info_lock); 419 420 /* not in cache - need to talk to hw */ 421 ret = virtio_gpu_cmd_get_capset(vgdev, found_valid, args->cap_set_ver, 422 &cache_ent); 423 if (ret) 424 return ret; 425 virtio_gpu_notify(vgdev); 426 427 copy_exit: 428 ret = wait_event_timeout(vgdev->resp_wq, 429 atomic_read(&cache_ent->is_valid), 5 * HZ); 430 if (!ret) 431 return -EBUSY; 432 433 /* is_valid check must proceed before copy of the cache entry. */ 434 smp_rmb(); 435 436 ptr = cache_ent->caps_cache; 437 438 if (copy_to_user(u64_to_user_ptr(args->addr), ptr, size)) 439 return -EFAULT; 440 441 return 0; 442 } 443 444 static int verify_blob(struct virtio_gpu_device *vgdev, 445 struct virtio_gpu_fpriv *vfpriv, 446 struct virtio_gpu_object_params *params, 447 struct drm_virtgpu_resource_create_blob *rc_blob, 448 bool *guest_blob, bool *host3d_blob) 449 { 450 if (!vgdev->has_resource_blob) 451 return -EINVAL; 452 453 if (rc_blob->blob_flags & ~VIRTGPU_BLOB_FLAG_USE_MASK) 454 return -EINVAL; 455 456 if (rc_blob->blob_flags & VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE) { 457 if (!vgdev->has_resource_assign_uuid) 458 return -EINVAL; 459 } 460 461 switch (rc_blob->blob_mem) { 462 case VIRTGPU_BLOB_MEM_GUEST: 463 *guest_blob = true; 464 break; 465 case VIRTGPU_BLOB_MEM_HOST3D_GUEST: 466 *guest_blob = true; 467 fallthrough; 468 case VIRTGPU_BLOB_MEM_HOST3D: 469 *host3d_blob = true; 470 break; 471 default: 472 return -EINVAL; 473 } 474 475 if (*host3d_blob) { 476 if (!vgdev->has_virgl_3d) 477 return -EINVAL; 478 479 /* Must be dword aligned. */ 480 if (rc_blob->cmd_size % 4 != 0) 481 return -EINVAL; 482 483 params->ctx_id = vfpriv->ctx_id; 484 params->blob_id = rc_blob->blob_id; 485 } else { 486 if (rc_blob->blob_id != 0) 487 return -EINVAL; 488 489 if (rc_blob->cmd_size != 0) 490 return -EINVAL; 491 } 492 493 params->blob_mem = rc_blob->blob_mem; 494 params->size = rc_blob->size; 495 params->blob = true; 496 params->blob_flags = rc_blob->blob_flags; 497 params->blob_hints = rc_blob->blob_hints; 498 499 if (vgdev->has_blob_alignment && 500 !IS_ALIGNED(params->size, vgdev->blob_alignment)) 501 return -EINVAL; 502 503 return 0; 504 } 505 506 static int virtio_gpu_resource_create_blob_ioctl(struct drm_device *dev, 507 void *data, 508 struct drm_file *file) 509 { 510 int ret = 0; 511 uint32_t handle = 0; 512 bool guest_blob = false; 513 bool host3d_blob = false; 514 struct drm_gem_object *obj; 515 struct virtio_gpu_object *bo; 516 struct virtio_gpu_object_params params = { 0 }; 517 struct virtio_gpu_device *vgdev = dev->dev_private; 518 struct virtio_gpu_fpriv *vfpriv = file->driver_priv; 519 struct drm_virtgpu_resource_create_blob *rc_blob = data; 520 521 if (verify_blob(vgdev, vfpriv, ¶ms, rc_blob, 522 &guest_blob, &host3d_blob)) 523 return -EINVAL; 524 525 if (vgdev->has_virgl_3d) 526 virtio_gpu_create_context(dev, file); 527 528 if (rc_blob->cmd_size) { 529 void *buf; 530 531 buf = memdup_user(u64_to_user_ptr(rc_blob->cmd), 532 rc_blob->cmd_size); 533 534 if (IS_ERR(buf)) 535 return PTR_ERR(buf); 536 537 virtio_gpu_cmd_submit(vgdev, buf, rc_blob->cmd_size, 538 vfpriv->ctx_id, NULL, NULL); 539 } 540 541 if (guest_blob) 542 ret = virtio_gpu_object_create(vgdev, ¶ms, &bo, NULL); 543 else if (!guest_blob && host3d_blob) 544 ret = virtio_gpu_vram_create(vgdev, ¶ms, &bo); 545 else 546 return -EINVAL; 547 548 if (ret < 0) 549 return ret; 550 551 bo->guest_blob = guest_blob; 552 bo->host3d_blob = host3d_blob; 553 bo->blob_mem = rc_blob->blob_mem; 554 bo->blob_flags = rc_blob->blob_flags; 555 556 obj = &bo->base.base; 557 if (params.blob_flags & VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE) { 558 ret = virtio_gpu_resource_assign_uuid(vgdev, bo); 559 if (ret) { 560 drm_gem_object_release(obj); 561 return ret; 562 } 563 } 564 565 ret = drm_gem_handle_create(file, obj, &handle); 566 if (ret) { 567 drm_gem_object_release(obj); 568 return ret; 569 } 570 571 rc_blob->res_handle = bo->hw_res_handle; 572 rc_blob->bo_handle = handle; 573 574 /* 575 * The handle owns the reference now. But we must drop our 576 * remaining reference *after* we no longer need to dereference 577 * the obj. Otherwise userspace could guess the handle and 578 * race closing it from another thread. 579 */ 580 drm_gem_object_put(obj); 581 582 return 0; 583 } 584 585 static int virtio_gpu_context_init_ioctl(struct drm_device *dev, 586 void *data, struct drm_file *file) 587 { 588 int ret = 0; 589 uint32_t num_params, i; 590 uint64_t valid_ring_mask, param, value; 591 size_t len; 592 struct drm_virtgpu_context_set_param *ctx_set_params = NULL; 593 struct virtio_gpu_device *vgdev = dev->dev_private; 594 struct virtio_gpu_fpriv *vfpriv = file->driver_priv; 595 struct drm_virtgpu_context_init *args = data; 596 597 num_params = args->num_params; 598 len = num_params * sizeof(struct drm_virtgpu_context_set_param); 599 600 if (!vgdev->has_context_init || !vgdev->has_virgl_3d) 601 return -EINVAL; 602 603 /* Number of unique parameters supported at this time. */ 604 if (num_params > 4) 605 return -EINVAL; 606 607 ctx_set_params = memdup_user(u64_to_user_ptr(args->ctx_set_params), 608 len); 609 610 if (IS_ERR(ctx_set_params)) 611 return PTR_ERR(ctx_set_params); 612 613 mutex_lock(&vfpriv->context_lock); 614 if (vfpriv->context_created) { 615 ret = -EEXIST; 616 goto out_unlock; 617 } 618 619 for (i = 0; i < num_params; i++) { 620 param = ctx_set_params[i].param; 621 value = ctx_set_params[i].value; 622 623 switch (param) { 624 case VIRTGPU_CONTEXT_PARAM_CAPSET_ID: 625 if (value > MAX_CAPSET_ID) { 626 ret = -EINVAL; 627 goto out_unlock; 628 } 629 630 if ((vgdev->capset_id_mask & (1ULL << value)) == 0) { 631 ret = -EINVAL; 632 goto out_unlock; 633 } 634 635 /* Context capset ID already set */ 636 if (vfpriv->context_init & 637 VIRTIO_GPU_CONTEXT_INIT_CAPSET_ID_MASK) { 638 ret = -EINVAL; 639 goto out_unlock; 640 } 641 642 vfpriv->context_init |= value; 643 break; 644 case VIRTGPU_CONTEXT_PARAM_NUM_RINGS: 645 if (vfpriv->base_fence_ctx) { 646 ret = -EINVAL; 647 goto out_unlock; 648 } 649 650 if (value > MAX_RINGS) { 651 ret = -EINVAL; 652 goto out_unlock; 653 } 654 655 vfpriv->base_fence_ctx = dma_fence_context_alloc(value); 656 vfpriv->num_rings = value; 657 break; 658 case VIRTGPU_CONTEXT_PARAM_POLL_RINGS_MASK: 659 if (vfpriv->ring_idx_mask) { 660 ret = -EINVAL; 661 goto out_unlock; 662 } 663 664 vfpriv->ring_idx_mask = value; 665 break; 666 case VIRTGPU_CONTEXT_PARAM_DEBUG_NAME: 667 if (vfpriv->explicit_debug_name) { 668 ret = -EINVAL; 669 goto out_unlock; 670 } 671 672 ret = strncpy_from_user(vfpriv->debug_name, 673 u64_to_user_ptr(value), 674 DEBUG_NAME_MAX_LEN - 1); 675 if (ret < 0) 676 goto out_unlock; 677 678 vfpriv->explicit_debug_name = true; 679 ret = 0; 680 break; 681 default: 682 ret = -EINVAL; 683 goto out_unlock; 684 } 685 } 686 687 if (vfpriv->ring_idx_mask) { 688 valid_ring_mask = 0; 689 for (i = 0; i < vfpriv->num_rings; i++) 690 valid_ring_mask |= 1ULL << i; 691 692 if (~valid_ring_mask & vfpriv->ring_idx_mask) { 693 ret = -EINVAL; 694 goto out_unlock; 695 } 696 } 697 698 virtio_gpu_create_context_locked(vgdev, vfpriv); 699 virtio_gpu_notify(vgdev); 700 701 out_unlock: 702 mutex_unlock(&vfpriv->context_lock); 703 kfree(ctx_set_params); 704 return ret; 705 } 706 707 struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS] = { 708 DRM_IOCTL_DEF_DRV(VIRTGPU_MAP, virtio_gpu_map_ioctl, 709 DRM_RENDER_ALLOW), 710 711 DRM_IOCTL_DEF_DRV(VIRTGPU_EXECBUFFER, virtio_gpu_execbuffer_ioctl, 712 DRM_RENDER_ALLOW), 713 714 DRM_IOCTL_DEF_DRV(VIRTGPU_GETPARAM, virtio_gpu_getparam_ioctl, 715 DRM_RENDER_ALLOW), 716 717 DRM_IOCTL_DEF_DRV(VIRTGPU_RESOURCE_CREATE, 718 virtio_gpu_resource_create_ioctl, 719 DRM_RENDER_ALLOW), 720 721 DRM_IOCTL_DEF_DRV(VIRTGPU_RESOURCE_INFO, virtio_gpu_resource_info_ioctl, 722 DRM_RENDER_ALLOW), 723 724 /* make transfer async to the main ring? - no sure, can we 725 * thread these in the underlying GL 726 */ 727 DRM_IOCTL_DEF_DRV(VIRTGPU_TRANSFER_FROM_HOST, 728 virtio_gpu_transfer_from_host_ioctl, 729 DRM_RENDER_ALLOW), 730 DRM_IOCTL_DEF_DRV(VIRTGPU_TRANSFER_TO_HOST, 731 virtio_gpu_transfer_to_host_ioctl, 732 DRM_RENDER_ALLOW), 733 734 DRM_IOCTL_DEF_DRV(VIRTGPU_WAIT, virtio_gpu_wait_ioctl, 735 DRM_RENDER_ALLOW), 736 737 DRM_IOCTL_DEF_DRV(VIRTGPU_GET_CAPS, virtio_gpu_get_caps_ioctl, 738 DRM_RENDER_ALLOW), 739 740 DRM_IOCTL_DEF_DRV(VIRTGPU_RESOURCE_CREATE_BLOB, 741 virtio_gpu_resource_create_blob_ioctl, 742 DRM_RENDER_ALLOW), 743 744 DRM_IOCTL_DEF_DRV(VIRTGPU_CONTEXT_INIT, virtio_gpu_context_init_ioctl, 745 DRM_RENDER_ALLOW), 746 }; 747