[PATCH] dmabuf mmap forward

Tvrtko Ursulin tvrtko.ursulin at linux.intel.com
Fri Aug 4 12:03:06 UTC 2023


From: Tvrtko Ursulin <tvrtko.ursulin at intel.com>

Test-with: 20230804120116.2392098-1-tvrtko.ursulin at linux.intel.com

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c      | 60 ++++++++++++++++++-
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  1 +
 2 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 9aa6ecf68432..48ab6351cca4 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -5,6 +5,7 @@
  */
 
 #include <linux/anon_inodes.h>
+#include <linux/dma-buf.h>
 #include <linux/mman.h>
 #include <linux/pfn_t.h>
 #include <linux/sizes.h>
@@ -656,6 +657,7 @@ insert_mmo(struct drm_i915_gem_object *obj, struct i915_mmap_offset *mmo)
 static struct i915_mmap_offset *
 mmap_offset_attach(struct drm_i915_gem_object *obj,
 		   enum i915_mmap_type mmap_type,
+		   bool forward_mmap,
 		   struct drm_file *file)
 {
 	struct drm_i915_private *i915 = to_i915(obj->base.dev);
@@ -674,6 +676,7 @@ mmap_offset_attach(struct drm_i915_gem_object *obj,
 
 	mmo->obj = obj;
 	mmo->mmap_type = mmap_type;
+	mmo->forward_mmap = forward_mmap;
 	drm_vma_node_reset(&mmo->vma_node);
 
 	err = drm_vma_offset_add(obj->base.dev->vma_offset_manager,
@@ -706,12 +709,25 @@ mmap_offset_attach(struct drm_i915_gem_object *obj,
 	return ERR_PTR(err);
 }
 
+static bool
+should_forward_mmap(struct drm_i915_gem_object *obj,
+		    enum i915_mmap_type mmap_type)
+{
+	if (!obj->base.import_attach)
+		return false;
+
+	return mmap_type == I915_MMAP_TYPE_WB ||
+	       mmap_type == I915_MMAP_TYPE_WC ||
+	       mmap_type == I915_MMAP_TYPE_UC;
+}
+
 static int
 __assign_mmap_offset(struct drm_i915_gem_object *obj,
 		     enum i915_mmap_type mmap_type,
 		     u64 *offset, struct drm_file *file)
 {
 	struct i915_mmap_offset *mmo;
+	bool should_forward;
 
 	if (i915_gem_object_never_mmap(obj))
 		return -ENODEV;
@@ -727,12 +743,15 @@ __assign_mmap_offset(struct drm_i915_gem_object *obj,
 	if (mmap_type == I915_MMAP_TYPE_FIXED)
 		return -ENODEV;
 
+	should_forward = should_forward_mmap(obj, mmap_type);
+
 	if (mmap_type != I915_MMAP_TYPE_GTT &&
 	    !i915_gem_object_has_struct_page(obj) &&
-	    !i915_gem_object_has_iomem(obj))
+	    !i915_gem_object_has_iomem(obj) &&
+	    !should_forward)
 		return -ENODEV;
 
-	mmo = mmap_offset_attach(obj, mmap_type, file);
+	mmo = mmap_offset_attach(obj, mmap_type, should_forward, file);
 	if (IS_ERR(mmo))
 		return PTR_ERR(mmo);
 
@@ -945,6 +964,41 @@ i915_gem_object_mmap(struct drm_i915_gem_object *obj,
 		vm_flags_clear(vma, VM_MAYWRITE);
 	}
 
+	/* dma-buf import */
+	if (mmo && mmo->forward_mmap) {
+
+		switch (mmo->mmap_type) {
+		case I915_MMAP_TYPE_WC:
+			vma->vm_page_prot =
+				pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+			break;
+		case I915_MMAP_TYPE_UC:
+			vma->vm_page_prot =
+				pgprot_noncached(vm_get_page_prot(vma->vm_flags));
+			break;
+		case I915_MMAP_TYPE_GTT:
+		case I915_MMAP_TYPE_FIXED:
+		default:
+			drm_err_once(&i915->drm, "Unhandled mmap type %u",
+				     mmo->mmap_type);
+			fallthrough;
+		case I915_MMAP_TYPE_WB:
+			vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+			break;
+		}
+		vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
+
+		vm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP | VM_IO);
+
+		/*
+		 * Don't have our vm_ops to drop the reference in this case so
+		 * drop it now and if object goes away userspace will fault.
+		 */
+		i915_gem_object_put(mmo->obj);
+
+		return dma_buf_mmap(obj->base.dma_buf, vma, 0);
+	}
+
 	anon = mmap_singleton(to_i915(dev));
 	if (IS_ERR(anon)) {
 		i915_gem_object_put(obj);
@@ -1076,7 +1130,7 @@ int i915_gem_fb_mmap(struct drm_i915_gem_object *obj, struct vm_area_struct *vma
 	} else {
 		/* handle stolen and smem objects */
 		mmap_type = i915_ggtt_has_aperture(ggtt) ? I915_MMAP_TYPE_GTT : I915_MMAP_TYPE_WC;
-		mmo = mmap_offset_attach(obj, mmap_type, NULL);
+		mmo = mmap_offset_attach(obj, mmap_type, false, NULL);
 		if (IS_ERR(mmo))
 			return PTR_ERR(mmo);
 	}
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
index 6790e13ad262..39feec2881d2 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -137,6 +137,7 @@ struct i915_mmap_offset {
 	struct drm_vma_offset_node vma_node;
 	struct drm_i915_gem_object *obj;
 	enum i915_mmap_type mmap_type;
+	bool forward_mmap;
 
 	struct rb_node offset;
 };
-- 
2.39.2


More information about the Intel-gfx-trybot mailing list