linux/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
<<
>>
Prefs
   1/*
   2 * Copyright 2008 Advanced Micro Devices, Inc.
   3 * Copyright 2008 Red Hat Inc.
   4 * Copyright 2009 Jerome Glisse.
   5 *
   6 * Permission is hereby granted, free of charge, to any person obtaining a
   7 * copy of this software and associated documentation files (the "Software"),
   8 * to deal in the Software without restriction, including without limitation
   9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10 * and/or sell copies of the Software, and to permit persons to whom the
  11 * Software is furnished to do so, subject to the following conditions:
  12 *
  13 * The above copyright notice and this permission notice shall be included in
  14 * all copies or substantial portions of the Software.
  15 *
  16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  22 * OTHER DEALINGS IN THE SOFTWARE.
  23 *
  24 * Authors: Dave Airlie
  25 *          Alex Deucher
  26 *          Jerome Glisse
  27 */
  28#include <linux/ktime.h>
  29#include <linux/module.h>
  30#include <linux/pagemap.h>
  31#include <linux/pci.h>
  32
  33#include <drm/amdgpu_drm.h>
  34#include <drm/drm_debugfs.h>
  35
  36#include "amdgpu.h"
  37#include "amdgpu_display.h"
  38#include "amdgpu_xgmi.h"
  39
  40void 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                amdgpu_mn_unregister(robj);
  46                amdgpu_bo_unref(&robj);
  47        }
  48}
  49
  50int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size,
  51                             int alignment, u32 initial_domain,
  52                             u64 flags, enum ttm_bo_type type,
  53                             struct dma_resv *resv,
  54                             struct drm_gem_object **obj)
  55{
  56        struct amdgpu_bo *bo;
  57        struct amdgpu_bo_param bp;
  58        int r;
  59
  60        memset(&bp, 0, sizeof(bp));
  61        *obj = NULL;
  62
  63        bp.size = size;
  64        bp.byte_align = alignment;
  65        bp.type = type;
  66        bp.resv = resv;
  67        bp.preferred_domain = initial_domain;
  68retry:
  69        bp.flags = flags;
  70        bp.domain = initial_domain;
  71        r = amdgpu_bo_create(adev, &bp, &bo);
  72        if (r) {
  73                if (r != -ERESTARTSYS) {
  74                        if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) {
  75                                flags &= ~AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
  76                                goto retry;
  77                        }
  78
  79                        if (initial_domain == AMDGPU_GEM_DOMAIN_VRAM) {
  80                                initial_domain |= AMDGPU_GEM_DOMAIN_GTT;
  81                                goto retry;
  82                        }
  83                        DRM_DEBUG("Failed to allocate GEM object (%ld, %d, %u, %d)\n",
  84                                  size, initial_domain, alignment, r);
  85                }
  86                return r;
  87        }
  88        *obj = &bo->tbo.base;
  89
  90        return 0;
  91}
  92
  93void amdgpu_gem_force_release(struct amdgpu_device *adev)
  94{
  95        struct drm_device *ddev = adev->ddev;
  96        struct drm_file *file;
  97
  98        mutex_lock(&ddev->filelist_mutex);
  99
 100        list_for_each_entry(file, &ddev->filelist, lhead) {
 101                struct drm_gem_object *gobj;
 102                int handle;
 103
 104                WARN_ONCE(1, "Still active user space clients!\n");
 105                spin_lock(&file->table_lock);
 106                idr_for_each_entry(&file->object_idr, gobj, handle) {
 107                        WARN_ONCE(1, "And also active allocations!\n");
 108                        drm_gem_object_put_unlocked(gobj);
 109                }
 110                idr_destroy(&file->object_idr);
 111                spin_unlock(&file->table_lock);
 112        }
 113
 114        mutex_unlock(&ddev->filelist_mutex);
 115}
 116
 117/*
 118 * Call from drm_gem_handle_create which appear in both new and open ioctl
 119 * case.
 120 */
 121int amdgpu_gem_object_open(struct drm_gem_object *obj,
 122                           struct drm_file *file_priv)
 123{
 124        struct amdgpu_bo *abo = gem_to_amdgpu_bo(obj);
 125        struct amdgpu_device *adev = amdgpu_ttm_adev(abo->tbo.bdev);
 126        struct amdgpu_fpriv *fpriv = file_priv->driver_priv;
 127        struct amdgpu_vm *vm = &fpriv->vm;
 128        struct amdgpu_bo_va *bo_va;
 129        struct mm_struct *mm;
 130        int r;
 131
 132        mm = amdgpu_ttm_tt_get_usermm(abo->tbo.ttm);
 133        if (mm && mm != current->mm)
 134                return -EPERM;
 135
 136        if (abo->flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID &&
 137            abo->tbo.base.resv != vm->root.base.bo->tbo.base.resv)
 138                return -EPERM;
 139
 140        r = amdgpu_bo_reserve(abo, false);
 141        if (r)
 142                return r;
 143
 144        bo_va = amdgpu_vm_bo_find(vm, abo);
 145        if (!bo_va) {
 146                bo_va = amdgpu_vm_bo_add(adev, vm, abo);
 147        } else {
 148                ++bo_va->ref_count;
 149        }
 150        amdgpu_bo_unreserve(abo);
 151        return 0;
 152}
 153
 154void amdgpu_gem_object_close(struct drm_gem_object *obj,
 155                             struct drm_file *file_priv)
 156{
 157        struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
 158        struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
 159        struct amdgpu_fpriv *fpriv = file_priv->driver_priv;
 160        struct amdgpu_vm *vm = &fpriv->vm;
 161
 162        struct amdgpu_bo_list_entry vm_pd;
 163        struct list_head list, duplicates;
 164        struct ttm_validate_buffer tv;
 165        struct ww_acquire_ctx ticket;
 166        struct amdgpu_bo_va *bo_va;
 167        int r;
 168
 169        INIT_LIST_HEAD(&list);
 170        INIT_LIST_HEAD(&duplicates);
 171
 172        tv.bo = &bo->tbo;
 173        tv.num_shared = 1;
 174        list_add(&tv.head, &list);
 175
 176        amdgpu_vm_get_pd_bo(vm, &list, &vm_pd);
 177
 178        r = ttm_eu_reserve_buffers(&ticket, &list, false, &duplicates, false);
 179        if (r) {
 180                dev_err(adev->dev, "leaking bo va because "
 181                        "we fail to reserve bo (%d)\n", r);
 182                return;
 183        }
 184        bo_va = amdgpu_vm_bo_find(vm, bo);
 185        if (bo_va && --bo_va->ref_count == 0) {
 186                amdgpu_vm_bo_rmv(adev, bo_va);
 187
 188                if (amdgpu_vm_ready(vm)) {
 189                        struct dma_fence *fence = NULL;
 190
 191                        r = amdgpu_vm_clear_freed(adev, vm, &fence);
 192                        if (unlikely(r)) {
 193                                dev_err(adev->dev, "failed to clear page "
 194                                        "tables on GEM object close (%d)\n", r);
 195                        }
 196
 197                        if (fence) {
 198                                amdgpu_bo_fence(bo, fence, true);
 199                                dma_fence_put(fence);
 200                        }
 201                }
 202        }
 203        ttm_eu_backoff_reservation(&ticket, &list);
 204}
 205
 206/*
 207 * GEM ioctls.
 208 */
 209int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
 210                            struct drm_file *filp)
 211{
 212        struct amdgpu_device *adev = dev->dev_private;
 213        struct amdgpu_fpriv *fpriv = filp->driver_priv;
 214        struct amdgpu_vm *vm = &fpriv->vm;
 215        union drm_amdgpu_gem_create *args = data;
 216        uint64_t flags = args->in.domain_flags;
 217        uint64_t size = args->in.bo_size;
 218        struct dma_resv *resv = NULL;
 219        struct drm_gem_object *gobj;
 220        uint32_t handle;
 221        int r;
 222
 223        /* reject invalid gem flags */
 224        if (flags & ~(AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
 225                      AMDGPU_GEM_CREATE_NO_CPU_ACCESS |
 226                      AMDGPU_GEM_CREATE_CPU_GTT_USWC |
 227                      AMDGPU_GEM_CREATE_VRAM_CLEARED |
 228                      AMDGPU_GEM_CREATE_VM_ALWAYS_VALID |
 229                      AMDGPU_GEM_CREATE_EXPLICIT_SYNC))
 230
 231                return -EINVAL;
 232
 233        /* reject invalid gem domains */
 234        if (args->in.domains & ~AMDGPU_GEM_DOMAIN_MASK)
 235                return -EINVAL;
 236
 237        /* create a gem object to contain this object in */
 238        if (args->in.domains & (AMDGPU_GEM_DOMAIN_GDS |
 239            AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA)) {
 240                if (flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID) {
 241                        /* if gds bo is created from user space, it must be
 242                         * passed to bo list
 243                         */
 244                        DRM_ERROR("GDS bo cannot be per-vm-bo\n");
 245                        return -EINVAL;
 246                }
 247                flags |= AMDGPU_GEM_CREATE_NO_CPU_ACCESS;
 248        }
 249
 250        if (flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID) {
 251                r = amdgpu_bo_reserve(vm->root.base.bo, false);
 252                if (r)
 253                        return r;
 254
 255                resv = vm->root.base.bo->tbo.base.resv;
 256        }
 257
 258        r = amdgpu_gem_object_create(adev, size, args->in.alignment,
 259                                     (u32)(0xffffffff & args->in.domains),
 260                                     flags, ttm_bo_type_device, resv, &gobj);
 261        if (flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID) {
 262                if (!r) {
 263                        struct amdgpu_bo *abo = gem_to_amdgpu_bo(gobj);
 264
 265                        abo->parent = amdgpu_bo_ref(vm->root.base.bo);
 266                }
 267                amdgpu_bo_unreserve(vm->root.base.bo);
 268        }
 269        if (r)
 270                return r;
 271
 272        r = drm_gem_handle_create(filp, gobj, &handle);
 273        /* drop reference from allocate - handle holds it now */
 274        drm_gem_object_put_unlocked(gobj);
 275        if (r)
 276                return r;
 277
 278        memset(args, 0, sizeof(*args));
 279        args->out.handle = handle;
 280        return 0;
 281}
 282
 283int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
 284                             struct drm_file *filp)
 285{
 286        struct ttm_operation_ctx ctx = { true, false };
 287        struct amdgpu_device *adev = dev->dev_private;
 288        struct drm_amdgpu_gem_userptr *args = data;
 289        struct drm_gem_object *gobj;
 290        struct amdgpu_bo *bo;
 291        uint32_t handle;
 292        int r;
 293
 294        args->addr = untagged_addr(args->addr);
 295
 296        if (offset_in_page(args->addr | args->size))
 297                return -EINVAL;
 298
 299        /* reject unknown flag values */
 300        if (args->flags & ~(AMDGPU_GEM_USERPTR_READONLY |
 301            AMDGPU_GEM_USERPTR_ANONONLY | AMDGPU_GEM_USERPTR_VALIDATE |
 302            AMDGPU_GEM_USERPTR_REGISTER))
 303                return -EINVAL;
 304
 305        if (!(args->flags & AMDGPU_GEM_USERPTR_READONLY) &&
 306             !(args->flags & AMDGPU_GEM_USERPTR_REGISTER)) {
 307
 308                /* if we want to write to it we must install a MMU notifier */
 309                return -EACCES;
 310        }
 311
 312        /* create a gem object to contain this object in */
 313        r = amdgpu_gem_object_create(adev, args->size, 0, AMDGPU_GEM_DOMAIN_CPU,
 314                                     0, ttm_bo_type_device, NULL, &gobj);
 315        if (r)
 316                return r;
 317
 318        bo = gem_to_amdgpu_bo(gobj);
 319        bo->preferred_domains = AMDGPU_GEM_DOMAIN_GTT;
 320        bo->allowed_domains = AMDGPU_GEM_DOMAIN_GTT;
 321        r = amdgpu_ttm_tt_set_userptr(bo->tbo.ttm, args->addr, args->flags);
 322        if (r)
 323                goto release_object;
 324
 325        if (args->flags & AMDGPU_GEM_USERPTR_REGISTER) {
 326                r = amdgpu_mn_register(bo, args->addr);
 327                if (r)
 328                        goto release_object;
 329        }
 330
 331        if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE) {
 332                r = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages);
 333                if (r)
 334                        goto release_object;
 335
 336                r = amdgpu_bo_reserve(bo, true);
 337                if (r)
 338                        goto user_pages_done;
 339
 340                amdgpu_bo_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_GTT);
 341                r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
 342                amdgpu_bo_unreserve(bo);
 343                if (r)
 344                        goto user_pages_done;
 345        }
 346
 347        r = drm_gem_handle_create(filp, gobj, &handle);
 348        if (r)
 349                goto user_pages_done;
 350
 351        args->handle = handle;
 352
 353user_pages_done:
 354        if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE)
 355                amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
 356
 357release_object:
 358        drm_gem_object_put_unlocked(gobj);
 359
 360        return r;
 361}
 362
 363int amdgpu_mode_dumb_mmap(struct drm_file *filp,
 364                          struct drm_device *dev,
 365                          uint32_t handle, uint64_t *offset_p)
 366{
 367        struct drm_gem_object *gobj;
 368        struct amdgpu_bo *robj;
 369
 370        gobj = drm_gem_object_lookup(filp, handle);
 371        if (gobj == NULL) {
 372                return -ENOENT;
 373        }
 374        robj = gem_to_amdgpu_bo(gobj);
 375        if (amdgpu_ttm_tt_get_usermm(robj->tbo.ttm) ||
 376            (robj->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS)) {
 377                drm_gem_object_put_unlocked(gobj);
 378                return -EPERM;
 379        }
 380        *offset_p = amdgpu_bo_mmap_offset(robj);
 381        drm_gem_object_put_unlocked(gobj);
 382        return 0;
 383}
 384
 385int amdgpu_gem_mmap_ioctl(struct drm_device *dev, void *data,
 386                          struct drm_file *filp)
 387{
 388        union drm_amdgpu_gem_mmap *args = data;
 389        uint32_t handle = args->in.handle;
 390        memset(args, 0, sizeof(*args));
 391        return amdgpu_mode_dumb_mmap(filp, dev, handle, &args->out.addr_ptr);
 392}
 393
 394/**
 395 * amdgpu_gem_timeout - calculate jiffies timeout from absolute value
 396 *
 397 * @timeout_ns: timeout in ns
 398 *
 399 * Calculate the timeout in jiffies from an absolute timeout in ns.
 400 */
 401unsigned long amdgpu_gem_timeout(uint64_t timeout_ns)
 402{
 403        unsigned long timeout_jiffies;
 404        ktime_t timeout;
 405
 406        /* clamp timeout if it's to large */
 407        if (((int64_t)timeout_ns) < 0)
 408                return MAX_SCHEDULE_TIMEOUT;
 409
 410        timeout = ktime_sub(ns_to_ktime(timeout_ns), ktime_get());
 411        if (ktime_to_ns(timeout) < 0)
 412                return 0;
 413
 414        timeout_jiffies = nsecs_to_jiffies(ktime_to_ns(timeout));
 415        /*  clamp timeout to avoid unsigned-> signed overflow */
 416        if (timeout_jiffies > MAX_SCHEDULE_TIMEOUT )
 417                return MAX_SCHEDULE_TIMEOUT - 1;
 418
 419        return timeout_jiffies;
 420}
 421
 422int amdgpu_gem_wait_idle_ioctl(struct drm_device *dev, void *data,
 423                              struct drm_file *filp)
 424{
 425        union drm_amdgpu_gem_wait_idle *args = data;
 426        struct drm_gem_object *gobj;
 427        struct amdgpu_bo *robj;
 428        uint32_t handle = args->in.handle;
 429        unsigned long timeout = amdgpu_gem_timeout(args->in.timeout);
 430        int r = 0;
 431        long ret;
 432
 433        gobj = drm_gem_object_lookup(filp, handle);
 434        if (gobj == NULL) {
 435                return -ENOENT;
 436        }
 437        robj = gem_to_amdgpu_bo(gobj);
 438        ret = dma_resv_wait_timeout_rcu(robj->tbo.base.resv, true, true,
 439                                                  timeout);
 440
 441        /* ret == 0 means not signaled,
 442         * ret > 0 means signaled
 443         * ret < 0 means interrupted before timeout
 444         */
 445        if (ret >= 0) {
 446                memset(args, 0, sizeof(*args));
 447                args->out.status = (ret == 0);
 448        } else
 449                r = ret;
 450
 451        drm_gem_object_put_unlocked(gobj);
 452        return r;
 453}
 454
 455int amdgpu_gem_metadata_ioctl(struct drm_device *dev, void *data,
 456                                struct drm_file *filp)
 457{
 458        struct drm_amdgpu_gem_metadata *args = data;
 459        struct drm_gem_object *gobj;
 460        struct amdgpu_bo *robj;
 461        int r = -1;
 462
 463        DRM_DEBUG("%d \n", args->handle);
 464        gobj = drm_gem_object_lookup(filp, args->handle);
 465        if (gobj == NULL)
 466                return -ENOENT;
 467        robj = gem_to_amdgpu_bo(gobj);
 468
 469        r = amdgpu_bo_reserve(robj, false);
 470        if (unlikely(r != 0))
 471                goto out;
 472
 473        if (args->op == AMDGPU_GEM_METADATA_OP_GET_METADATA) {
 474                amdgpu_bo_get_tiling_flags(robj, &args->data.tiling_info);
 475                r = amdgpu_bo_get_metadata(robj, args->data.data,
 476                                           sizeof(args->data.data),
 477                                           &args->data.data_size_bytes,
 478                                           &args->data.flags);
 479        } else if (args->op == AMDGPU_GEM_METADATA_OP_SET_METADATA) {
 480                if (args->data.data_size_bytes > sizeof(args->data.data)) {
 481                        r = -EINVAL;
 482                        goto unreserve;
 483                }
 484                r = amdgpu_bo_set_tiling_flags(robj, args->data.tiling_info);
 485                if (!r)
 486                        r = amdgpu_bo_set_metadata(robj, args->data.data,
 487                                                   args->data.data_size_bytes,
 488                                                   args->data.flags);
 489        }
 490
 491unreserve:
 492        amdgpu_bo_unreserve(robj);
 493out:
 494        drm_gem_object_put_unlocked(gobj);
 495        return r;
 496}
 497
 498/**
 499 * amdgpu_gem_va_update_vm -update the bo_va in its VM
 500 *
 501 * @adev: amdgpu_device pointer
 502 * @vm: vm to update
 503 * @bo_va: bo_va to update
 504 * @operation: map, unmap or clear
 505 *
 506 * Update the bo_va directly after setting its address. Errors are not
 507 * vital here, so they are not reported back to userspace.
 508 */
 509static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev,
 510                                    struct amdgpu_vm *vm,
 511                                    struct amdgpu_bo_va *bo_va,
 512                                    uint32_t operation)
 513{
 514        int r;
 515
 516        if (!amdgpu_vm_ready(vm))
 517                return;
 518
 519        r = amdgpu_vm_clear_freed(adev, vm, NULL);
 520        if (r)
 521                goto error;
 522
 523        if (operation == AMDGPU_VA_OP_MAP ||
 524            operation == AMDGPU_VA_OP_REPLACE) {
 525                r = amdgpu_vm_bo_update(adev, bo_va, false);
 526                if (r)
 527                        goto error;
 528        }
 529
 530        r = amdgpu_vm_update_directories(adev, vm);
 531
 532error:
 533        if (r && r != -ERESTARTSYS)
 534                DRM_ERROR("Couldn't update BO_VA (%d)\n", r);
 535}
 536
 537int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
 538                          struct drm_file *filp)
 539{
 540        const uint32_t valid_flags = AMDGPU_VM_DELAY_UPDATE |
 541                AMDGPU_VM_PAGE_READABLE | AMDGPU_VM_PAGE_WRITEABLE |
 542                AMDGPU_VM_PAGE_EXECUTABLE | AMDGPU_VM_MTYPE_MASK;
 543        const uint32_t prt_flags = AMDGPU_VM_DELAY_UPDATE |
 544                AMDGPU_VM_PAGE_PRT;
 545
 546        struct drm_amdgpu_gem_va *args = data;
 547        struct drm_gem_object *gobj;
 548        struct amdgpu_device *adev = dev->dev_private;
 549        struct amdgpu_fpriv *fpriv = filp->driver_priv;
 550        struct amdgpu_bo *abo;
 551        struct amdgpu_bo_va *bo_va;
 552        struct amdgpu_bo_list_entry vm_pd;
 553        struct ttm_validate_buffer tv;
 554        struct ww_acquire_ctx ticket;
 555        struct list_head list, duplicates;
 556        uint64_t va_flags;
 557        int r = 0;
 558
 559        if (args->va_address < AMDGPU_VA_RESERVED_SIZE) {
 560                dev_dbg(&dev->pdev->dev,
 561                        "va_address 0x%LX is in reserved area 0x%LX\n",
 562                        args->va_address, AMDGPU_VA_RESERVED_SIZE);
 563                return -EINVAL;
 564        }
 565
 566        if (args->va_address >= AMDGPU_GMC_HOLE_START &&
 567            args->va_address < AMDGPU_GMC_HOLE_END) {
 568                dev_dbg(&dev->pdev->dev,
 569                        "va_address 0x%LX is in VA hole 0x%LX-0x%LX\n",
 570                        args->va_address, AMDGPU_GMC_HOLE_START,
 571                        AMDGPU_GMC_HOLE_END);
 572                return -EINVAL;
 573        }
 574
 575        args->va_address &= AMDGPU_GMC_HOLE_MASK;
 576
 577        if ((args->flags & ~valid_flags) && (args->flags & ~prt_flags)) {
 578                dev_dbg(&dev->pdev->dev, "invalid flags combination 0x%08X\n",
 579                        args->flags);
 580                return -EINVAL;
 581        }
 582
 583        switch (args->operation) {
 584        case AMDGPU_VA_OP_MAP:
 585        case AMDGPU_VA_OP_UNMAP:
 586        case AMDGPU_VA_OP_CLEAR:
 587        case AMDGPU_VA_OP_REPLACE:
 588                break;
 589        default:
 590                dev_dbg(&dev->pdev->dev, "unsupported operation %d\n",
 591                        args->operation);
 592                return -EINVAL;
 593        }
 594
 595        INIT_LIST_HEAD(&list);
 596        INIT_LIST_HEAD(&duplicates);
 597        if ((args->operation != AMDGPU_VA_OP_CLEAR) &&
 598            !(args->flags & AMDGPU_VM_PAGE_PRT)) {
 599                gobj = drm_gem_object_lookup(filp, args->handle);
 600                if (gobj == NULL)
 601                        return -ENOENT;
 602                abo = gem_to_amdgpu_bo(gobj);
 603                tv.bo = &abo->tbo;
 604                if (abo->flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID)
 605                        tv.num_shared = 1;
 606                else
 607                        tv.num_shared = 0;
 608                list_add(&tv.head, &list);
 609        } else {
 610                gobj = NULL;
 611                abo = NULL;
 612        }
 613
 614        amdgpu_vm_get_pd_bo(&fpriv->vm, &list, &vm_pd);
 615
 616        r = ttm_eu_reserve_buffers(&ticket, &list, true, &duplicates, false);
 617        if (r)
 618                goto error_unref;
 619
 620        if (abo) {
 621                bo_va = amdgpu_vm_bo_find(&fpriv->vm, abo);
 622                if (!bo_va) {
 623                        r = -ENOENT;
 624                        goto error_backoff;
 625                }
 626        } else if (args->operation != AMDGPU_VA_OP_CLEAR) {
 627                bo_va = fpriv->prt_va;
 628        } else {
 629                bo_va = NULL;
 630        }
 631
 632        switch (args->operation) {
 633        case AMDGPU_VA_OP_MAP:
 634                va_flags = amdgpu_gmc_get_pte_flags(adev, args->flags);
 635                r = amdgpu_vm_bo_map(adev, bo_va, args->va_address,
 636                                     args->offset_in_bo, args->map_size,
 637                                     va_flags);
 638                break;
 639        case AMDGPU_VA_OP_UNMAP:
 640                r = amdgpu_vm_bo_unmap(adev, bo_va, args->va_address);
 641                break;
 642
 643        case AMDGPU_VA_OP_CLEAR:
 644                r = amdgpu_vm_bo_clear_mappings(adev, &fpriv->vm,
 645                                                args->va_address,
 646                                                args->map_size);
 647                break;
 648        case AMDGPU_VA_OP_REPLACE:
 649                va_flags = amdgpu_gmc_get_pte_flags(adev, args->flags);
 650                r = amdgpu_vm_bo_replace_map(adev, bo_va, args->va_address,
 651                                             args->offset_in_bo, args->map_size,
 652                                             va_flags);
 653                break;
 654        default:
 655                break;
 656        }
 657        if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE) && !amdgpu_vm_debug)
 658                amdgpu_gem_va_update_vm(adev, &fpriv->vm, bo_va,
 659                                        args->operation);
 660
 661error_backoff:
 662        ttm_eu_backoff_reservation(&ticket, &list);
 663
 664error_unref:
 665        drm_gem_object_put_unlocked(gobj);
 666        return r;
 667}
 668
 669int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data,
 670                        struct drm_file *filp)
 671{
 672        struct amdgpu_device *adev = dev->dev_private;
 673        struct drm_amdgpu_gem_op *args = data;
 674        struct drm_gem_object *gobj;
 675        struct amdgpu_vm_bo_base *base;
 676        struct amdgpu_bo *robj;
 677        int r;
 678
 679        gobj = drm_gem_object_lookup(filp, args->handle);
 680        if (gobj == NULL) {
 681                return -ENOENT;
 682        }
 683        robj = gem_to_amdgpu_bo(gobj);
 684
 685        r = amdgpu_bo_reserve(robj, false);
 686        if (unlikely(r))
 687                goto out;
 688
 689        switch (args->op) {
 690        case AMDGPU_GEM_OP_GET_GEM_CREATE_INFO: {
 691                struct drm_amdgpu_gem_create_in info;
 692                void __user *out = u64_to_user_ptr(args->value);
 693
 694                info.bo_size = robj->tbo.base.size;
 695                info.alignment = robj->tbo.mem.page_alignment << PAGE_SHIFT;
 696                info.domains = robj->preferred_domains;
 697                info.domain_flags = robj->flags;
 698                amdgpu_bo_unreserve(robj);
 699                if (copy_to_user(out, &info, sizeof(info)))
 700                        r = -EFAULT;
 701                break;
 702        }
 703        case AMDGPU_GEM_OP_SET_PLACEMENT:
 704                if (robj->prime_shared_count && (args->value & AMDGPU_GEM_DOMAIN_VRAM)) {
 705                        r = -EINVAL;
 706                        amdgpu_bo_unreserve(robj);
 707                        break;
 708                }
 709                if (amdgpu_ttm_tt_get_usermm(robj->tbo.ttm)) {
 710                        r = -EPERM;
 711                        amdgpu_bo_unreserve(robj);
 712                        break;
 713                }
 714                for (base = robj->vm_bo; base; base = base->next)
 715                        if (amdgpu_xgmi_same_hive(amdgpu_ttm_adev(robj->tbo.bdev),
 716                                amdgpu_ttm_adev(base->vm->root.base.bo->tbo.bdev))) {
 717                                r = -EINVAL;
 718                                amdgpu_bo_unreserve(robj);
 719                                goto out;
 720                        }
 721
 722
 723                robj->preferred_domains = args->value & (AMDGPU_GEM_DOMAIN_VRAM |
 724                                                        AMDGPU_GEM_DOMAIN_GTT |
 725                                                        AMDGPU_GEM_DOMAIN_CPU);
 726                robj->allowed_domains = robj->preferred_domains;
 727                if (robj->allowed_domains == AMDGPU_GEM_DOMAIN_VRAM)
 728                        robj->allowed_domains |= AMDGPU_GEM_DOMAIN_GTT;
 729
 730                if (robj->flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID)
 731                        amdgpu_vm_bo_invalidate(adev, robj, true);
 732
 733                amdgpu_bo_unreserve(robj);
 734                break;
 735        default:
 736                amdgpu_bo_unreserve(robj);
 737                r = -EINVAL;
 738        }
 739
 740out:
 741        drm_gem_object_put_unlocked(gobj);
 742        return r;
 743}
 744
 745int amdgpu_mode_dumb_create(struct drm_file *file_priv,
 746                            struct drm_device *dev,
 747                            struct drm_mode_create_dumb *args)
 748{
 749        struct amdgpu_device *adev = dev->dev_private;
 750        struct drm_gem_object *gobj;
 751        uint32_t handle;
 752        u64 flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
 753                    AMDGPU_GEM_CREATE_CPU_GTT_USWC;
 754        u32 domain;
 755        int r;
 756
 757        /*
 758         * The buffer returned from this function should be cleared, but
 759         * it can only be done if the ring is enabled or we'll fail to
 760         * create the buffer.
 761         */
 762        if (adev->mman.buffer_funcs_enabled)
 763                flags |= AMDGPU_GEM_CREATE_VRAM_CLEARED;
 764
 765        args->pitch = amdgpu_align_pitch(adev, args->width,
 766                                         DIV_ROUND_UP(args->bpp, 8), 0);
 767        args->size = (u64)args->pitch * args->height;
 768        args->size = ALIGN(args->size, PAGE_SIZE);
 769        domain = amdgpu_bo_get_preferred_pin_domain(adev,
 770                                amdgpu_display_supported_domains(adev, flags));
 771        r = amdgpu_gem_object_create(adev, args->size, 0, domain, flags,
 772                                     ttm_bo_type_device, NULL, &gobj);
 773        if (r)
 774                return -ENOMEM;
 775
 776        r = drm_gem_handle_create(file_priv, gobj, &handle);
 777        /* drop reference from allocate - handle holds it now */
 778        drm_gem_object_put_unlocked(gobj);
 779        if (r) {
 780                return r;
 781        }
 782        args->handle = handle;
 783        return 0;
 784}
 785
 786#if defined(CONFIG_DEBUG_FS)
 787
 788#define amdgpu_debugfs_gem_bo_print_flag(m, bo, flag)   \
 789        if (bo->flags & (AMDGPU_GEM_CREATE_ ## flag)) { \
 790                seq_printf((m), " " #flag);             \
 791        }
 792
 793static int amdgpu_debugfs_gem_bo_info(int id, void *ptr, void *data)
 794{
 795        struct drm_gem_object *gobj = ptr;
 796        struct amdgpu_bo *bo = gem_to_amdgpu_bo(gobj);
 797        struct seq_file *m = data;
 798
 799        struct dma_buf_attachment *attachment;
 800        struct dma_buf *dma_buf;
 801        unsigned domain;
 802        const char *placement;
 803        unsigned pin_count;
 804
 805        domain = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type);
 806        switch (domain) {
 807        case AMDGPU_GEM_DOMAIN_VRAM:
 808                placement = "VRAM";
 809                break;
 810        case AMDGPU_GEM_DOMAIN_GTT:
 811                placement = " GTT";
 812                break;
 813        case AMDGPU_GEM_DOMAIN_CPU:
 814        default:
 815                placement = " CPU";
 816                break;
 817        }
 818        seq_printf(m, "\t0x%08x: %12ld byte %s",
 819                   id, amdgpu_bo_size(bo), placement);
 820
 821        pin_count = READ_ONCE(bo->pin_count);
 822        if (pin_count)
 823                seq_printf(m, " pin count %d", pin_count);
 824
 825        dma_buf = READ_ONCE(bo->tbo.base.dma_buf);
 826        attachment = READ_ONCE(bo->tbo.base.import_attach);
 827
 828        if (attachment)
 829                seq_printf(m, " imported from %p", dma_buf);
 830        else if (dma_buf)
 831                seq_printf(m, " exported as %p", dma_buf);
 832
 833        amdgpu_debugfs_gem_bo_print_flag(m, bo, CPU_ACCESS_REQUIRED);
 834        amdgpu_debugfs_gem_bo_print_flag(m, bo, NO_CPU_ACCESS);
 835        amdgpu_debugfs_gem_bo_print_flag(m, bo, CPU_GTT_USWC);
 836        amdgpu_debugfs_gem_bo_print_flag(m, bo, VRAM_CLEARED);
 837        amdgpu_debugfs_gem_bo_print_flag(m, bo, SHADOW);
 838        amdgpu_debugfs_gem_bo_print_flag(m, bo, VRAM_CONTIGUOUS);
 839        amdgpu_debugfs_gem_bo_print_flag(m, bo, VM_ALWAYS_VALID);
 840        amdgpu_debugfs_gem_bo_print_flag(m, bo, EXPLICIT_SYNC);
 841
 842        seq_printf(m, "\n");
 843
 844        return 0;
 845}
 846
 847static int amdgpu_debugfs_gem_info(struct seq_file *m, void *data)
 848{
 849        struct drm_info_node *node = (struct drm_info_node *)m->private;
 850        struct drm_device *dev = node->minor->dev;
 851        struct drm_file *file;
 852        int r;
 853
 854        r = mutex_lock_interruptible(&dev->filelist_mutex);
 855        if (r)
 856                return r;
 857
 858        list_for_each_entry(file, &dev->filelist, lhead) {
 859                struct task_struct *task;
 860
 861                /*
 862                 * Although we have a valid reference on file->pid, that does
 863                 * not guarantee that the task_struct who called get_pid() is
 864                 * still alive (e.g. get_pid(current) => fork() => exit()).
 865                 * Therefore, we need to protect this ->comm access using RCU.
 866                 */
 867                rcu_read_lock();
 868                task = pid_task(file->pid, PIDTYPE_PID);
 869                seq_printf(m, "pid %8d command %s:\n", pid_nr(file->pid),
 870                           task ? task->comm : "<unknown>");
 871                rcu_read_unlock();
 872
 873                spin_lock(&file->table_lock);
 874                idr_for_each(&file->object_idr, amdgpu_debugfs_gem_bo_info, m);
 875                spin_unlock(&file->table_lock);
 876        }
 877
 878        mutex_unlock(&dev->filelist_mutex);
 879        return 0;
 880}
 881
 882static const struct drm_info_list amdgpu_debugfs_gem_list[] = {
 883        {"amdgpu_gem_info", &amdgpu_debugfs_gem_info, 0, NULL},
 884};
 885#endif
 886
 887int amdgpu_debugfs_gem_init(struct amdgpu_device *adev)
 888{
 889#if defined(CONFIG_DEBUG_FS)
 890        return amdgpu_debugfs_add_files(adev, amdgpu_debugfs_gem_list, 1);
 891#endif
 892        return 0;
 893}
 894