diff mbox

[3/3] drm/gem: start adding support for per-file object mmaps

Message ID 1355892119-13926-4-git-send-email-airlied@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Dave Airlie Dec. 19, 2012, 4:41 a.m. UTC
From: Dave Airlie <airlied@redhat.com>

This adds the support for drivers that use the gem mmap call, they need
to specify DRIVER_GEM_MMAP in their feature set, so they get this behaviour.

This saves me adding 10 open/close handlers for now, if someone would like
to do that instead of midlayer, then I'd be happy to watch.

TODO: all other non-i915 drivers.

Signed-off-by: Dave Airlie <airlied@redhat.com>
---
 drivers/gpu/drm/drm_gem.c       | 17 +++++++++++++++++
 drivers/gpu/drm/i915/i915_drv.c |  2 +-
 include/drm/drmP.h              |  1 +
 3 files changed, 19 insertions(+), 1 deletion(-)

Comments

Chris Wilson Dec. 19, 2012, 9:47 a.m. UTC | #1
From: Chris Wilson <chris@chris-wilson.co.uk>
Subject: Re: [proof-of-concept/rfc] per object file mmaps
To: Dave Airlie <airlied@gmail.com>, dri-devel@lists.freedesktop.org
In-Reply-To: <1355892119-13926-1-git-send-email-airlied@gmail.com>
References: <1355892119-13926-1-git-send-email-airlied@gmail.com>

On Wed, 19 Dec 2012 14:41:56 +1000, Dave Airlie <airlied@gmail.com> wrote:
> The 2+3 patches are actually the code, the first was just a cleanup.
> 
> Anyways the second patch describes it best, but I've taken the approach
> that we just need to keep track of what filp this object has had a handle
> created on, and block mmaps on it. We could also probably block a bit
> more explicitly in the driver respective mmap offset retrieval ioctls,
> however we need to block in mmap itself to stop people just picking misc
> address and trying them.
> 
> It doesn't really add much now, but with render nodes where we have flink_to
> or fd passing it would be more useful.
> 
> I've no idea if I'll get to do much more with this, so consider it an
> indication of how I'd like it done for someone else to run with :-)

Locking looks entirely non-existent for per-file mmap add/remove in the
generic gem code. Also we have a pair of hooks there that look like they
would be a convenient point to place that code.
-Chris
diff mbox

Patch

diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index bb5ac23..dbbd736 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -240,6 +240,8 @@  drm_gem_handle_delete(struct drm_file *filp, u32 handle)
 
 	drm_gem_remove_prime_handles(obj, filp);
 
+	if (drm_core_check_feature(dev, DRIVER_GEM_MMAP))
+		drm_vma_offset_node_remove_file(&obj->vma_offset, filp->filp);
 	if (dev->driver->gem_close_object)
 		dev->driver->gem_close_object(obj, filp);
 	drm_gem_object_handle_unreference_unlocked(obj);
@@ -280,9 +282,19 @@  again:
 
 	drm_gem_object_handle_reference(obj);
 
+	if (drm_core_check_feature(dev, DRIVER_GEM_MMAP)) {
+		ret = drm_vma_offset_node_add_file(&obj->vma_offset,
+						   file_priv->filp);
+		if (ret) {
+			drm_gem_handle_delete(file_priv, *handlep);
+			return ret;
+		}
+	}
 	if (dev->driver->gem_open_object) {
 		ret = dev->driver->gem_open_object(obj, file_priv);
 		if (ret) {
+			if (drm_core_check_feature(dev, DRIVER_GEM_MMAP))
+				drm_vma_offset_node_remove_file(&obj->vma_offset, file_priv->filp);
 			drm_gem_handle_delete(file_priv, *handlep);
 			return ret;
 		}
@@ -633,6 +645,11 @@  int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
 		return drm_mmap(filp, vma);
 	}
 
+	if (drm_vma_offset_node_valid_file(offset_node, filp) == false) {
+		ret = -EINVAL;
+		goto out_unlock;
+	}
+
 	obj = container_of(offset_node, struct drm_gem_object, vma_offset);
 
 	/* Check for valid size. */
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 530db83..a42cb8f 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1017,7 +1017,7 @@  static struct drm_driver driver = {
 	 */
 	.driver_features =
 	    DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/
-	    DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | DRIVER_PRIME,
+	    DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | DRIVER_PRIME | DRIVER_GEM_MMAP,
 	.load = i915_driver_load,
 	.unload = i915_driver_unload,
 	.open = i915_driver_open,
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index f7186e8..b6bce07 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -155,6 +155,7 @@  int drm_err(const char *func, const char *format, ...);
 #define DRIVER_GEM         0x1000
 #define DRIVER_MODESET     0x2000
 #define DRIVER_PRIME       0x4000
+#define DRIVER_GEM_MMAP    0x8000
 
 #define DRIVER_BUS_PCI 0x1
 #define DRIVER_BUS_PLATFORM 0x2