1 // SPDX-License-Identifier: GPL-2.0-only 2 /* Copyright (c) 2020 NVIDIA Corporation */ 3 4 #include <linux/dma-fence-array.h> 5 #include <linux/dma-mapping.h> 6 #include <linux/file.h> 7 #include <linux/host1x.h> 8 #include <linux/iommu.h> 9 #include <linux/kref.h> 10 #include <linux/list.h> 11 #include <linux/nospec.h> 12 #include <linux/pm_runtime.h> 13 #include <linux/scatterlist.h> 14 #include <linux/slab.h> 15 #include <linux/sync_file.h> 16 17 #include <drm/drm_drv.h> 18 #include <drm/drm_file.h> 19 #include <drm/drm_syncobj.h> 20 21 #include "drm.h" 22 #include "gem.h" 23 #include "submit.h" 24 #include "uapi.h" 25 26 #define SUBMIT_ERR(context, fmt, ...) \ 27 dev_err_ratelimited(context->client->base.dev, \ 28 "%s: job submission failed: " fmt "\n", \ 29 current->comm, ##__VA_ARGS__) 30 31 struct gather_bo { 32 struct host1x_bo base; 33 34 struct kref ref; 35 36 struct device *dev; 37 u32 *gather_data; 38 dma_addr_t gather_data_dma; 39 size_t gather_data_words; 40 }; 41 42 static struct host1x_bo *gather_bo_get(struct host1x_bo *host_bo) 43 { 44 struct gather_bo *bo = container_of(host_bo, struct gather_bo, base); 45 46 kref_get(&bo->ref); 47 48 return host_bo; 49 } 50 51 static void gather_bo_release(struct kref *ref) 52 { 53 struct gather_bo *bo = container_of(ref, struct gather_bo, ref); 54 55 dma_free_attrs(bo->dev, bo->gather_data_words * 4, bo->gather_data, bo->gather_data_dma, 56 0); 57 kfree(bo); 58 } 59 60 static void gather_bo_put(struct host1x_bo *host_bo) 61 { 62 struct gather_bo *bo = container_of(host_bo, struct gather_bo, base); 63 64 kref_put(&bo->ref, gather_bo_release); 65 } 66 67 static struct host1x_bo_mapping * 68 gather_bo_pin(struct device *dev, struct host1x_bo *bo, enum dma_data_direction direction) 69 { 70 struct gather_bo *gather = container_of(bo, struct gather_bo, base); 71 struct host1x_bo_mapping *map; 72 int err; 73 74 map = kzalloc(sizeof(*map), GFP_KERNEL); 75 if (!map) 76 return ERR_PTR(-ENOMEM); 77 78 kref_init(&map->ref); 79 map->bo = host1x_bo_get(bo); 80 map->direction = direction; 81 map->dev = dev; 82 83 map->sgt = kzalloc(sizeof(*map->sgt), GFP_KERNEL); 84 if (!map->sgt) { 85 err = -ENOMEM; 86 goto free; 87 } 88 89 err = dma_get_sgtable(gather->dev, map->sgt, gather->gather_data, gather->gather_data_dma, 90 gather->gather_data_words * 4); 91 if (err) 92 goto free_sgt; 93 94 err = dma_map_sgtable(dev, map->sgt, direction, 0); 95 if (err) 96 goto free_sgt; 97 98 map->phys = sg_dma_address(map->sgt->sgl); 99 map->size = gather->gather_data_words * 4; 100 map->chunks = err; 101 102 return map; 103 104 free_sgt: 105 sg_free_table(map->sgt); 106 kfree(map->sgt); 107 free: 108 kfree(map); 109 return ERR_PTR(err); 110 } 111 112 static void gather_bo_unpin(struct host1x_bo_mapping *map) 113 { 114 if (!map) 115 return; 116 117 dma_unmap_sgtable(map->dev, map->sgt, map->direction, 0); 118 sg_free_table(map->sgt); 119 kfree(map->sgt); 120 host1x_bo_put(map->bo); 121 122 kfree(map); 123 } 124 125 static void *gather_bo_mmap(struct host1x_bo *host_bo) 126 { 127 struct gather_bo *bo = container_of(host_bo, struct gather_bo, base); 128 129 return bo->gather_data; 130 } 131 132 static void gather_bo_munmap(struct host1x_bo *host_bo, void *addr) 133 { 134 } 135 136 static const struct host1x_bo_ops gather_bo_ops = { 137 .get = gather_bo_get, 138 .put = gather_bo_put, 139 .pin = gather_bo_pin, 140 .unpin = gather_bo_unpin, 141 .mmap = gather_bo_mmap, 142 .munmap = gather_bo_munmap, 143 }; 144 145 static struct tegra_drm_mapping * 146 tegra_drm_mapping_get(struct tegra_drm_context *context, u32 id) 147 { 148 struct tegra_drm_mapping *mapping; 149 150 xa_lock(&context->mappings); 151 152 mapping = xa_load(&context->mappings, id); 153 if (mapping) 154 kref_get(&mapping->ref); 155 156 xa_unlock(&context->mappings); 157 158 return mapping; 159 } 160 161 static void *alloc_copy_user_array(void __user *from, size_t count, size_t size) 162 { 163 size_t copy_len; 164 void *data; 165 166 if (check_mul_overflow(count, size, ©_len)) 167 return ERR_PTR(-EINVAL); 168 169 if (copy_len > 0x4000) 170 return ERR_PTR(-E2BIG); 171 172 data = vmemdup_user(from, copy_len); 173 if (IS_ERR(data)) 174 return ERR_CAST(data); 175 176 return data; 177 } 178 179 static int submit_copy_gather_data(struct gather_bo **pbo, struct device *dev, 180 struct tegra_drm_context *context, 181 struct drm_tegra_channel_submit *args) 182 { 183 struct gather_bo *bo; 184 size_t copy_len; 185 186 if (args->gather_data_words == 0) { 187 SUBMIT_ERR(context, "gather_data_words cannot be zero"); 188 return -EINVAL; 189 } 190 191 if (check_mul_overflow((size_t)args->gather_data_words, (size_t)4, ©_len)) { 192 SUBMIT_ERR(context, "gather_data_words is too large"); 193 return -EINVAL; 194 } 195 196 bo = kzalloc(sizeof(*bo), GFP_KERNEL); 197 if (!bo) { 198 SUBMIT_ERR(context, "failed to allocate memory for bo info"); 199 return -ENOMEM; 200 } 201 202 host1x_bo_init(&bo->base, &gather_bo_ops); 203 kref_init(&bo->ref); 204 bo->dev = dev; 205 206 bo->gather_data = dma_alloc_attrs(dev, copy_len, &bo->gather_data_dma, 207 GFP_KERNEL | __GFP_NOWARN, 0); 208 if (!bo->gather_data) { 209 SUBMIT_ERR(context, "failed to allocate memory for gather data"); 210 kfree(bo); 211 return -ENOMEM; 212 } 213 214 if (copy_from_user(bo->gather_data, u64_to_user_ptr(args->gather_data_ptr), copy_len)) { 215 SUBMIT_ERR(context, "failed to copy gather data from userspace"); 216 dma_free_attrs(dev, copy_len, bo->gather_data, bo->gather_data_dma, 0); 217 kfree(bo); 218 return -EFAULT; 219 } 220 221 bo->gather_data_words = args->gather_data_words; 222 223 *pbo = bo; 224 225 return 0; 226 } 227 228 static int submit_write_reloc(struct tegra_drm_context *context, struct gather_bo *bo, 229 struct drm_tegra_submit_buf *buf, struct tegra_drm_mapping *mapping) 230 { 231 /* TODO check that target_offset is within bounds */ 232 dma_addr_t iova = mapping->iova + buf->reloc.target_offset; 233 u32 written_ptr; 234 235 #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT 236 if (buf->flags & DRM_TEGRA_SUBMIT_RELOC_SECTOR_LAYOUT) 237 iova |= BIT_ULL(39); 238 #endif 239 240 written_ptr = iova >> buf->reloc.shift; 241 242 if (buf->reloc.gather_offset_words >= bo->gather_data_words) { 243 SUBMIT_ERR(context, 244 "relocation has too large gather offset (%u vs gather length %zu)", 245 buf->reloc.gather_offset_words, bo->gather_data_words); 246 return -EINVAL; 247 } 248 249 buf->reloc.gather_offset_words = array_index_nospec(buf->reloc.gather_offset_words, 250 bo->gather_data_words); 251 252 bo->gather_data[buf->reloc.gather_offset_words] = written_ptr; 253 254 return 0; 255 } 256 257 static int submit_process_bufs(struct tegra_drm_context *context, struct gather_bo *bo, 258 struct drm_tegra_channel_submit *args, 259 struct tegra_drm_submit_data *job_data) 260 { 261 struct tegra_drm_used_mapping *mappings; 262 struct drm_tegra_submit_buf *bufs; 263 int err; 264 u32 i; 265 266 bufs = alloc_copy_user_array(u64_to_user_ptr(args->bufs_ptr), args->num_bufs, 267 sizeof(*bufs)); 268 if (IS_ERR(bufs)) { 269 SUBMIT_ERR(context, "failed to copy bufs array from userspace"); 270 return PTR_ERR(bufs); 271 } 272 273 mappings = kcalloc(args->num_bufs, sizeof(*mappings), GFP_KERNEL); 274 if (!mappings) { 275 SUBMIT_ERR(context, "failed to allocate memory for mapping info"); 276 err = -ENOMEM; 277 goto done; 278 } 279 280 for (i = 0; i < args->num_bufs; i++) { 281 struct drm_tegra_submit_buf *buf = &bufs[i]; 282 struct tegra_drm_mapping *mapping; 283 284 if (buf->flags & ~DRM_TEGRA_SUBMIT_RELOC_SECTOR_LAYOUT) { 285 SUBMIT_ERR(context, "invalid flag specified for buffer"); 286 err = -EINVAL; 287 goto drop_refs; 288 } 289 290 mapping = tegra_drm_mapping_get(context, buf->mapping); 291 if (!mapping) { 292 SUBMIT_ERR(context, "invalid mapping ID '%u' for buffer", buf->mapping); 293 err = -EINVAL; 294 goto drop_refs; 295 } 296 297 err = submit_write_reloc(context, bo, buf, mapping); 298 if (err) { 299 tegra_drm_mapping_put(mapping); 300 goto drop_refs; 301 } 302 303 mappings[i].mapping = mapping; 304 mappings[i].flags = buf->flags; 305 } 306 307 job_data->used_mappings = mappings; 308 job_data->num_used_mappings = i; 309 310 err = 0; 311 312 goto done; 313 314 drop_refs: 315 while (i--) 316 tegra_drm_mapping_put(mappings[i].mapping); 317 318 kfree(mappings); 319 job_data->used_mappings = NULL; 320 321 done: 322 kvfree(bufs); 323 324 return err; 325 } 326 327 static int submit_get_syncpt(struct tegra_drm_context *context, struct host1x_job *job, 328 struct xarray *syncpoints, struct drm_tegra_channel_submit *args) 329 { 330 struct host1x_syncpt *sp; 331 332 if (args->syncpt.flags) { 333 SUBMIT_ERR(context, "invalid flag specified for syncpt"); 334 return -EINVAL; 335 } 336 337 /* Syncpt ref will be dropped on job release */ 338 sp = xa_load(syncpoints, args->syncpt.id); 339 if (!sp) { 340 SUBMIT_ERR(context, "syncpoint specified in syncpt was not allocated"); 341 return -EINVAL; 342 } 343 344 job->syncpt = host1x_syncpt_get(sp); 345 job->syncpt_incrs = args->syncpt.increments; 346 347 return 0; 348 } 349 350 static int submit_job_add_gather(struct host1x_job *job, struct tegra_drm_context *context, 351 struct drm_tegra_submit_cmd_gather_uptr *cmd, 352 struct gather_bo *bo, u32 *offset, 353 struct tegra_drm_submit_data *job_data, 354 u32 *class) 355 { 356 u32 next_offset; 357 358 if (cmd->reserved[0] || cmd->reserved[1] || cmd->reserved[2]) { 359 SUBMIT_ERR(context, "non-zero reserved field in GATHER_UPTR command"); 360 return -EINVAL; 361 } 362 363 /* Check for maximum gather size */ 364 if (cmd->words > 16383) { 365 SUBMIT_ERR(context, "too many words in GATHER_UPTR command"); 366 return -EINVAL; 367 } 368 369 if (check_add_overflow(*offset, cmd->words, &next_offset)) { 370 SUBMIT_ERR(context, "too many total words in job"); 371 return -EINVAL; 372 } 373 374 if (next_offset > bo->gather_data_words) { 375 SUBMIT_ERR(context, "GATHER_UPTR command overflows gather data"); 376 return -EINVAL; 377 } 378 379 if (tegra_drm_fw_validate(context->client, bo->gather_data, *offset, 380 cmd->words, job_data, class)) { 381 SUBMIT_ERR(context, "job was rejected by firewall"); 382 return -EINVAL; 383 } 384 385 host1x_job_add_gather(job, &bo->base, cmd->words, *offset * 4); 386 387 *offset = next_offset; 388 389 return 0; 390 } 391 392 static struct host1x_job * 393 submit_create_job(struct tegra_drm_context *context, struct gather_bo *bo, 394 struct drm_tegra_channel_submit *args, struct tegra_drm_submit_data *job_data, 395 struct xarray *syncpoints) 396 { 397 struct drm_tegra_submit_cmd *cmds; 398 u32 i, gather_offset = 0, class; 399 struct host1x_job *job; 400 int err; 401 402 /* Set initial class for firewall. */ 403 class = context->client->base.class; 404 405 cmds = alloc_copy_user_array(u64_to_user_ptr(args->cmds_ptr), args->num_cmds, 406 sizeof(*cmds)); 407 if (IS_ERR(cmds)) { 408 SUBMIT_ERR(context, "failed to copy cmds array from userspace"); 409 return ERR_CAST(cmds); 410 } 411 412 job = host1x_job_alloc(context->channel, args->num_cmds, 0, true); 413 if (!job) { 414 SUBMIT_ERR(context, "failed to allocate memory for job"); 415 job = ERR_PTR(-ENOMEM); 416 goto done; 417 } 418 419 err = submit_get_syncpt(context, job, syncpoints, args); 420 if (err < 0) 421 goto free_job; 422 423 job->client = &context->client->base; 424 job->class = context->client->base.class; 425 job->serialize = true; 426 427 for (i = 0; i < args->num_cmds; i++) { 428 struct drm_tegra_submit_cmd *cmd = &cmds[i]; 429 430 if (cmd->flags) { 431 SUBMIT_ERR(context, "unknown flags given for cmd"); 432 err = -EINVAL; 433 goto free_job; 434 } 435 436 if (cmd->type == DRM_TEGRA_SUBMIT_CMD_GATHER_UPTR) { 437 err = submit_job_add_gather(job, context, &cmd->gather_uptr, bo, 438 &gather_offset, job_data, &class); 439 if (err) 440 goto free_job; 441 } else if (cmd->type == DRM_TEGRA_SUBMIT_CMD_WAIT_SYNCPT) { 442 if (cmd->wait_syncpt.reserved[0] || cmd->wait_syncpt.reserved[1]) { 443 SUBMIT_ERR(context, "non-zero reserved value"); 444 err = -EINVAL; 445 goto free_job; 446 } 447 448 host1x_job_add_wait(job, cmd->wait_syncpt.id, cmd->wait_syncpt.value, 449 false, class); 450 } else if (cmd->type == DRM_TEGRA_SUBMIT_CMD_WAIT_SYNCPT_RELATIVE) { 451 if (cmd->wait_syncpt.reserved[0] || cmd->wait_syncpt.reserved[1]) { 452 SUBMIT_ERR(context, "non-zero reserved value"); 453 err = -EINVAL; 454 goto free_job; 455 } 456 457 if (cmd->wait_syncpt.id != args->syncpt.id) { 458 SUBMIT_ERR(context, "syncpoint ID in CMD_WAIT_SYNCPT_RELATIVE is not used by the job"); 459 err = -EINVAL; 460 goto free_job; 461 } 462 463 host1x_job_add_wait(job, cmd->wait_syncpt.id, cmd->wait_syncpt.value, 464 true, class); 465 } else { 466 SUBMIT_ERR(context, "unknown cmd type"); 467 err = -EINVAL; 468 goto free_job; 469 } 470 } 471 472 if (gather_offset == 0) { 473 SUBMIT_ERR(context, "job must have at least one gather"); 474 err = -EINVAL; 475 goto free_job; 476 } 477 478 goto done; 479 480 free_job: 481 host1x_job_put(job); 482 job = ERR_PTR(err); 483 484 done: 485 kvfree(cmds); 486 487 return job; 488 } 489 490 static void release_job(struct host1x_job *job) 491 { 492 struct tegra_drm_client *client = container_of(job->client, struct tegra_drm_client, base); 493 struct tegra_drm_submit_data *job_data = job->user_data; 494 u32 i; 495 496 if (job->memory_context) 497 host1x_memory_context_put(job->memory_context); 498 499 for (i = 0; i < job_data->num_used_mappings; i++) 500 tegra_drm_mapping_put(job_data->used_mappings[i].mapping); 501 502 kfree(job_data->used_mappings); 503 kfree(job_data); 504 505 pm_runtime_mark_last_busy(client->base.dev); 506 pm_runtime_put_autosuspend(client->base.dev); 507 } 508 509 int tegra_drm_ioctl_channel_submit(struct drm_device *drm, void *data, 510 struct drm_file *file) 511 { 512 struct tegra_drm_file *fpriv = file->driver_priv; 513 struct drm_tegra_channel_submit *args = data; 514 struct tegra_drm_submit_data *job_data; 515 struct drm_syncobj *syncobj = NULL; 516 struct tegra_drm_context *context; 517 struct host1x_job *job; 518 struct gather_bo *bo; 519 u32 i; 520 int err; 521 522 mutex_lock(&fpriv->lock); 523 524 context = xa_load(&fpriv->contexts, args->context); 525 if (!context) { 526 mutex_unlock(&fpriv->lock); 527 pr_err_ratelimited("%s: %s: invalid channel context '%#x'", __func__, 528 current->comm, args->context); 529 return -EINVAL; 530 } 531 532 if (args->syncobj_in) { 533 struct dma_fence *fence; 534 535 err = drm_syncobj_find_fence(file, args->syncobj_in, 0, 0, &fence); 536 if (err) { 537 SUBMIT_ERR(context, "invalid syncobj_in '%#x'", args->syncobj_in); 538 goto unlock; 539 } 540 541 err = dma_fence_wait_timeout(fence, true, msecs_to_jiffies(10000)); 542 dma_fence_put(fence); 543 if (err) { 544 SUBMIT_ERR(context, "wait for syncobj_in timed out"); 545 goto unlock; 546 } 547 } 548 549 if (args->syncobj_out) { 550 syncobj = drm_syncobj_find(file, args->syncobj_out); 551 if (!syncobj) { 552 SUBMIT_ERR(context, "invalid syncobj_out '%#x'", args->syncobj_out); 553 err = -ENOENT; 554 goto unlock; 555 } 556 } 557 558 /* Allocate gather BO and copy gather words in. */ 559 err = submit_copy_gather_data(&bo, drm->dev, context, args); 560 if (err) 561 goto unlock; 562 563 job_data = kzalloc(sizeof(*job_data), GFP_KERNEL); 564 if (!job_data) { 565 SUBMIT_ERR(context, "failed to allocate memory for job data"); 566 err = -ENOMEM; 567 goto put_bo; 568 } 569 570 /* Get data buffer mappings and do relocation patching. */ 571 err = submit_process_bufs(context, bo, args, job_data); 572 if (err) 573 goto free_job_data; 574 575 /* Allocate host1x_job and add gathers and waits to it. */ 576 job = submit_create_job(context, bo, args, job_data, &fpriv->syncpoints); 577 if (IS_ERR(job)) { 578 err = PTR_ERR(job); 579 goto free_job_data; 580 } 581 582 /* Map gather data for Host1x. */ 583 err = host1x_job_pin(job, context->client->base.dev); 584 if (err) { 585 SUBMIT_ERR(context, "failed to pin job: %d", err); 586 goto put_job; 587 } 588 589 if (context->client->ops->get_streamid_offset) { 590 err = context->client->ops->get_streamid_offset( 591 context->client, &job->engine_streamid_offset); 592 if (err) { 593 SUBMIT_ERR(context, "failed to get streamid offset: %d", err); 594 goto unpin_job; 595 } 596 } 597 598 if (context->memory_context && context->client->ops->can_use_memory_ctx) { 599 bool supported; 600 601 err = context->client->ops->can_use_memory_ctx(context->client, &supported); 602 if (err) { 603 SUBMIT_ERR(context, "failed to detect if engine can use memory context: %d", err); 604 goto unpin_job; 605 } 606 607 if (supported) { 608 job->memory_context = context->memory_context; 609 host1x_memory_context_get(job->memory_context); 610 } 611 } else if (context->client->ops->get_streamid_offset) { 612 #ifdef CONFIG_IOMMU_API 613 struct iommu_fwspec *spec; 614 615 /* 616 * Job submission will need to temporarily change stream ID, 617 * so need to tell it what to change it back to. 618 */ 619 spec = dev_iommu_fwspec_get(context->client->base.dev); 620 if (spec && spec->num_ids > 0) 621 job->engine_fallback_streamid = spec->ids[0] & 0xffff; 622 else 623 job->engine_fallback_streamid = 0x7f; 624 #else 625 job->engine_fallback_streamid = 0x7f; 626 #endif 627 } 628 629 /* Boot engine. */ 630 err = pm_runtime_resume_and_get(context->client->base.dev); 631 if (err < 0) { 632 SUBMIT_ERR(context, "could not power up engine: %d", err); 633 goto put_memory_context; 634 } 635 636 job->user_data = job_data; 637 job->release = release_job; 638 job->timeout = 10000; 639 640 /* 641 * job_data is now part of job reference counting, so don't release 642 * it from here. 643 */ 644 job_data = NULL; 645 646 /* Submit job to hardware. */ 647 err = host1x_job_submit(job); 648 if (err) { 649 SUBMIT_ERR(context, "host1x job submission failed: %d", err); 650 goto unpin_job; 651 } 652 653 /* Return postfences to userspace and add fences to DMA reservations. */ 654 args->syncpt.value = job->syncpt_end; 655 656 if (syncobj) { 657 struct dma_fence *fence = host1x_fence_create(job->syncpt, job->syncpt_end); 658 if (IS_ERR(fence)) { 659 err = PTR_ERR(fence); 660 SUBMIT_ERR(context, "failed to create postfence: %d", err); 661 } 662 663 drm_syncobj_replace_fence(syncobj, fence); 664 } 665 666 goto put_job; 667 668 put_memory_context: 669 if (job->memory_context) 670 host1x_memory_context_put(job->memory_context); 671 unpin_job: 672 host1x_job_unpin(job); 673 put_job: 674 host1x_job_put(job); 675 free_job_data: 676 if (job_data && job_data->used_mappings) { 677 for (i = 0; i < job_data->num_used_mappings; i++) 678 tegra_drm_mapping_put(job_data->used_mappings[i].mapping); 679 680 kfree(job_data->used_mappings); 681 } 682 683 if (job_data) 684 kfree(job_data); 685 put_bo: 686 gather_bo_put(&bo->base); 687 unlock: 688 if (syncobj) 689 drm_syncobj_put(syncobj); 690 691 mutex_unlock(&fpriv->lock); 692 return err; 693 } 694