From 71df0368e9b66afeb1fdb92a88be1a98cc25f310 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 25 May 2021 17:10:50 +0200 Subject: drm/amdgpu: Implement mmap as GEM object function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Moving the driver-specific mmap code into a GEM object function allows for using DRM helpers for various mmap callbacks. This change resolves several inconsistencies between regular mmap and prime-based mmap. The vm_ops field in vma is now set for all mmap'ed areas. Previously it way only set for regular mmap calls, prime-based mmap used TTM's default vm_ops. The function amdgpu_verify_access() is no longer being called and therefore removed by this patch. As a side effect, amdgpu_ttm_vm_ops and amdgpu_ttm_fault() are now implemented in amdgpu's GEM code. v4: * rebased v3: * rename mmap function to amdgpu_gem_object_mmap() (Christian) * remove unnecessary checks from mmap (Christian) v2: * rename amdgpu_ttm_vm_ops and amdgpu_ttm_fault() to amdgpu_gem_vm_ops and amdgpu_gem_fault() (Christian) * the check for kfd_bo has meanwhile been removed Signed-off-by: Thomas Zimmermann Reviewed-by: Christian König Link: https://patchwork.freedesktop.org/patch/msgid/20210525151055.8174-3-tzimmermann@suse.de --- drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 55 +++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index 18974bd081f0..73c76a3e2b12 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -32,6 +32,7 @@ #include #include +#include #include #include "amdgpu.h" @@ -41,6 +42,46 @@ static const struct drm_gem_object_funcs amdgpu_gem_object_funcs; +static vm_fault_t amdgpu_gem_fault(struct vm_fault *vmf) +{ + struct ttm_buffer_object *bo = vmf->vma->vm_private_data; + struct drm_device *ddev = bo->base.dev; + vm_fault_t ret; + int idx; + + ret = ttm_bo_vm_reserve(bo, vmf); + if (ret) + return ret; + + if (drm_dev_enter(ddev, &idx)) { + ret = amdgpu_bo_fault_reserve_notify(bo); + if (ret) { + drm_dev_exit(idx); + goto unlock; + } + + ret = ttm_bo_vm_fault_reserved(vmf, vmf->vma->vm_page_prot, + TTM_BO_VM_NUM_PREFAULT, 1); + + drm_dev_exit(idx); + } else { + ret = ttm_bo_vm_dummy_page(vmf, vmf->vma->vm_page_prot); + } + if (ret == VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) + return ret; + +unlock: + dma_resv_unlock(bo->base.resv); + return ret; +} + +static const struct vm_operations_struct amdgpu_gem_vm_ops = { + .fault = amdgpu_gem_fault, + .open = ttm_bo_vm_open, + .close = ttm_bo_vm_close, + .access = ttm_bo_vm_access +}; + static void amdgpu_gem_object_free(struct drm_gem_object *gobj) { struct amdgpu_bo *robj = gem_to_amdgpu_bo(gobj); @@ -205,6 +246,18 @@ out_unlock: ttm_eu_backoff_reservation(&ticket, &list); } +static int amdgpu_gem_object_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) +{ + struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); + + if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm)) + return -EPERM; + if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) + return -EPERM; + + return drm_gem_ttm_mmap(obj, vma); +} + static const struct drm_gem_object_funcs amdgpu_gem_object_funcs = { .free = amdgpu_gem_object_free, .open = amdgpu_gem_object_open, @@ -212,6 +265,8 @@ static const struct drm_gem_object_funcs amdgpu_gem_object_funcs = { .export = amdgpu_gem_prime_export, .vmap = drm_gem_ttm_vmap, .vunmap = drm_gem_ttm_vunmap, + .mmap = amdgpu_gem_object_mmap, + .vm_ops = &amdgpu_gem_vm_ops, }; /* -- cgit v1.2.3