drm/amdgpu: Initialise drm_gem_object_funcs for imported BOs
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_gem.c
index aa7f230..cc12ac6 100644 (file)
 
 #include "amdgpu.h"
 #include "amdgpu_display.h"
+#include "amdgpu_dma_buf.h"
 #include "amdgpu_xgmi.h"
 
-void amdgpu_gem_object_free(struct drm_gem_object *gobj)
+static const struct drm_gem_object_funcs amdgpu_gem_object_funcs;
+
+static void amdgpu_gem_object_free(struct drm_gem_object *gobj)
 {
        struct amdgpu_bo *robj = gem_to_amdgpu_bo(gobj);
 
@@ -66,27 +69,14 @@ int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size,
        bp.type = type;
        bp.resv = resv;
        bp.preferred_domain = initial_domain;
-retry:
        bp.flags = flags;
        bp.domain = initial_domain;
        r = amdgpu_bo_create(adev, &bp, &bo);
-       if (r) {
-               if (r != -ERESTARTSYS) {
-                       if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) {
-                               flags &= ~AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
-                               goto retry;
-                       }
-
-                       if (initial_domain == AMDGPU_GEM_DOMAIN_VRAM) {
-                               initial_domain |= AMDGPU_GEM_DOMAIN_GTT;
-                               goto retry;
-                       }
-                       DRM_DEBUG("Failed to allocate GEM object (%ld, %d, %u, %d)\n",
-                                 size, initial_domain, alignment, r);
-               }
+       if (r)
                return r;
-       }
+
        *obj = &bo->tbo.base;
+       (*obj)->funcs = &amdgpu_gem_object_funcs;
 
        return 0;
 }
@@ -119,8 +109,8 @@ void amdgpu_gem_force_release(struct amdgpu_device *adev)
  * Call from drm_gem_handle_create which appear in both new and open ioctl
  * case.
  */
-int amdgpu_gem_object_open(struct drm_gem_object *obj,
-                          struct drm_file *file_priv)
+static int amdgpu_gem_object_open(struct drm_gem_object *obj,
+                                 struct drm_file *file_priv)
 {
        struct amdgpu_bo *abo = gem_to_amdgpu_bo(obj);
        struct amdgpu_device *adev = amdgpu_ttm_adev(abo->tbo.bdev);
@@ -152,8 +142,8 @@ int amdgpu_gem_object_open(struct drm_gem_object *obj,
        return 0;
 }
 
-void amdgpu_gem_object_close(struct drm_gem_object *obj,
-                            struct drm_file *file_priv)
+static void amdgpu_gem_object_close(struct drm_gem_object *obj,
+                                   struct drm_file *file_priv)
 {
        struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
        struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
@@ -211,6 +201,15 @@ out_unlock:
        ttm_eu_backoff_reservation(&ticket, &list);
 }
 
+static const struct drm_gem_object_funcs amdgpu_gem_object_funcs = {
+       .free = amdgpu_gem_object_free,
+       .open = amdgpu_gem_object_open,
+       .close = amdgpu_gem_object_close,
+       .export = amdgpu_gem_prime_export,
+       .vmap = amdgpu_gem_prime_vmap,
+       .vunmap = amdgpu_gem_prime_vunmap,
+};
+
 /*
  * GEM ioctls.
  */
@@ -225,7 +224,7 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
        uint64_t size = args->in.bo_size;
        struct dma_resv *resv = NULL;
        struct drm_gem_object *gobj;
-       uint32_t handle;
+       uint32_t handle, initial_domain;
        int r;
 
        /* reject invalid gem flags */
@@ -269,9 +268,28 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
                resv = vm->root.base.bo->tbo.base.resv;
        }
 
+retry:
+       initial_domain = (u32)(0xffffffff & args->in.domains);
        r = amdgpu_gem_object_create(adev, size, args->in.alignment,
-                                    (u32)(0xffffffff & args->in.domains),
+                                    initial_domain,
                                     flags, ttm_bo_type_device, resv, &gobj);
+       if (r) {
+               if (r != -ERESTARTSYS) {
+                       if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) {
+                               flags &= ~AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
+                               goto retry;
+                       }
+
+                       if (initial_domain == AMDGPU_GEM_DOMAIN_VRAM) {
+                               initial_domain |= AMDGPU_GEM_DOMAIN_GTT;
+                               goto retry;
+                       }
+                       DRM_DEBUG("Failed to allocate GEM object (%llu, %d, %llu, %d)\n",
+                                 size, initial_domain, args->in.alignment, r);
+               }
+               return r;
+       }
+
        if (flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID) {
                if (!r) {
                        struct amdgpu_bo *abo = gem_to_amdgpu_bo(gobj);
@@ -596,6 +614,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
        struct ww_acquire_ctx ticket;
        struct list_head list, duplicates;
        uint64_t va_flags;
+       uint64_t vm_size;
        int r = 0;
 
        if (args->va_address < AMDGPU_VA_RESERVED_SIZE) {
@@ -616,6 +635,15 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
 
        args->va_address &= AMDGPU_GMC_HOLE_MASK;
 
+       vm_size = adev->vm_manager.max_pfn * AMDGPU_GPU_PAGE_SIZE;
+       vm_size -= AMDGPU_VA_RESERVED_SIZE;
+       if (args->va_address + args->map_size > vm_size) {
+               dev_dbg(&dev->pdev->dev,
+                       "va_address 0x%llx is in top reserved area 0x%llx\n",
+                       args->va_address + args->map_size, vm_size);
+               return -EINVAL;
+       }
+
        if ((args->flags & ~valid_flags) && (args->flags & ~prt_flags)) {
                dev_dbg(&dev->pdev->dev, "invalid flags combination 0x%08X\n",
                        args->flags);
@@ -826,67 +854,6 @@ int amdgpu_mode_dumb_create(struct drm_file *file_priv,
 }
 
 #if defined(CONFIG_DEBUG_FS)
-
-#define amdgpu_debugfs_gem_bo_print_flag(m, bo, flag)  \
-       if (bo->flags & (AMDGPU_GEM_CREATE_ ## flag)) { \
-               seq_printf((m), " " #flag);             \
-       }
-
-static int amdgpu_debugfs_gem_bo_info(int id, void *ptr, void *data)
-{
-       struct drm_gem_object *gobj = ptr;
-       struct amdgpu_bo *bo = gem_to_amdgpu_bo(gobj);
-       struct seq_file *m = data;
-
-       struct dma_buf_attachment *attachment;
-       struct dma_buf *dma_buf;
-       unsigned domain;
-       const char *placement;
-       unsigned pin_count;
-
-       domain = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type);
-       switch (domain) {
-       case AMDGPU_GEM_DOMAIN_VRAM:
-               placement = "VRAM";
-               break;
-       case AMDGPU_GEM_DOMAIN_GTT:
-               placement = " GTT";
-               break;
-       case AMDGPU_GEM_DOMAIN_CPU:
-       default:
-               placement = " CPU";
-               break;
-       }
-       seq_printf(m, "\t0x%08x: %12ld byte %s",
-                  id, amdgpu_bo_size(bo), placement);
-
-       pin_count = READ_ONCE(bo->pin_count);
-       if (pin_count)
-               seq_printf(m, " pin count %d", pin_count);
-
-       dma_buf = READ_ONCE(bo->tbo.base.dma_buf);
-       attachment = READ_ONCE(bo->tbo.base.import_attach);
-
-       if (attachment)
-               seq_printf(m, " imported from %p%s", dma_buf,
-                          attachment->peer2peer ? " P2P" : "");
-       else if (dma_buf)
-               seq_printf(m, " exported as %p", dma_buf);
-
-       amdgpu_debugfs_gem_bo_print_flag(m, bo, CPU_ACCESS_REQUIRED);
-       amdgpu_debugfs_gem_bo_print_flag(m, bo, NO_CPU_ACCESS);
-       amdgpu_debugfs_gem_bo_print_flag(m, bo, CPU_GTT_USWC);
-       amdgpu_debugfs_gem_bo_print_flag(m, bo, VRAM_CLEARED);
-       amdgpu_debugfs_gem_bo_print_flag(m, bo, SHADOW);
-       amdgpu_debugfs_gem_bo_print_flag(m, bo, VRAM_CONTIGUOUS);
-       amdgpu_debugfs_gem_bo_print_flag(m, bo, VM_ALWAYS_VALID);
-       amdgpu_debugfs_gem_bo_print_flag(m, bo, EXPLICIT_SYNC);
-
-       seq_printf(m, "\n");
-
-       return 0;
-}
-
 static int amdgpu_debugfs_gem_info(struct seq_file *m, void *data)
 {
        struct drm_info_node *node = (struct drm_info_node *)m->private;
@@ -900,6 +867,8 @@ static int amdgpu_debugfs_gem_info(struct seq_file *m, void *data)
 
        list_for_each_entry(file, &dev->filelist, lhead) {
                struct task_struct *task;
+               struct drm_gem_object *gobj;
+               int id;
 
                /*
                 * Although we have a valid reference on file->pid, that does
@@ -914,7 +883,11 @@ static int amdgpu_debugfs_gem_info(struct seq_file *m, void *data)
                rcu_read_unlock();
 
                spin_lock(&file->table_lock);
-               idr_for_each(&file->object_idr, amdgpu_debugfs_gem_bo_info, m);
+               idr_for_each_entry(&file->object_idr, gobj, id) {
+                       struct amdgpu_bo *bo = gem_to_amdgpu_bo(gobj);
+
+                       amdgpu_bo_print_info(id, bo, m);
+               }
                spin_unlock(&file->table_lock);
        }