[PATCH 61/74] fast-pwrite-ioctl
Chris Wilson
chris at chris-wilson.co.uk
Sun Jul 16 19:01:02 UTC 2017
---
drivers/gpu/drm/i915/i915_drv.c | 2 +-
drivers/gpu/drm/i915/i915_drv.h | 5 ++--
drivers/gpu/drm/i915/i915_gem.c | 50 +++++++++++++++++++++++++--------------
drivers/gpu/drm/i915/i915_utils.h | 2 +-
4 files changed, 37 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 984bc5426b1c..a48b97e33884 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2652,7 +2652,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF_DRV(I915_GEM_LEAVEVT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
DRM_DRIVER_IOCTL_DEF(I915_GEM_CREATE, i915_gem_create_ioctl, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_RENDER_ALLOW),
- DRM_IOCTL_DEF_DRV(I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_RENDER_ALLOW),
+ DRM_DRIVER_IOCTL_DEF(I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_RENDER_ALLOW),
DRM_DRIVER_IOCTL_DEF(I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_RENDER_ALLOW),
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index d82933ba5af6..19b4bcbdb69b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3244,8 +3244,9 @@ long i915_gem_create_ioctl(struct file *filp,
unsigned long data);
int i915_gem_pread_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-int i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
+long i915_gem_pwrite_ioctl(struct file *filp,
+ unsigned int cmd,
+ unsigned long data);
int i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
int i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 20e5f8397dff..18529ba3c594 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -603,8 +603,7 @@ i915_gem_object_attach_phys(struct drm_i915_gem_object *obj,
static int
i915_gem_phys_pwrite(struct drm_i915_gem_object *obj,
- struct drm_i915_gem_pwrite *args,
- struct drm_file *file)
+ struct drm_i915_gem_pwrite *args)
{
void *vaddr = obj->phys_handle->vaddr + args->offset;
char __user *user_data = u64_to_user_ptr(args->data_ptr);
@@ -1507,37 +1506,48 @@ i915_gem_shmem_pwrite(struct drm_i915_gem_object *obj,
*
* On error, the contents of the buffer that were to be modified are undefined.
*/
-int
-i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file)
+long
+i915_gem_pwrite_ioctl(struct file *filp,
+ unsigned int cmd,
+ unsigned long data)
{
- struct drm_i915_gem_pwrite *args = data;
+ struct drm_i915_gem_pwrite __user *user = (typeof(user))data;
+ struct drm_file *file = filp->private_data;
struct drm_i915_gem_object *obj;
+ struct drm_i915_gem_pwrite arg;
int ret;
- if (args->size == 0)
+ if (unlikely(!access_ok(VERIFY_READ, user, sizeof(*user))))
+ return -EFAULT;
+
+ user_access_begin();
+ unsafe_get_user(arg.handle, &user->handle, err_user);
+ unsafe_get_user(arg.size, &user->size, err_user);
+ unsafe_get_user(arg.offset, &user->offset, err_user);
+ unsafe_get_user(arg.data_ptr, &user->data_ptr, err_user);
+ user_access_end();
+
+ if (arg.size == 0)
return 0;
- if (!access_ok(VERIFY_READ,
- u64_to_user_ptr(args->data_ptr),
- args->size))
+ if (!access_ok(VERIFY_READ, u64_to_user_ptr(arg.data_ptr), arg.size))
return -EFAULT;
- obj = i915_gem_object_lookup(file, args->handle);
- if (!obj)
+ obj = i915_gem_object_lookup(file, arg.handle);
+ if (unlikely(!obj))
return -ENOENT;
/* Bounds check destination. */
- if (range_overflows_t(u64, args->offset, args->size, obj->base.size)) {
+ if (range_overflows_t(u64, arg.offset, arg.size, obj->base.size)) {
ret = -EINVAL;
goto err;
}
- trace_i915_gem_object_pwrite(obj, args->offset, args->size);
+ trace_i915_gem_object_pwrite(obj, arg.offset, arg.size);
ret = -ENODEV;
if (obj->ops->pwrite)
- ret = obj->ops->pwrite(obj, args);
+ ret = obj->ops->pwrite(obj, &arg);
if (ret != -ENODEV)
goto err;
@@ -1566,19 +1576,23 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
* pointers (e.g. gtt mappings when moving data between
* textures). Fallback to the shmem path in that case.
*/
- ret = i915_gem_gtt_pwrite_fast(obj, args);
+ ret = i915_gem_gtt_pwrite_fast(obj, &arg);
if (ret == -EFAULT || ret == -ENOSPC) {
if (obj->phys_handle)
- ret = i915_gem_phys_pwrite(obj, args, file);
+ ret = i915_gem_phys_pwrite(obj, &arg);
else
- ret = i915_gem_shmem_pwrite(obj, args);
+ ret = i915_gem_shmem_pwrite(obj, &arg);
}
i915_gem_object_unpin_pages(obj);
err:
i915_gem_object_put(obj);
return ret;
+
+err_user:
+ user_access_end();
+ return -EFAULT;
}
static void i915_gem_object_bump_inactive_ggtt(struct drm_i915_gem_object *obj)
diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h
index 12fc250b47b9..b6ba7a09fe2a 100644
--- a/drivers/gpu/drm/i915/i915_utils.h
+++ b/drivers/gpu/drm/i915/i915_utils.h
@@ -60,7 +60,7 @@
typeof(max) max__ = (max); \
(void)(&start__ == &size__); \
(void)(&start__ == &max__); \
- start__ > max__ || size__ > max__ - start__; \
+ unlikely(start__ > max__ || size__ > max__ - start__); \
})
#define range_overflows_t(type, start, size, max) \
--
2.13.2
More information about the Intel-gfx-trybot
mailing list