1 /* $NetBSD: amdgpu_gem.c,v 1.4 2018/08/27 15:22:54 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.4 2018/08/27 15:22:54 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 void amdgpu_gem_object_free(struct drm_gem_object *gobj) 39 { 40 struct amdgpu_bo *robj = gem_to_amdgpu_bo(gobj); 41 42 if (robj) { 43 if (robj->gem_base.import_attach) 44 drm_prime_gem_destroy(&robj->gem_base, robj->tbo.sg); 45 amdgpu_mn_unregister(robj); 46 amdgpu_bo_unref(&robj); 47 } 48 } 49 50 int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size, 51 int alignment, u32 initial_domain, 52 u64 flags, bool kernel, 53 struct drm_gem_object **obj) 54 { 55 struct amdgpu_bo *robj; 56 unsigned long max_size; 57 int r; 58 59 *obj = NULL; 60 /* At least align on page size */ 61 if (alignment < PAGE_SIZE) { 62 alignment = PAGE_SIZE; 63 } 64 65 if (!(initial_domain & (AMDGPU_GEM_DOMAIN_GDS | AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA))) { 66 /* Maximum bo size is the unpinned gtt size since we use the gtt to 67 * handle vram to system pool migrations. 68 */ 69 max_size = adev->mc.gtt_size - adev->gart_pin_size; 70 if (size > max_size) { 71 DRM_DEBUG("Allocation size %ldMb bigger than %ldMb limit\n", 72 size >> 20, max_size >> 20); 73 return -ENOMEM; 74 } 75 } 76 retry: 77 r = amdgpu_bo_create(adev, size, alignment, kernel, initial_domain, 78 flags, NULL, NULL, &robj); 79 if (r) { 80 if (r != -ERESTARTSYS) { 81 if (initial_domain == AMDGPU_GEM_DOMAIN_VRAM) { 82 initial_domain |= AMDGPU_GEM_DOMAIN_GTT; 83 goto retry; 84 } 85 DRM_ERROR("Failed to allocate GEM object (%ld, %d, %u, %d)\n", 86 size, initial_domain, alignment, r); 87 } 88 return r; 89 } 90 *obj = &robj->gem_base; 91 #ifndef __NetBSD__ 92 robj->pid = task_pid_nr(current); 93 #endif 94 95 mutex_lock(&adev->gem.mutex); 96 list_add_tail(&robj->list, &adev->gem.objects); 97 mutex_unlock(&adev->gem.mutex); 98 99 return 0; 100 } 101 102 int amdgpu_gem_init(struct amdgpu_device *adev) 103 { 104 INIT_LIST_HEAD(&adev->gem.objects); 105 return 0; 106 } 107 108 void amdgpu_gem_fini(struct amdgpu_device *adev) 109 { 110 amdgpu_bo_force_delete(adev); 111 } 112 113 /* 114 * Call from drm_gem_handle_create which appear in both new and open ioctl 115 * case. 116 */ 117 int amdgpu_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_priv) 118 { 119 struct amdgpu_bo *rbo = gem_to_amdgpu_bo(obj); 120 struct amdgpu_device *adev = rbo->adev; 121 struct amdgpu_fpriv *fpriv = file_priv->driver_priv; 122 struct amdgpu_vm *vm = &fpriv->vm; 123 struct amdgpu_bo_va *bo_va; 124 int r; 125 r = amdgpu_bo_reserve(rbo, false); 126 if (r) 127 return r; 128 129 bo_va = amdgpu_vm_bo_find(vm, rbo); 130 if (!bo_va) { 131 bo_va = amdgpu_vm_bo_add(adev, vm, rbo); 132 } else { 133 ++bo_va->ref_count; 134 } 135 amdgpu_bo_unreserve(rbo); 136 return 0; 137 } 138 139 void amdgpu_gem_object_close(struct drm_gem_object *obj, 140 struct drm_file *file_priv) 141 { 142 struct amdgpu_bo *rbo = gem_to_amdgpu_bo(obj); 143 struct amdgpu_device *adev = rbo->adev; 144 struct amdgpu_fpriv *fpriv = file_priv->driver_priv; 145 struct amdgpu_vm *vm = &fpriv->vm; 146 struct amdgpu_bo_va *bo_va; 147 int r; 148 r = amdgpu_bo_reserve(rbo, true); 149 if (r) { 150 dev_err(adev->dev, "leaking bo va because " 151 "we fail to reserve bo (%d)\n", r); 152 return; 153 } 154 bo_va = amdgpu_vm_bo_find(vm, rbo); 155 if (bo_va) { 156 if (--bo_va->ref_count == 0) { 157 amdgpu_vm_bo_rmv(adev, bo_va); 158 } 159 } 160 amdgpu_bo_unreserve(rbo); 161 } 162 163 static int amdgpu_gem_handle_lockup(struct amdgpu_device *adev, int r) 164 { 165 if (r == -EDEADLK) { 166 r = amdgpu_gpu_reset(adev); 167 if (!r) 168 r = -EAGAIN; 169 } 170 return r; 171 } 172 173 /* 174 * GEM ioctls. 175 */ 176 int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data, 177 struct drm_file *filp) 178 { 179 struct amdgpu_device *adev = dev->dev_private; 180 union drm_amdgpu_gem_create *args = data; 181 uint64_t size = args->in.bo_size; 182 struct drm_gem_object *gobj; 183 uint32_t handle; 184 bool kernel = false; 185 int r; 186 187 /* create a gem object to contain this object in */ 188 if (args->in.domains & (AMDGPU_GEM_DOMAIN_GDS | 189 AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA)) { 190 kernel = true; 191 if (args->in.domains == AMDGPU_GEM_DOMAIN_GDS) 192 size = size << AMDGPU_GDS_SHIFT; 193 else if (args->in.domains == AMDGPU_GEM_DOMAIN_GWS) 194 size = size << AMDGPU_GWS_SHIFT; 195 else if (args->in.domains == AMDGPU_GEM_DOMAIN_OA) 196 size = size << AMDGPU_OA_SHIFT; 197 else { 198 r = -EINVAL; 199 goto error_unlock; 200 } 201 } 202 size = roundup(size, PAGE_SIZE); 203 204 r = amdgpu_gem_object_create(adev, size, args->in.alignment, 205 (u32)(0xffffffff & args->in.domains), 206 args->in.domain_flags, 207 kernel, &gobj); 208 if (r) 209 goto error_unlock; 210 211 r = drm_gem_handle_create(filp, gobj, &handle); 212 /* drop reference from allocate - handle holds it now */ 213 drm_gem_object_unreference_unlocked(gobj); 214 if (r) 215 goto error_unlock; 216 217 memset(args, 0, sizeof(*args)); 218 args->out.handle = handle; 219 return 0; 220 221 error_unlock: 222 r = amdgpu_gem_handle_lockup(adev, r); 223 return r; 224 } 225 226 int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data, 227 struct drm_file *filp) 228 { 229 #ifdef __NetBSD__ 230 /* 231 * XXX Too painful to contemplate for now. If you add this, 232 * make sure to update amdgpu_cs.c amdgpu_cs_parser_relocs 233 * (need_mmap_lock), and anything else using 234 * amdgpu_ttm_tt_has_userptr. 235 */ 236 return -ENODEV; 237 #else 238 struct amdgpu_device *adev = dev->dev_private; 239 struct drm_amdgpu_gem_userptr *args = data; 240 struct drm_gem_object *gobj; 241 struct amdgpu_bo *bo; 242 uint32_t handle; 243 int r; 244 245 if (offset_in_page(args->addr | args->size)) 246 return -EINVAL; 247 248 /* reject unknown flag values */ 249 if (args->flags & ~(AMDGPU_GEM_USERPTR_READONLY | 250 AMDGPU_GEM_USERPTR_ANONONLY | AMDGPU_GEM_USERPTR_VALIDATE | 251 AMDGPU_GEM_USERPTR_REGISTER)) 252 return -EINVAL; 253 254 if (!(args->flags & AMDGPU_GEM_USERPTR_READONLY) && ( 255 !(args->flags & AMDGPU_GEM_USERPTR_ANONONLY) || 256 !(args->flags & AMDGPU_GEM_USERPTR_REGISTER))) { 257 258 /* if we want to write to it we must require anonymous 259 memory and install a MMU notifier */ 260 return -EACCES; 261 } 262 263 /* create a gem object to contain this object in */ 264 r = amdgpu_gem_object_create(adev, args->size, 0, 265 AMDGPU_GEM_DOMAIN_CPU, 0, 266 0, &gobj); 267 if (r) 268 goto handle_lockup; 269 270 bo = gem_to_amdgpu_bo(gobj); 271 r = amdgpu_ttm_tt_set_userptr(bo->tbo.ttm, args->addr, args->flags); 272 if (r) 273 goto release_object; 274 275 if (args->flags & AMDGPU_GEM_USERPTR_REGISTER) { 276 r = amdgpu_mn_register(bo, args->addr); 277 if (r) 278 goto release_object; 279 } 280 281 if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE) { 282 down_read(¤t->mm->mmap_sem); 283 r = amdgpu_bo_reserve(bo, true); 284 if (r) { 285 up_read(¤t->mm->mmap_sem); 286 goto release_object; 287 } 288 289 amdgpu_ttm_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_GTT); 290 r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false); 291 amdgpu_bo_unreserve(bo); 292 up_read(¤t->mm->mmap_sem); 293 if (r) 294 goto release_object; 295 } 296 297 r = drm_gem_handle_create(filp, gobj, &handle); 298 /* drop reference from allocate - handle holds it now */ 299 drm_gem_object_unreference_unlocked(gobj); 300 if (r) 301 goto handle_lockup; 302 303 args->handle = handle; 304 return 0; 305 306 release_object: 307 drm_gem_object_unreference_unlocked(gobj); 308 309 handle_lockup: 310 r = amdgpu_gem_handle_lockup(adev, r); 311 312 return r; 313 #endif 314 } 315 316 int amdgpu_mode_dumb_mmap(struct drm_file *filp, 317 struct drm_device *dev, 318 uint32_t handle, uint64_t *offset_p) 319 { 320 struct drm_gem_object *gobj; 321 struct amdgpu_bo *robj; 322 323 gobj = drm_gem_object_lookup(dev, filp, handle); 324 if (gobj == NULL) { 325 return -ENOENT; 326 } 327 robj = gem_to_amdgpu_bo(gobj); 328 if (amdgpu_ttm_tt_has_userptr(robj->tbo.ttm) || 329 (robj->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS)) { 330 drm_gem_object_unreference_unlocked(gobj); 331 return -EPERM; 332 } 333 *offset_p = amdgpu_bo_mmap_offset(robj); 334 drm_gem_object_unreference_unlocked(gobj); 335 return 0; 336 } 337 338 int amdgpu_gem_mmap_ioctl(struct drm_device *dev, void *data, 339 struct drm_file *filp) 340 { 341 union drm_amdgpu_gem_mmap *args = data; 342 uint32_t handle = args->in.handle; 343 memset(args, 0, sizeof(*args)); 344 return amdgpu_mode_dumb_mmap(filp, dev, handle, &args->out.addr_ptr); 345 } 346 347 /** 348 * amdgpu_gem_timeout - calculate jiffies timeout from absolute value 349 * 350 * @timeout_ns: timeout in ns 351 * 352 * Calculate the timeout in jiffies from an absolute timeout in ns. 353 */ 354 unsigned long amdgpu_gem_timeout(uint64_t timeout_ns) 355 { 356 unsigned long timeout_jiffies; 357 ktime_t timeout; 358 359 /* clamp timeout if it's to large */ 360 if (((int64_t)timeout_ns) < 0) 361 return MAX_SCHEDULE_TIMEOUT; 362 363 timeout = ktime_sub(ns_to_ktime(timeout_ns), ktime_get()); 364 if (ktime_to_ns(timeout) < 0) 365 return 0; 366 367 timeout_jiffies = nsecs_to_jiffies(ktime_to_ns(timeout)); 368 /* clamp timeout to avoid unsigned-> signed overflow */ 369 if (timeout_jiffies > MAX_SCHEDULE_TIMEOUT ) 370 return MAX_SCHEDULE_TIMEOUT - 1; 371 372 return timeout_jiffies; 373 } 374 375 int amdgpu_gem_wait_idle_ioctl(struct drm_device *dev, void *data, 376 struct drm_file *filp) 377 { 378 struct amdgpu_device *adev = dev->dev_private; 379 union drm_amdgpu_gem_wait_idle *args = data; 380 struct drm_gem_object *gobj; 381 struct amdgpu_bo *robj; 382 uint32_t handle = args->in.handle; 383 unsigned long timeout = amdgpu_gem_timeout(args->in.timeout); 384 int r = 0; 385 long ret; 386 387 gobj = drm_gem_object_lookup(dev, filp, handle); 388 if (gobj == NULL) { 389 return -ENOENT; 390 } 391 robj = gem_to_amdgpu_bo(gobj); 392 if (timeout == 0) 393 ret = reservation_object_test_signaled_rcu(robj->tbo.resv, true); 394 else 395 ret = reservation_object_wait_timeout_rcu(robj->tbo.resv, true, true, timeout); 396 397 /* ret == 0 means not signaled, 398 * ret > 0 means signaled 399 * ret < 0 means interrupted before timeout 400 */ 401 if (ret >= 0) { 402 memset(args, 0, sizeof(*args)); 403 args->out.status = (ret == 0); 404 } else 405 r = ret; 406 407 drm_gem_object_unreference_unlocked(gobj); 408 r = amdgpu_gem_handle_lockup(adev, r); 409 return r; 410 } 411 412 int amdgpu_gem_metadata_ioctl(struct drm_device *dev, void *data, 413 struct drm_file *filp) 414 { 415 struct drm_amdgpu_gem_metadata *args = data; 416 struct drm_gem_object *gobj; 417 struct amdgpu_bo *robj; 418 int r = -1; 419 420 DRM_DEBUG("%d \n", args->handle); 421 gobj = drm_gem_object_lookup(dev, filp, args->handle); 422 if (gobj == NULL) 423 return -ENOENT; 424 robj = gem_to_amdgpu_bo(gobj); 425 426 r = amdgpu_bo_reserve(robj, false); 427 if (unlikely(r != 0)) 428 goto out; 429 430 if (args->op == AMDGPU_GEM_METADATA_OP_GET_METADATA) { 431 amdgpu_bo_get_tiling_flags(robj, &args->data.tiling_info); 432 r = amdgpu_bo_get_metadata(robj, args->data.data, 433 sizeof(args->data.data), 434 &args->data.data_size_bytes, 435 &args->data.flags); 436 } else if (args->op == AMDGPU_GEM_METADATA_OP_SET_METADATA) { 437 if (args->data.data_size_bytes > sizeof(args->data.data)) { 438 r = -EINVAL; 439 goto unreserve; 440 } 441 r = amdgpu_bo_set_tiling_flags(robj, args->data.tiling_info); 442 if (!r) 443 r = amdgpu_bo_set_metadata(robj, args->data.data, 444 args->data.data_size_bytes, 445 args->data.flags); 446 } 447 448 unreserve: 449 amdgpu_bo_unreserve(robj); 450 out: 451 drm_gem_object_unreference_unlocked(gobj); 452 return r; 453 } 454 455 /** 456 * amdgpu_gem_va_update_vm -update the bo_va in its VM 457 * 458 * @adev: amdgpu_device pointer 459 * @bo_va: bo_va to update 460 * 461 * Update the bo_va directly after setting it's address. Errors are not 462 * vital here, so they are not reported back to userspace. 463 */ 464 static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev, 465 struct amdgpu_bo_va *bo_va, uint32_t operation) 466 { 467 struct ttm_validate_buffer tv, *entry; 468 struct amdgpu_bo_list_entry *vm_bos; 469 struct ww_acquire_ctx ticket; 470 struct list_head list, duplicates; 471 unsigned domain; 472 int r; 473 474 INIT_LIST_HEAD(&list); 475 INIT_LIST_HEAD(&duplicates); 476 477 tv.bo = &bo_va->bo->tbo; 478 tv.shared = true; 479 list_add(&tv.head, &list); 480 481 vm_bos = amdgpu_vm_get_bos(adev, bo_va->vm, &list); 482 if (!vm_bos) 483 return; 484 485 /* Provide duplicates to avoid -EALREADY */ 486 r = ttm_eu_reserve_buffers(&ticket, &list, true, &duplicates); 487 if (r) 488 goto error_free; 489 490 list_for_each_entry(entry, &list, head) { 491 domain = amdgpu_mem_type_to_domain(entry->bo->mem.mem_type); 492 /* if anything is swapped out don't swap it in here, 493 just abort and wait for the next CS */ 494 if (domain == AMDGPU_GEM_DOMAIN_CPU) 495 goto error_unreserve; 496 } 497 list_for_each_entry(entry, &duplicates, head) { 498 domain = amdgpu_mem_type_to_domain(entry->bo->mem.mem_type); 499 /* if anything is swapped out don't swap it in here, 500 just abort and wait for the next CS */ 501 if (domain == AMDGPU_GEM_DOMAIN_CPU) 502 goto error_unreserve; 503 } 504 505 r = amdgpu_vm_update_page_directory(adev, bo_va->vm); 506 if (r) 507 goto error_unreserve; 508 509 r = amdgpu_vm_clear_freed(adev, bo_va->vm); 510 if (r) 511 goto error_unreserve; 512 513 if (operation == AMDGPU_VA_OP_MAP) 514 r = amdgpu_vm_bo_update(adev, bo_va, &bo_va->bo->tbo.mem); 515 516 error_unreserve: 517 ttm_eu_backoff_reservation(&ticket, &list); 518 519 error_free: 520 drm_free_large(vm_bos); 521 522 if (r && r != -ERESTARTSYS) 523 DRM_ERROR("Couldn't update BO_VA (%d)\n", r); 524 } 525 526 527 528 int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, 529 struct drm_file *filp) 530 { 531 struct drm_amdgpu_gem_va *args = data; 532 struct drm_gem_object *gobj; 533 struct amdgpu_device *adev = dev->dev_private; 534 struct amdgpu_fpriv *fpriv = filp->driver_priv; 535 struct amdgpu_bo *rbo; 536 struct amdgpu_bo_va *bo_va; 537 struct ttm_validate_buffer tv, tv_pd; 538 struct ww_acquire_ctx ticket; 539 struct list_head list, duplicates; 540 uint32_t invalid_flags, va_flags = 0; 541 int r = 0; 542 543 if (!adev->vm_manager.enabled) 544 return -ENOTTY; 545 546 if (args->va_address < AMDGPU_VA_RESERVED_SIZE) { 547 dev_err(pci_dev_dev(dev->pdev), 548 "va_address 0x%lX is in reserved area 0x%X\n", 549 (unsigned long)args->va_address, 550 AMDGPU_VA_RESERVED_SIZE); 551 return -EINVAL; 552 } 553 554 invalid_flags = ~(AMDGPU_VM_DELAY_UPDATE | AMDGPU_VM_PAGE_READABLE | 555 AMDGPU_VM_PAGE_WRITEABLE | AMDGPU_VM_PAGE_EXECUTABLE); 556 if ((args->flags & invalid_flags)) { 557 dev_err(pci_dev_dev(dev->pdev), "invalid flags 0x%08X vs 0x%08X\n", 558 args->flags, invalid_flags); 559 return -EINVAL; 560 } 561 562 switch (args->operation) { 563 case AMDGPU_VA_OP_MAP: 564 case AMDGPU_VA_OP_UNMAP: 565 break; 566 default: 567 dev_err(pci_dev_dev(dev->pdev), "unsupported operation %d\n", 568 args->operation); 569 return -EINVAL; 570 } 571 572 gobj = drm_gem_object_lookup(dev, filp, args->handle); 573 if (gobj == NULL) 574 return -ENOENT; 575 rbo = gem_to_amdgpu_bo(gobj); 576 INIT_LIST_HEAD(&list); 577 INIT_LIST_HEAD(&duplicates); 578 tv.bo = &rbo->tbo; 579 tv.shared = true; 580 list_add(&tv.head, &list); 581 582 if (args->operation == AMDGPU_VA_OP_MAP) { 583 tv_pd.bo = &fpriv->vm.page_directory->tbo; 584 tv_pd.shared = true; 585 list_add(&tv_pd.head, &list); 586 } 587 r = ttm_eu_reserve_buffers(&ticket, &list, true, &duplicates); 588 if (r) { 589 drm_gem_object_unreference_unlocked(gobj); 590 return r; 591 } 592 593 bo_va = amdgpu_vm_bo_find(&fpriv->vm, rbo); 594 if (!bo_va) { 595 ttm_eu_backoff_reservation(&ticket, &list); 596 drm_gem_object_unreference_unlocked(gobj); 597 return -ENOENT; 598 } 599 600 switch (args->operation) { 601 case AMDGPU_VA_OP_MAP: 602 if (args->flags & AMDGPU_VM_PAGE_READABLE) 603 va_flags |= AMDGPU_PTE_READABLE; 604 if (args->flags & AMDGPU_VM_PAGE_WRITEABLE) 605 va_flags |= AMDGPU_PTE_WRITEABLE; 606 if (args->flags & AMDGPU_VM_PAGE_EXECUTABLE) 607 va_flags |= AMDGPU_PTE_EXECUTABLE; 608 r = amdgpu_vm_bo_map(adev, bo_va, args->va_address, 609 args->offset_in_bo, args->map_size, 610 va_flags); 611 break; 612 case AMDGPU_VA_OP_UNMAP: 613 r = amdgpu_vm_bo_unmap(adev, bo_va, args->va_address); 614 break; 615 default: 616 break; 617 } 618 ttm_eu_backoff_reservation(&ticket, &list); 619 if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE)) 620 amdgpu_gem_va_update_vm(adev, bo_va, args->operation); 621 622 drm_gem_object_unreference_unlocked(gobj); 623 return r; 624 } 625 626 int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data, 627 struct drm_file *filp) 628 { 629 struct drm_amdgpu_gem_op *args = data; 630 struct drm_gem_object *gobj; 631 struct amdgpu_bo *robj; 632 int r; 633 634 gobj = drm_gem_object_lookup(dev, filp, args->handle); 635 if (gobj == NULL) { 636 return -ENOENT; 637 } 638 robj = gem_to_amdgpu_bo(gobj); 639 640 r = amdgpu_bo_reserve(robj, false); 641 if (unlikely(r)) 642 goto out; 643 644 switch (args->op) { 645 case AMDGPU_GEM_OP_GET_GEM_CREATE_INFO: { 646 struct drm_amdgpu_gem_create_in info; 647 void __user *out = (void __user *)(long)args->value; 648 649 info.bo_size = robj->gem_base.size; 650 info.alignment = robj->tbo.mem.page_alignment << PAGE_SHIFT; 651 info.domains = robj->initial_domain; 652 info.domain_flags = robj->flags; 653 amdgpu_bo_unreserve(robj); 654 if (copy_to_user(out, &info, sizeof(info))) 655 r = -EFAULT; 656 break; 657 } 658 case AMDGPU_GEM_OP_SET_PLACEMENT: 659 if (amdgpu_ttm_tt_has_userptr(robj->tbo.ttm)) { 660 r = -EPERM; 661 amdgpu_bo_unreserve(robj); 662 break; 663 } 664 robj->initial_domain = args->value & (AMDGPU_GEM_DOMAIN_VRAM | 665 AMDGPU_GEM_DOMAIN_GTT | 666 AMDGPU_GEM_DOMAIN_CPU); 667 amdgpu_bo_unreserve(robj); 668 break; 669 default: 670 amdgpu_bo_unreserve(robj); 671 r = -EINVAL; 672 } 673 674 out: 675 drm_gem_object_unreference_unlocked(gobj); 676 return r; 677 } 678 679 int amdgpu_mode_dumb_create(struct drm_file *file_priv, 680 struct drm_device *dev, 681 struct drm_mode_create_dumb *args) 682 { 683 struct amdgpu_device *adev = dev->dev_private; 684 struct drm_gem_object *gobj; 685 uint32_t handle; 686 int r; 687 688 args->pitch = amdgpu_align_pitch(adev, args->width, args->bpp, 0) * ((args->bpp + 1) / 8); 689 args->size = (u64)args->pitch * args->height; 690 #ifdef __NetBSD__ /* XXX ALIGN means something else. */ 691 args->size = round_up(args->size, PAGE_SIZE); 692 #else 693 args->size = ALIGN(args->size, PAGE_SIZE); 694 #endif 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