aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_gem.c
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2009-03-11 15:30:04 -0400
committerEric Anholt <eric@anholt.net>2009-03-27 17:47:34 -0400
commit201361a54ed187d8595a283e3a4ddb213bc8323b (patch)
tree12a5d23a45f72f8bd917161735d55985654b52e0 /drivers/gpu/drm/i915/i915_gem.c
parenteb01459fbbccb4ca0b879cbfc97e33ac6eabf975 (diff)
drm/i915: Fix lock order reversal with cliprects and cmdbuf in non-DRI2 paths.
This introduces allocation in the batch submission path that wasn't there previously, but these are compatibility paths so we care about simplicity more than performance. kernel.org bug #12419. Signed-off-by: Eric Anholt <eric@anholt.net> Reviewed-by: Keith Packard <keithp@keithp.com> Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 010af908bdb6..2bda15197cce 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2891,11 +2891,10 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
2891static int 2891static int
2892i915_dispatch_gem_execbuffer(struct drm_device *dev, 2892i915_dispatch_gem_execbuffer(struct drm_device *dev,
2893 struct drm_i915_gem_execbuffer *exec, 2893 struct drm_i915_gem_execbuffer *exec,
2894 struct drm_clip_rect *cliprects,
2894 uint64_t exec_offset) 2895 uint64_t exec_offset)
2895{ 2896{
2896 drm_i915_private_t *dev_priv = dev->dev_private; 2897 drm_i915_private_t *dev_priv = dev->dev_private;
2897 struct drm_clip_rect __user *boxes = (struct drm_clip_rect __user *)
2898 (uintptr_t) exec->cliprects_ptr;
2899 int nbox = exec->num_cliprects; 2898 int nbox = exec->num_cliprects;
2900 int i = 0, count; 2899 int i = 0, count;
2901 uint32_t exec_start, exec_len; 2900 uint32_t exec_start, exec_len;
@@ -2916,7 +2915,7 @@ i915_dispatch_gem_execbuffer(struct drm_device *dev,
2916 2915
2917 for (i = 0; i < count; i++) { 2916 for (i = 0; i < count; i++) {
2918 if (i < nbox) { 2917 if (i < nbox) {
2919 int ret = i915_emit_box(dev, boxes, i, 2918 int ret = i915_emit_box(dev, cliprects, i,
2920 exec->DR1, exec->DR4); 2919 exec->DR1, exec->DR4);
2921 if (ret) 2920 if (ret)
2922 return ret; 2921 return ret;
@@ -2983,6 +2982,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
2983 struct drm_gem_object **object_list = NULL; 2982 struct drm_gem_object **object_list = NULL;
2984 struct drm_gem_object *batch_obj; 2983 struct drm_gem_object *batch_obj;
2985 struct drm_i915_gem_object *obj_priv; 2984 struct drm_i915_gem_object *obj_priv;
2985 struct drm_clip_rect *cliprects = NULL;
2986 int ret, i, pinned = 0; 2986 int ret, i, pinned = 0;
2987 uint64_t exec_offset; 2987 uint64_t exec_offset;
2988 uint32_t seqno, flush_domains; 2988 uint32_t seqno, flush_domains;
@@ -3019,6 +3019,23 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
3019 goto pre_mutex_err; 3019 goto pre_mutex_err;
3020 } 3020 }
3021 3021
3022 if (args->num_cliprects != 0) {
3023 cliprects = drm_calloc(args->num_cliprects, sizeof(*cliprects),
3024 DRM_MEM_DRIVER);
3025 if (cliprects == NULL)
3026 goto pre_mutex_err;
3027
3028 ret = copy_from_user(cliprects,
3029 (struct drm_clip_rect __user *)
3030 (uintptr_t) args->cliprects_ptr,
3031 sizeof(*cliprects) * args->num_cliprects);
3032 if (ret != 0) {
3033 DRM_ERROR("copy %d cliprects failed: %d\n",
3034 args->num_cliprects, ret);
3035 goto pre_mutex_err;
3036 }
3037 }
3038
3022 mutex_lock(&dev->struct_mutex); 3039 mutex_lock(&dev->struct_mutex);
3023 3040
3024 i915_verify_inactive(dev, __FILE__, __LINE__); 3041 i915_verify_inactive(dev, __FILE__, __LINE__);
@@ -3155,7 +3172,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
3155#endif 3172#endif
3156 3173
3157 /* Exec the batchbuffer */ 3174 /* Exec the batchbuffer */
3158 ret = i915_dispatch_gem_execbuffer(dev, args, exec_offset); 3175 ret = i915_dispatch_gem_execbuffer(dev, args, cliprects, exec_offset);
3159 if (ret) { 3176 if (ret) {
3160 DRM_ERROR("dispatch failed %d\n", ret); 3177 DRM_ERROR("dispatch failed %d\n", ret);
3161 goto err; 3178 goto err;
@@ -3224,6 +3241,8 @@ pre_mutex_err:
3224 DRM_MEM_DRIVER); 3241 DRM_MEM_DRIVER);
3225 drm_free(exec_list, sizeof(*exec_list) * args->buffer_count, 3242 drm_free(exec_list, sizeof(*exec_list) * args->buffer_count,
3226 DRM_MEM_DRIVER); 3243 DRM_MEM_DRIVER);
3244 drm_free(cliprects, sizeof(*cliprects) * args->num_cliprects,
3245 DRM_MEM_DRIVER);
3227 3246
3228 return ret; 3247 return ret;
3229} 3248}