Merge branch 'address-masking'
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_gem.c
index 49a5f1c..0e617df 100644 (file)
@@ -108,6 +108,7 @@ int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size,
 
        memset(&bp, 0, sizeof(bp));
        *obj = NULL;
+       flags |= AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE;
 
        bp.size = size;
        bp.byte_align = alignment;
@@ -174,7 +175,7 @@ static int amdgpu_gem_object_open(struct drm_gem_object *obj,
                return -EPERM;
 
        if (abo->flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID &&
-           abo->tbo.base.resv != vm->root.bo->tbo.base.resv)
+           !amdgpu_vm_is_bo_always_valid(vm, abo))
                return -EPERM;
 
        r = amdgpu_bo_reserve(abo, false);
@@ -187,7 +188,40 @@ static int amdgpu_gem_object_open(struct drm_gem_object *obj,
        else
                ++bo_va->ref_count;
        amdgpu_bo_unreserve(abo);
-       return 0;
+
+       /* Validate and add eviction fence to DMABuf imports with dynamic
+        * attachment in compute VMs. Re-validation will be done by
+        * amdgpu_vm_validate. Fences are on the reservation shared with the
+        * export, which is currently required to be validated and fenced
+        * already by amdgpu_amdkfd_gpuvm_restore_process_bos.
+        *
+        * Nested locking below for the case that a GEM object is opened in
+        * kfd_mem_export_dmabuf. Since the lock below is only taken for imports,
+        * but not for export, this is a different lock class that cannot lead to
+        * circular lock dependencies.
+        */
+       if (!vm->is_compute_context || !vm->process_info)
+               return 0;
+       if (!obj->import_attach ||
+           !dma_buf_is_dynamic(obj->import_attach->dmabuf))
+               return 0;
+       mutex_lock_nested(&vm->process_info->lock, 1);
+       if (!WARN_ON(!vm->process_info->eviction_fence)) {
+               r = amdgpu_amdkfd_bo_validate_and_fence(abo, AMDGPU_GEM_DOMAIN_GTT,
+                                                       &vm->process_info->eviction_fence->base);
+               if (r) {
+                       struct amdgpu_task_info *ti = amdgpu_vm_get_task_info_vm(vm);
+
+                       dev_warn(adev->dev, "validate_and_fence failed: %d\n", r);
+                       if (ti) {
+                               dev_warn(adev->dev, "pid %d\n", ti->pid);
+                               amdgpu_vm_put_task_info(ti);
+                       }
+               }
+       }
+       mutex_unlock(&vm->process_info->lock);
+
+       return r;
 }
 
 static void amdgpu_gem_object_close(struct drm_gem_object *obj,
@@ -301,6 +335,7 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
                      AMDGPU_GEM_CREATE_VM_ALWAYS_VALID |
                      AMDGPU_GEM_CREATE_EXPLICIT_SYNC |
                      AMDGPU_GEM_CREATE_ENCRYPTED |
+                     AMDGPU_GEM_CREATE_GFX12_DCC |
                      AMDGPU_GEM_CREATE_DISCARDABLE))
                return -EINVAL;
 
@@ -313,6 +348,9 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
                return -EINVAL;
        }
 
+       /* always clear VRAM */
+       flags |= AMDGPU_GEM_CREATE_VRAM_CLEARED;
+
        /* create a gem object to contain this object in */
        if (args->in.domains & (AMDGPU_GEM_DOMAIN_GDS |
            AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA)) {
@@ -650,7 +688,7 @@ uint64_t amdgpu_gem_va_map_flags(struct amdgpu_device *adev, uint32_t flags)
        if (flags & AMDGPU_VM_PAGE_WRITEABLE)
                pte_flag |= AMDGPU_PTE_WRITEABLE;
        if (flags & AMDGPU_VM_PAGE_PRT)
-               pte_flag |= AMDGPU_PTE_PRT;
+               pte_flag |= AMDGPU_PTE_PRT_FLAG(adev);
        if (flags & AMDGPU_VM_PAGE_NOALLOC)
                pte_flag |= AMDGPU_PTE_NOALLOC;
 
@@ -682,10 +720,10 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
        uint64_t vm_size;
        int r = 0;
 
-       if (args->va_address < AMDGPU_VA_RESERVED_SIZE) {
+       if (args->va_address < AMDGPU_VA_RESERVED_BOTTOM) {
                dev_dbg(dev->dev,
                        "va_address 0x%llx is in reserved area 0x%llx\n",
-                       args->va_address, AMDGPU_VA_RESERVED_SIZE);
+                       args->va_address, AMDGPU_VA_RESERVED_BOTTOM);
                return -EINVAL;
        }
 
@@ -701,7 +739,7 @@ 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;
+       vm_size -= AMDGPU_VA_RESERVED_TOP;
        if (args->va_address + args->map_size > vm_size) {
                dev_dbg(dev->dev,
                        "va_address 0x%llx is in top reserved area 0x%llx\n",