[PATCH] drm/amdgpu: Implement mmap of imported dma-bufs

From: Marek Maslanka
Date: Fri Mar 03 2023 - 06:10:30 EST


Use dmabuf mmap from exporting driver to do the mapping.

Signed-off-by: Marek Maslanka <mmaslanka@xxxxxxxxxxxx>
Signed-off-by: Dominik Behr <dbehr@xxxxxxxxxxxx>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 46 +++++++++++++++++++++
drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.h | 2 +
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 9 ++++
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h | 1 +
5 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
index 0c001bb8fc2b..8f22d29ba077 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
@@ -37,6 +37,7 @@
#include "amdgpu_dma_buf.h"
#include "amdgpu_xgmi.h"
#include <drm/amdgpu_drm.h>
+#include <drm/drm_drv.h>
#include <drm/ttm/ttm_tt.h>
#include <linux/dma-buf.h>
#include <linux/dma-fence-array.h>
@@ -275,6 +276,51 @@ const struct dma_buf_ops amdgpu_dmabuf_ops = {
.vunmap = drm_gem_dmabuf_vunmap,
};

+int amdgpu_try_dma_buf_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ struct drm_file *priv = filp->private_data;
+ struct drm_device *dev = priv->minor->dev;
+ struct amdgpu_device *adev = drm_to_adev(dev);
+ struct ttm_device *bdev = &adev->mman.bdev;
+ struct ttm_buffer_object *tbo = NULL;
+ struct amdgpu_bo *bo = NULL;
+ struct drm_gem_object *obj = NULL;
+ struct drm_vma_offset_node *node;
+ int ret;
+
+ if (drm_dev_is_unplugged(dev))
+ return -ENODEV;
+
+ drm_vma_offset_lock_lookup(bdev->vma_manager);
+ node = drm_vma_offset_exact_lookup_locked(bdev->vma_manager,
+ vma->vm_pgoff,
+ vma_pages(vma));
+
+ if (likely(node)) {
+ tbo = container_of(node, struct ttm_buffer_object,
+ base.vma_node);
+ tbo = ttm_bo_get_unless_zero(tbo);
+ }
+ drm_vma_offset_unlock_lookup(bdev->vma_manager);
+
+ if (!tbo)
+ return -EINVAL;
+
+ bo = ttm_to_amdgpu_bo(tbo);
+ obj = &tbo->base;
+
+ if (!obj->import_attach) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ret = dma_buf_mmap(obj->import_attach->dmabuf, vma, 0);
+
+done:
+ ttm_bo_put(tbo);
+ return ret;
+}
+
/**
* amdgpu_gem_prime_export - &drm_driver.gem_prime_export implementation
* @gobj: GEM BO
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.h
index 3e93b9b407a9..ecf1dc32eec4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.h
@@ -25,6 +25,8 @@

#include <drm/drm_gem.h>

+int amdgpu_try_dma_buf_mmap(struct file *filp, struct vm_area_struct *vma);
+
struct dma_buf *amdgpu_gem_prime_export(struct drm_gem_object *gobj,
int flags);
struct drm_gem_object *amdgpu_gem_prime_import(struct drm_device *dev,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 86fbb4138285..91e94342d48e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -2737,7 +2737,7 @@ static const struct file_operations amdgpu_driver_kms_fops = {
.flush = amdgpu_flush,
.release = drm_release,
.unlocked_ioctl = amdgpu_drm_ioctl,
- .mmap = drm_gem_mmap,
+ .mmap = amdgpu_mmap,
.poll = drm_poll,
.read = drm_read,
#ifdef CONFIG_COMPAT
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index c5ef7f7bdc15..41944439cd6c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -61,6 +61,7 @@
#include "amdgpu_hmm.h"
#include "amdgpu_atomfirmware.h"
#include "amdgpu_res_cursor.h"
+#include "amdgpu_dma_buf.h"
#include "bif/bif_4_1_d.h"

MODULE_IMPORT_NS(DMA_BUF);
@@ -1994,6 +1995,14 @@ static int amdgpu_ttm_prepare_job(struct amdgpu_device *adev,
DMA_RESV_USAGE_BOOKKEEP);
}

+int amdgpu_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ if (amdgpu_try_dma_buf_mmap(filp, vma) == 0)
+ return 0;
+
+ return drm_gem_mmap(filp, vma);
+}
+
int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
uint64_t dst_offset, uint32_t byte_count,
struct dma_resv *resv,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
index e2cd5894afc9..e4cd1bda7a2b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
@@ -152,6 +152,7 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo,
struct dma_resv *resv,
struct dma_fence **fence);

+int amdgpu_mmap(struct file *filp, struct vm_area_struct *vma);
int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo);
void amdgpu_ttm_recover_gart(struct ttm_buffer_object *tbo);
uint64_t amdgpu_ttm_domain_start(struct amdgpu_device *adev, uint32_t type);
--
2.40.0.rc0.216.gc4246ad0f0-goog