[PATCH 1/6] drm/gem: refine drm_gem_objects_lookup

Qiang Yu yuq825 at gmail.com
Thu Sep 26 14:10:40 UTC 2019


Do not use user space bo handles directly and left the user
to kernel copy work to drivers calling this function.

This is for driver like lima which does not pass gem bo
handles continously in an array in ioctl argument.

Cc: Rob Herring <robh at kernel.org>
Cc: Tomeu Vizoso <tomeu.vizoso at collabora.com>
Cc: Steven Price <steven.price at arm.com>
Cc: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>
Signed-off-by: Qiang Yu <yuq825 at gmail.com>
---
 drivers/gpu/drm/drm_gem.c               | 28 +++++++------------------
 drivers/gpu/drm/panfrost/panfrost_drv.c | 23 +++++++++++++++++---
 include/drm/drm_gem.h                   |  2 +-
 3 files changed, 29 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 6854f5867d51..9f73e5f3b53f 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -679,11 +679,11 @@ static int objects_lookup(struct drm_file *filp, u32 *handle, int count,
 /**
  * drm_gem_objects_lookup - look up GEM objects from an array of handles
  * @filp: DRM file private date
- * @bo_handles: user pointer to array of userspace handle
+ * @bo_handles: array of GEM object handles
  * @count: size of handle array
  * @objs_out: returned pointer to array of drm_gem_object pointers
  *
- * Takes an array of userspace handles and returns a newly allocated array of
+ * Takes an array of GEM object handles and returns a newly allocated array of
  * GEM objects.
  *
  * For a single handle lookup, use drm_gem_object_lookup().
@@ -695,11 +695,10 @@ static int objects_lookup(struct drm_file *filp, u32 *handle, int count,
  * failure. 0 is returned on success.
  *
  */
-int drm_gem_objects_lookup(struct drm_file *filp, void __user *bo_handles,
+int drm_gem_objects_lookup(struct drm_file *filp, u32 *bo_handles,
 			   int count, struct drm_gem_object ***objs_out)
 {
 	int ret;
-	u32 *handles;
 	struct drm_gem_object **objs;
 
 	if (!count)
@@ -710,23 +709,12 @@ int drm_gem_objects_lookup(struct drm_file *filp, void __user *bo_handles,
 	if (!objs)
 		return -ENOMEM;
 
-	handles = kvmalloc_array(count, sizeof(u32), GFP_KERNEL);
-	if (!handles) {
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	if (copy_from_user(handles, bo_handles, count * sizeof(u32))) {
-		ret = -EFAULT;
-		DRM_DEBUG("Failed to copy in GEM handles\n");
-		goto out;
-	}
-
-	ret = objects_lookup(filp, handles, count, objs);
-	*objs_out = objs;
+	ret = objects_lookup(filp, bo_handles, count, objs);
+	if (ret)
+		kvfree(objs);
+	else
+		*objs_out = objs;
 
-out:
-	kvfree(handles);
 	return ret;
 
 }
diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c
index d74442d71048..616f8fcc4652 100644
--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
@@ -119,6 +119,9 @@ panfrost_lookup_bos(struct drm_device *dev,
 		  struct drm_panfrost_submit *args,
 		  struct panfrost_job *job)
 {
+	u32 *handles;
+	int ret;
+
 	job->bo_count = args->bo_handle_count;
 
 	if (!job->bo_count)
@@ -130,9 +133,23 @@ panfrost_lookup_bos(struct drm_device *dev,
 	if (!job->implicit_fences)
 		return -ENOMEM;
 
-	return drm_gem_objects_lookup(file_priv,
-				      (void __user *)(uintptr_t)args->bo_handles,
-				      job->bo_count, &job->bos);
+	handles = kvmalloc_array(job->bo_count, sizeof(u32), GFP_KERNEL);
+	if (!handles)
+		return -ENOMEM;
+
+	if (copy_from_user(handles, (void __user *)(uintptr_t)args->bo_handles,
+			   job->bo_count * sizeof(u32))) {
+		DRM_DEBUG("Failed to copy in GEM handles\n");
+		ret = -EFAULT;
+		goto out;
+	}
+
+	ret = drm_gem_objects_lookup(file_priv, handles,
+				     job->bo_count, &job->bos);
+
+out:
+	kvfree(handles);
+	return ret;
 }
 
 /**
diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h
index 6aaba14f5972..c23ac36231ba 100644
--- a/include/drm/drm_gem.h
+++ b/include/drm/drm_gem.h
@@ -387,7 +387,7 @@ struct page **drm_gem_get_pages(struct drm_gem_object *obj);
 void drm_gem_put_pages(struct drm_gem_object *obj, struct page **pages,
 		bool dirty, bool accessed);
 
-int drm_gem_objects_lookup(struct drm_file *filp, void __user *bo_handles,
+int drm_gem_objects_lookup(struct drm_file *filp, u32 *bo_handles,
 			   int count, struct drm_gem_object ***objs_out);
 struct drm_gem_object *drm_gem_object_lookup(struct drm_file *filp, u32 handle);
 long drm_gem_dma_resv_wait(struct drm_file *filep, u32 handle,
-- 
2.17.1



More information about the dri-devel mailing list