diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 38e0f8301a14..ac22668b239a 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -3050,20 +3050,12 @@ i915_dispatch_gem_execbuffer(struct drm_device *dev, | |||
3050 | drm_i915_private_t *dev_priv = dev->dev_private; | 3050 | drm_i915_private_t *dev_priv = dev->dev_private; |
3051 | int nbox = exec->num_cliprects; | 3051 | int nbox = exec->num_cliprects; |
3052 | int i = 0, count; | 3052 | int i = 0, count; |
3053 | uint32_t exec_start, exec_len; | 3053 | uint32_t exec_start, exec_len; |
3054 | RING_LOCALS; | 3054 | RING_LOCALS; |
3055 | 3055 | ||
3056 | exec_start = (uint32_t) exec_offset + exec->batch_start_offset; | 3056 | exec_start = (uint32_t) exec_offset + exec->batch_start_offset; |
3057 | exec_len = (uint32_t) exec->batch_len; | 3057 | exec_len = (uint32_t) exec->batch_len; |
3058 | 3058 | ||
3059 | if ((exec_start | exec_len) & 0x7) { | ||
3060 | DRM_ERROR("alignment\n"); | ||
3061 | return -EINVAL; | ||
3062 | } | ||
3063 | |||
3064 | if (!exec_start) | ||
3065 | return -EINVAL; | ||
3066 | |||
3067 | count = nbox ? nbox : 1; | 3059 | count = nbox ? nbox : 1; |
3068 | 3060 | ||
3069 | for (i = 0; i < count; i++) { | 3061 | for (i = 0; i < count; i++) { |
@@ -3211,6 +3203,24 @@ err: | |||
3211 | return ret; | 3203 | return ret; |
3212 | } | 3204 | } |
3213 | 3205 | ||
3206 | static int | ||
3207 | i915_gem_check_execbuffer (struct drm_i915_gem_execbuffer *exec, | ||
3208 | uint64_t exec_offset) | ||
3209 | { | ||
3210 | uint32_t exec_start, exec_len; | ||
3211 | |||
3212 | exec_start = (uint32_t) exec_offset + exec->batch_start_offset; | ||
3213 | exec_len = (uint32_t) exec->batch_len; | ||
3214 | |||
3215 | if ((exec_start | exec_len) & 0x7) | ||
3216 | return -EINVAL; | ||
3217 | |||
3218 | if (!exec_start) | ||
3219 | return -EINVAL; | ||
3220 | |||
3221 | return 0; | ||
3222 | } | ||
3223 | |||
3214 | int | 3224 | int |
3215 | i915_gem_execbuffer(struct drm_device *dev, void *data, | 3225 | i915_gem_execbuffer(struct drm_device *dev, void *data, |
3216 | struct drm_file *file_priv) | 3226 | struct drm_file *file_priv) |
@@ -3362,6 +3372,14 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, | |||
3362 | batch_obj->pending_read_domains = I915_GEM_DOMAIN_COMMAND; | 3372 | batch_obj->pending_read_domains = I915_GEM_DOMAIN_COMMAND; |
3363 | batch_obj->pending_write_domain = 0; | 3373 | batch_obj->pending_write_domain = 0; |
3364 | 3374 | ||
3375 | /* Sanity check the batch buffer, prior to moving objects */ | ||
3376 | exec_offset = exec_list[args->buffer_count - 1].offset; | ||
3377 | ret = i915_gem_check_execbuffer (args, exec_offset); | ||
3378 | if (ret != 0) { | ||
3379 | DRM_ERROR("execbuf with invalid offset/length\n"); | ||
3380 | goto err; | ||
3381 | } | ||
3382 | |||
3365 | i915_verify_inactive(dev, __FILE__, __LINE__); | 3383 | i915_verify_inactive(dev, __FILE__, __LINE__); |
3366 | 3384 | ||
3367 | /* Zero the global flush/invalidate flags. These | 3385 | /* Zero the global flush/invalidate flags. These |
@@ -3410,8 +3428,6 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, | |||
3410 | } | 3428 | } |
3411 | #endif | 3429 | #endif |
3412 | 3430 | ||
3413 | exec_offset = exec_list[args->buffer_count - 1].offset; | ||
3414 | |||
3415 | #if WATCH_EXEC | 3431 | #if WATCH_EXEC |
3416 | i915_gem_dump_object(batch_obj, | 3432 | i915_gem_dump_object(batch_obj, |
3417 | args->batch_len, | 3433 | args->batch_len, |