1 /* $NetBSD: amdgpu_gem.c,v 1.6 2020/02/14 04:38:23 riastradh Exp $ */ 2 3 /* 4 * Copyright 2008 Advanced Micro Devices, Inc. 5 * Copyright 2008 Red Hat Inc. 6 * Copyright 2009 Jerome Glisse. 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the "Software"), 10 * to deal in the Software without restriction, including without limitation 11 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 * and/or sell copies of the Software, and to permit persons to whom the 13 * Software is furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included in 16 * all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 * OTHER DEALINGS IN THE SOFTWARE. 25 * 26 * Authors: Dave Airlie 27 * Alex Deucher 28 * Jerome Glisse 29 */ 30 #include <sys/cdefs.h> 31 __KERNEL_RCSID(0, "$NetBSD: amdgpu_gem.c,v 1.6 2020/02/14 04:38:23 riastradh Exp $"); 32 33 #include <linux/ktime.h> 34 #include <drm/drmP.h> 35 #include <drm/amdgpu_drm.h> 36 #include "amdgpu.h" 37 38 #include <linux/nbsd-namespace.h> 39 40 void amdgpu_gem_object_free(struct drm_gem_object *gobj) 41 { 42 struct amdgpu_bo *robj = gem_to_amdgpu_bo(gobj); 43 44 if (robj) { 45 if (robj->gem_base.import_attach) 46 drm_prime_gem_destroy(&robj->gem_base, robj->tbo.sg); 47 amdgpu_mn_unregister(robj); 48 amdgpu_bo_unref(&robj); 49 } 50 } 51 52 int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size, 53 int alignment, u32 initial_domain, 54 u64 flags, bool kernel, 55 struct drm_gem_object **obj) 56 { 57 struct amdgpu_bo *robj; 58 unsigned long max_size; 59 int r; 60 61 *obj = NULL; 62 /* At least align on page size */ 63 if (alignment < PAGE_SIZE) { 64 alignment = PAGE_SIZE; 65 } 66 67 if (!(initial_domain & (AMDGPU_GEM_DOMAIN_GDS | AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA))) { 68 /* Maximum bo size is the unpinned gtt size since we use the gtt to 69 * handle vram to system pool migrations. 70 */ 71 max_size = adev->mc.gtt_size - adev->gart_pin_size; 72 if (size > max_size) { 73 DRM_DEBUG("Allocation size %ldMb bigger than %ldMb limit\n", 74 size >> 20, max_size >> 20); 75 return -ENOMEM; 76 } 77 } 78 retry: 79 r = amdgpu_bo_create(adev, size, alignment, kernel, initial_domain, 80 flags, NULL, NULL, &robj); 81 if (r) { 82 if (r != -ERESTARTSYS) { 83 if (initial_domain == AMDGPU_GEM_DOMAIN_VRAM) { 84 initial_domain |= AMDGPU_GEM_DOMAIN_GTT; 85 goto retry; 86 } 87 DRM_ERROR("Failed to allocate GEM object (%ld, %d, %u, %d)\n", 88 size, initial_domain, alignment, r); 89 } 90 return r; 91 } 92 *obj = &robj->gem_base; 93 #ifndef __NetBSD__ 94 robj->pid = task_pid_nr(current); 95 #endif 96 97 mutex_lock(&adev->gem.mutex); 98 list_add_tail(&robj->list, &adev->gem.objects); 99 mutex_unlock(&adev->gem.mutex); 100 101 return 0; 102 } 103 104 int amdgpu_gem_init(struct amdgpu_device *adev) 105 { 106 INIT_LIST_HEAD(&adev->gem.objects); 107 return 0; 108 } 109 110 void amdgpu_gem_fini(struct amdgpu_device *adev) 111 { 112 amdgpu_bo_force_delete(adev); 113 } 114 115 /* 116 * Call from drm_gem_handle_create which appear in both new and open ioctl 117 * case. 118 */ 119 int amdgpu_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_priv) 120 { 121 struct amdgpu_bo *rbo = gem_to_amdgpu_bo(obj); 122 struct amdgpu_device *adev = rbo->adev; 123 struct amdgpu_fpriv *fpriv = file_priv->driver_priv; 124 struct amdgpu_vm *vm = &fpriv->vm; 125 struct amdgpu_bo_va *bo_va; 126 int r; 127 r = amdgpu_bo_reserve(rbo, false); 128 if (r) 129 return r; 130 131 bo_va = amdgpu_vm_bo_find(vm, rbo); 132 if (!bo_va) { 133 bo_va = amdgpu_vm_bo_add(adev, vm, rbo); 134 } else { 135 ++bo_va->ref_count; 136 } 137 amdgpu_bo_unreserve(rbo); 138 return 0; 139 } 140 141 void amdgpu_gem_object_close(struct drm_gem_object *obj, 142 struct drm_file *file_priv) 143 { 144 struct amdgpu_bo *rbo = gem_to_amdgpu_bo(obj); 145 struct amdgpu_device *adev = rbo->adev; 146 struct amdgpu_fpriv *fpriv = file_priv->driver_priv; 147 struct amdgpu_vm *vm = &fpriv->vm; 148 struct amdgpu_bo_va *bo_va; 149 int r; 150 r = amdgpu_bo_reserve(rbo, true); 151 if (r) { 152 dev_err(adev->dev, "leaking bo va because " 153 "we fail to reserve bo (%d)\n", r); 154 return; 155 } 156 bo_va = amdgpu_vm_bo_find(vm, rbo); 157 if (bo_va) { 158 if (--bo_va->ref_count == 0) { 159 amdgpu_vm_bo_rmv(adev, bo_va); 160 } 161 } 162 amdgpu_bo_unreserve(rbo); 163 } 164 165 static int amdgpu_gem_handle_lockup(struct amdgpu_device *adev, int r) 166 { 167 if (r == -EDEADLK) { 168 r = amdgpu_gpu_reset(adev); 169 if (!r) 170 r = -EAGAIN; 171 } 172 return r; 173 } 174 175 /* 176 * GEM ioctls. 177 */ 178 int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data, 179 struct drm_file *filp) 180 { 181 struct amdgpu_device *adev = dev->dev_private; 182 union drm_amdgpu_gem_create *args = data; 183 uint64_t size = args->in.bo_size; 184 struct drm_gem_object *gobj; 185 uint32_t handle; 186 bool kernel = false; 187 int r; 188 189 /* create a gem object to contain this object in */ 190 if (args->in.domains & (AMDGPU_GEM_DOMAIN_GDS | 191 AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA)) { 192 kernel = true; 193 if (args->in.domains == AMDGPU_GEM_DOMAIN_GDS) 194 size = size << AMDGPU_GDS_SHIFT; 195 else if (args->in.domains == AMDGPU_GEM_DOMAIN_GWS) 196 size = size << AMDGPU_GWS_SHIFT; 197 else if (args->in.domains == AMDGPU_GEM_DOMAIN_OA) 198 size = size << AMDGPU_OA_SHIFT; 199 else { 200 r = -EINVAL; 201 goto error_unlock; 202 } 203 } 204 size = roundup(size, PAGE_SIZE); 205 206 r = amdgpu_gem_object_create(adev, size, args->in.alignment, 207 (u32)(0xffffffff & args->in.domains), 208 args->in.domain_flags, 209 kernel, &gobj); 210 if (r) 211 goto error_unlock; 212 213 r = drm_gem_handle_create(filp, gobj, &handle); 214 /* drop reference from allocate - handle holds it now */ 215 drm_gem_object_unreference_unlocked(gobj); 216 if (r) 217 goto error_unlock; 218 219 memset(args, 0, sizeof(*args)); 220 args->out.handle = handle; 221 return 0; 222 223 error_unlock: 224 r = amdgpu_gem_handle_lockup(adev, r); 225 return r; 226 } 227 228 int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data, 229 struct drm_file *filp) 230 { 231 struct amdgpu_device *adev = dev->dev_private; 232 struct drm_amdgpu_gem_userptr *args = data; 233 struct drm_gem_object *gobj; 234 struct amdgpu_bo *bo; 235 uint32_t handle; 236 int r; 237 238 if (offset_in_page(args->addr | args->size)) 239 return -EINVAL; 240 241 /* reject unknown flag values */ 242 if (args->flags & ~(AMDGPU_GEM_USERPTR_READONLY | 243 AMDGPU_GEM_USERPTR_ANONONLY | AMDGPU_GEM_USERPTR_VALIDATE | 244 AMDGPU_GEM_USERPTR_REGISTER)) 245 return -EINVAL; 246 247 if (!(args->flags & AMDGPU_GEM_USERPTR_READONLY) && ( 248 !(args->flags & AMDGPU_GEM_USERPTR_ANONONLY) || 249 !(args->flags & AMDGPU_GEM_USERPTR_REGISTER))) { 250 251 /* if we want to write to it we must require anonymous 252 memory and install a MMU notifier */ 253 return -EACCES; 254 } 255 256 /* create a gem object to contain this object in */ 257 r = amdgpu_gem_object_create(adev, args->size, 0, 258 AMDGPU_GEM_DOMAIN_CPU, 0, 259 0, &gobj); 260 if (r) 261 goto handle_lockup; 262 263 bo = gem_to_amdgpu_bo(gobj); 264 r = amdgpu_ttm_tt_set_userptr(bo->tbo.ttm, args->addr, args->flags); 265 if (r) 266 goto release_object; 267 268 if (args->flags & AMDGPU_GEM_USERPTR_REGISTER) { 269 r = amdgpu_mn_register(bo, args->addr); 270 if (r) 271 goto release_object; 272 } 273 274 if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE) { 275 #ifdef __NetBSD__ 276 vm_map_lock_read(&curproc->p_vmspace->vm_map); 277 #else 278 down_read(¤t->mm->mmap_sem); 279 #endif 280 r = amdgpu_bo_reserve(bo, true); 281 if (r) { 282 #ifdef __NetBSD__ 283 vm_map_unlock_read(&curproc->p_vmspace->vm_map); 284 #else 285 up_read(¤t->mm->mmap_sem); 286 #endif 287 goto release_object; 288 } 289 290 amdgpu_ttm_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_GTT); 291 r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false); 292 amdgpu_bo_unreserve(bo); 293 #ifdef __NetBSD__ 294 vm_map_unlock_read(&curproc->p_vmspace->vm_map); 295 #else 296 up_read(¤t->mm->mmap_sem); 297 #endif 298 if (r) 299 goto release_object; 300 } 301 302 r = drm_gem_handle_create(filp, gobj, &handle); 303 /* drop reference from allocate - handle holds it now */ 304 drm_gem_object_unreference_unlocked(gobj); 305 if (r) 306 goto handle_lockup; 307 308 args->handle = handle; 309 return 0; 310 311 release_object: 312 drm_gem_object_unreference_unlocked(gobj); 313 314 handle_lockup: 315 r = amdgpu_gem_handle_lockup(adev, r); 316 317 return r; 318 } 319 320 int amdgpu_mode_dumb_mmap(struct drm_file *filp, 321 struct drm_device *dev, 322 uint32_t handle, uint64_t *offset_p) 323 { 324 struct drm_gem_object *gobj; 325 struct amdgpu_bo *robj; 326 327 gobj = drm_gem_object_lookup(dev, filp, handle); 328 if (gobj == NULL) { 329 return -ENOENT; 330 } 331 robj = gem_to_amdgpu_bo(gobj); 332 if (amdgpu_ttm_tt_has_userptr(robj->tbo.ttm) || 333 (robj->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS)) { 334 drm_gem_object_unreference_unlocked(gobj); 335 return -EPERM; 336 } 337 *offset_p = amdgpu_bo_mmap_offset(robj); 338 drm_gem_object_unreference_unlocked(gobj); 339 return 0; 340 } 341 342 int amdgpu_gem_mmap_ioctl(struct drm_device *dev, void *data, 343 struct drm_file *filp) 344 { 345 union drm_amdgpu_gem_mmap *args = data; 346 uint32_t handle = args->in.handle; 347 memset(args, 0, sizeof(*args)); 348 return amdgpu_mode_dumb_mmap(filp, dev, handle, &args->out.addr_ptr); 349 } 350 351 /** 352 * amdgpu_gem_timeout - calculate jiffies timeout from absolute value 353 * 354 * @timeout_ns: timeout in ns 355 * 356 * Calculate the timeout in jiffies from an absolute timeout in ns. 357 */ 358 unsigned long amdgpu_gem_timeout(uint64_t timeout_ns) 359 { 360 unsigned long timeout_jiffies; 361 ktime_t timeout; 362 363 /* clamp timeout if it's to large */ 364 if (((int64_t)timeout_ns) < 0) 365 return MAX_SCHEDULE_TIMEOUT; 366 367 timeout = ktime_sub(ns_to_ktime(timeout_ns), ktime_get()); 368 if (ktime_to_ns(timeout) < 0) 369 return 0; 370 371 timeout_jiffies = nsecs_to_jiffies(ktime_to_ns(timeout)); 372 /* clamp timeout to avoid unsigned-> signed overflow */ 373 if (timeout_jiffies > MAX_SCHEDULE_TIMEOUT ) 374 return MAX_SCHEDULE_TIMEOUT - 1; 375 376 return timeout_jiffies; 377 } 378 379 int amdgpu_gem_wait_idle_ioctl(struct drm_device *dev, void *data, 380 struct drm_file *filp) 381 { 382 struct amdgpu_device *adev = dev->dev_private; 383 union drm_amdgpu_gem_wait_idle *args = data; 384 struct drm_gem_object *gobj; 385 struct amdgpu_bo *robj; 386 uint32_t handle = args->in.handle; 387 unsigned long timeout = amdgpu_gem_timeout(args->in.timeout); 388 int r = 0; 389 long ret; 390 391 gobj = drm_gem_object_lookup(dev, filp, handle); 392 if (gobj == NULL) { 393 return -ENOENT; 394 } 395 robj = gem_to_amdgpu_bo(gobj); 396 if (timeout == 0) 397 ret = reservation_object_test_signaled_rcu(robj->tbo.resv, true); 398 else 399 ret = reservation_object_wait_timeout_rcu(robj->tbo.resv, true, true, timeout); 400 401 /* ret == 0 means not signaled, 402 * ret > 0 means signaled 403 * ret < 0 means interrupted before timeout 404 */ 405 if (ret >= 0) { 406 memset(args, 0, sizeof(*args)); 407 args->out.status = (ret == 0); 408 } else 409 r = ret; 410 411 drm_gem_object_unreference_unlocked(gobj); 412 r = amdgpu_gem_handle_lockup(adev, r); 413 return r; 414 } 415 416 int amdgpu_gem_metadata_ioctl(struct drm_device *dev, void *data, 417 struct drm_file *filp) 418 { 419 struct drm_amdgpu_gem_metadata *args = data; 420 struct drm_gem_object *gobj; 421 struct amdgpu_bo *robj; 422 int r = -1; 423 424 DRM_DEBUG("%d \n", args->handle); 425 gobj = drm_gem_object_lookup(dev, filp, args->handle); 426 if (gobj == NULL) 427 return -ENOENT; 428 robj = gem_to_amdgpu_bo(gobj); 429 430 r = amdgpu_bo_reserve(robj, false); 431 if (unlikely(r != 0)) 432 goto out; 433 434 if (args->op == AMDGPU_GEM_METADATA_OP_GET_METADATA) { 435 amdgpu_bo_get_tiling_flags(robj, &args->data.tiling_info); 436 r = amdgpu_bo_get_metadata(robj, args->data.data, 437 sizeof(args->data.data), 438 &args->data.data_size_bytes, 439 &args->data.flags); 440 } else if (args->op == AMDGPU_GEM_METADATA_OP_SET_METADATA) { 441 if (args->data.data_size_bytes > sizeof(args->data.data)) { 442 r = -EINVAL; 443 goto unreserve; 444 } 445 r = amdgpu_bo_set_tiling_flags(robj, args->data.tiling_info); 446 if (!r) 447 r = amdgpu_bo_set_metadata(robj, args->data.data, 448 args->data.data_size_bytes, 449 args->data.flags); 450 } 451 452 unreserve: 453 amdgpu_bo_unreserve(robj); 454 out: 455 drm_gem_object_unreference_unlocked(gobj); 456 return r; 457 } 458 459 /** 460 * amdgpu_gem_va_update_vm -update the bo_va in its VM 461 * 462 * @adev: amdgpu_device pointer 463 * @bo_va: bo_va to update 464 * 465 * Update the bo_va directly after setting it's address. Errors are not 466 * vital here, so they are not reported back to userspace. 467 */ 468 static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev, 469 struct amdgpu_bo_va *bo_va, uint32_t operation) 470 { 471 struct ttm_validate_buffer tv, *entry; 472 struct amdgpu_bo_list_entry *vm_bos; 473 struct ww_acquire_ctx ticket; 474 struct list_head list, duplicates; 475 unsigned domain; 476 int r; 477 478 INIT_LIST_HEAD(&list); 479 INIT_LIST_HEAD(&duplicates); 480 481 tv.bo = &bo_va->bo->tbo; 482 tv.shared = true; 483 list_add(&tv.head, &list); 484 485 vm_bos = amdgpu_vm_get_bos(adev, bo_va->vm, &list); 486 if (!vm_bos) 487 return; 488 489 /* Provide duplicates to avoid -EALREADY */ 490 r = ttm_eu_reserve_buffers(&ticket, &list, true, &duplicates); 491 if (r) 492 goto error_free; 493 494 list_for_each_entry(entry, &list, head) { 495 domain = amdgpu_mem_type_to_domain(entry->bo->mem.mem_type); 496 /* if anything is swapped out don't swap it in here, 497 just abort and wait for the next CS */ 498 if (domain == AMDGPU_GEM_DOMAIN_CPU) 499 goto error_unreserve; 500 } 501 list_for_each_entry(entry, &duplicates, head) { 502 domain = amdgpu_mem_type_to_domain(entry->bo->mem.mem_type); 503 /* if anything is swapped out don't swap it in here, 504 just abort and wait for the next CS */ 505 if (domain == AMDGPU_GEM_DOMAIN_CPU) 506 goto error_unreserve; 507 } 508 509 r = amdgpu_vm_update_page_directory(adev, bo_va->vm); 510 if (r) 511 goto error_unreserve; 512 513 r = amdgpu_vm_clear_freed(adev, bo_va->vm); 514 if (r) 515 goto error_unreserve; 516 517 if (operation == AMDGPU_VA_OP_MAP) 518 r = amdgpu_vm_bo_update(adev, bo_va, &bo_va->bo->tbo.mem); 519 520 error_unreserve: 521 ttm_eu_backoff_reservation(&ticket, &list); 522 523 error_free: 524 drm_free_large(vm_bos); 525 526 if (r && r != -ERESTARTSYS) 527 DRM_ERROR("Couldn't update BO_VA (%d)\n", r); 528 } 529 530 531 532 int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, 533 struct drm_file *filp) 534 { 535 struct drm_amdgpu_gem_va *args = data; 536 struct drm_gem_object *gobj; 537 struct amdgpu_device *adev = dev->dev_private; 538 struct amdgpu_fpriv *fpriv = filp->driver_priv; 539 struct amdgpu_bo *rbo; 540 struct amdgpu_bo_va *bo_va; 541 struct ttm_validate_buffer tv, tv_pd; 542 struct ww_acquire_ctx ticket; 543 struct list_head list, duplicates; 544 uint32_t invalid_flags, va_flags = 0; 545 int r = 0; 546 547 if (!adev->vm_manager.enabled) 548 return -ENOTTY; 549 550 if (args->va_address < AMDGPU_VA_RESERVED_SIZE) { 551 dev_err(pci_dev_dev(dev->pdev), 552 "va_address 0x%lX is in reserved area 0x%X\n", 553 (unsigned long)args->va_address, 554 AMDGPU_VA_RESERVED_SIZE); 555 return -EINVAL; 556 } 557 558 invalid_flags = ~(AMDGPU_VM_DELAY_UPDATE | AMDGPU_VM_PAGE_READABLE | 559 AMDGPU_VM_PAGE_WRITEABLE | AMDGPU_VM_PAGE_EXECUTABLE); 560 if ((args->flags & invalid_flags)) { 561 dev_err(pci_dev_dev(dev->pdev), "invalid flags 0x%08X vs 0x%08X\n", 562 args->flags, invalid_flags); 563 return -EINVAL; 564 } 565 566 switch (args->operation) { 567 case AMDGPU_VA_OP_MAP: 568 case AMDGPU_VA_OP_UNMAP: 569 break; 570 default: 571 dev_err(pci_dev_dev(dev->pdev), "unsupported operation %d\n", 572 args->operation); 573 return -EINVAL; 574 } 575 576 gobj = drm_gem_object_lookup(dev, filp, args->handle); 577 if (gobj == NULL) 578 return -ENOENT; 579 rbo = gem_to_amdgpu_bo(gobj); 580 INIT_LIST_HEAD(&list); 581 INIT_LIST_HEAD(&duplicates); 582 tv.bo = &rbo->tbo; 583 tv.shared = true; 584 list_add(&tv.head, &list); 585 586 if (args->operation == AMDGPU_VA_OP_MAP) { 587 tv_pd.bo = &fpriv->vm.page_directory->tbo; 588 tv_pd.shared = true; 589 list_add(&tv_pd.head, &list); 590 } 591 r = ttm_eu_reserve_buffers(&ticket, &list, true, &duplicates); 592 if (r) { 593 drm_gem_object_unreference_unlocked(gobj); 594 return r; 595 } 596 597 bo_va = amdgpu_vm_bo_find(&fpriv->vm, rbo); 598 if (!bo_va) { 599 ttm_eu_backoff_reservation(&ticket, &list); 600 drm_gem_object_unreference_unlocked(gobj); 601 return -ENOENT; 602 } 603 604 switch (args->operation) { 605 case AMDGPU_VA_OP_MAP: 606 if (args->flags & AMDGPU_VM_PAGE_READABLE) 607 va_flags |= AMDGPU_PTE_READABLE; 608 if (args->flags & AMDGPU_VM_PAGE_WRITEABLE) 609 va_flags |= AMDGPU_PTE_WRITEABLE; 610 if (args->flags & AMDGPU_VM_PAGE_EXECUTABLE) 611 va_flags |= AMDGPU_PTE_EXECUTABLE; 612 r = amdgpu_vm_bo_map(adev, bo_va, args->va_address, 613 args->offset_in_bo, args->map_size, 614 va_flags); 615 break; 616 case AMDGPU_VA_OP_UNMAP: 617 r = amdgpu_vm_bo_unmap(adev, bo_va, args->va_address); 618 break; 619 default: 620 break; 621 } 622 ttm_eu_backoff_reservation(&ticket, &list); 623 if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE)) 624 amdgpu_gem_va_update_vm(adev, bo_va, args->operation); 625 626 drm_gem_object_unreference_unlocked(gobj); 627 return r; 628 } 629 630 int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data, 631 struct drm_file *filp) 632 { 633 struct drm_amdgpu_gem_op *args = data; 634 struct drm_gem_object *gobj; 635 struct amdgpu_bo *robj; 636 int r; 637 638 gobj = drm_gem_object_lookup(dev, filp, args->handle); 639 if (gobj == NULL) { 640 return -ENOENT; 641 } 642 robj = gem_to_amdgpu_bo(gobj); 643 644 r = amdgpu_bo_reserve(robj, false); 645 if (unlikely(r)) 646 goto out; 647 648 switch (args->op) { 649 case AMDGPU_GEM_OP_GET_GEM_CREATE_INFO: { 650 struct drm_amdgpu_gem_create_in info; 651 void __user *out = (void __user *)(long)args->value; 652 653 info.bo_size = robj->gem_base.size; 654 info.alignment = robj->tbo.mem.page_alignment << PAGE_SHIFT; 655 info.domains = robj->initial_domain; 656 info.domain_flags = robj->flags; 657 amdgpu_bo_unreserve(robj); 658 if (copy_to_user(out, &info, sizeof(info))) 659 r = -EFAULT; 660 break; 661 } 662 case AMDGPU_GEM_OP_SET_PLACEMENT: 663 if (amdgpu_ttm_tt_has_userptr(robj->tbo.ttm)) { 664 r = -EPERM; 665 amdgpu_bo_unreserve(robj); 666 break; 667 } 668 robj->initial_domain = args->value & (AMDGPU_GEM_DOMAIN_VRAM | 669 AMDGPU_GEM_DOMAIN_GTT | 670 AMDGPU_GEM_DOMAIN_CPU); 671 amdgpu_bo_unreserve(robj); 672 break; 673 default: 674 amdgpu_bo_unreserve(robj); 675 r = -EINVAL; 676 } 677 678 out: 679 drm_gem_object_unreference_unlocked(gobj); 680 return r; 681 } 682 683 int amdgpu_mode_dumb_create(struct drm_file *file_priv, 684 struct drm_device *dev, 685 struct drm_mode_create_dumb *args) 686 { 687 struct amdgpu_device *adev = dev->dev_private; 688 struct drm_gem_object *gobj; 689 uint32_t handle; 690 int r; 691 692 args->pitch = amdgpu_align_pitch(adev, args->width, args->bpp, 0) * ((args->bpp + 1) / 8); 693 args->size = (u64)args->pitch * args->height; 694 args->size = ALIGN(args->size, PAGE_SIZE); 695 696 r = amdgpu_gem_object_create(adev, args->size, 0, 697 AMDGPU_GEM_DOMAIN_VRAM, 698 AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, 699 ttm_bo_type_device, 700 &gobj); 701 if (r) 702 return -ENOMEM; 703 704 r = drm_gem_handle_create(file_priv, gobj, &handle); 705 /* drop reference from allocate - handle holds it now */ 706 drm_gem_object_unreference_unlocked(gobj); 707 if (r) { 708 return r; 709 } 710 args->handle = handle; 711 return 0; 712 } 713 714 #if defined(CONFIG_DEBUG_FS) 715 static int amdgpu_debugfs_gem_info(struct seq_file *m, void *data) 716 { 717 struct drm_info_node *node = (struct drm_info_node *)m->private; 718 struct drm_device *dev = node->minor->dev; 719 struct amdgpu_device *adev = dev->dev_private; 720 struct amdgpu_bo *rbo; 721 unsigned i = 0; 722 723 mutex_lock(&adev->gem.mutex); 724 list_for_each_entry(rbo, &adev->gem.objects, list) { 725 unsigned domain; 726 const char *placement; 727 728 domain = amdgpu_mem_type_to_domain(rbo->tbo.mem.mem_type); 729 switch (domain) { 730 case AMDGPU_GEM_DOMAIN_VRAM: 731 placement = "VRAM"; 732 break; 733 case AMDGPU_GEM_DOMAIN_GTT: 734 placement = " GTT"; 735 break; 736 case AMDGPU_GEM_DOMAIN_CPU: 737 default: 738 placement = " CPU"; 739 break; 740 } 741 seq_printf(m, "bo[0x%08x] %8ldkB %8ldMB %s pid %8ld\n", 742 i, amdgpu_bo_size(rbo) >> 10, amdgpu_bo_size(rbo) >> 20, 743 placement, (unsigned long)rbo->pid); 744 i++; 745 } 746 mutex_unlock(&adev->gem.mutex); 747 return 0; 748 } 749 750 static struct drm_info_list amdgpu_debugfs_gem_list[] = { 751 {"amdgpu_gem_info", &amdgpu_debugfs_gem_info, 0, NULL}, 752 }; 753 #endif 754 755 int amdgpu_gem_debugfs_init(struct amdgpu_device *adev) 756 { 757 #if defined(CONFIG_DEBUG_FS) 758 return amdgpu_debugfs_add_files(adev, amdgpu_debugfs_gem_list, 1); 759 #endif 760 return 0; 761 } 762