aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2017-06-29 11:04:25 -0400
committerJani Nikula <jani.nikula@intel.com>2017-07-03 09:12:48 -0400
commit4ec654bf3a63d503e3c5336eade5c369ae17db56 (patch)
tree854ea8aa70115e1d8b0c73f14e9417d1790d4220
parent9c75b185274b7766fe69c2e73607c1ed780b284b (diff)
drm/i915: Avoid undefined behaviour of "u32 >> 32"
When computing a hash for looking up relocation target handles in an execbuf, we start with a large size for the hashtable and proceed to halve it until the allocation succeeds. The final attempt is with an order of 0 (i.e. a single element). This means that we then pass bits=0 to hash_32() which then computes "hash >> (32 - 0)" to lookup the single element. Right shifting a value by the width of the operand is undefined, so limit the smallest hash table we use to order 1. v2: Keep the retry allocation flag for the final pass Fixes: 4ff4b44cbb70 ("drm/i915: Store a direct lookup from object handle to vma") Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170629150425.27508-1-chris@chris-wilson.co.uk (cherry picked from commit 4d470f7359c4bf22518baa30700ad45649371a22) Signed-off-by: Jani Nikula <jani.nikula@intel.com>
-rw-r--r--drivers/gpu/drm/i915/i915_gem_execbuffer.c38
1 files changed, 24 insertions, 14 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 9337446f1068..054b2e54cdaf 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -288,20 +288,26 @@ static int eb_create(struct i915_execbuffer *eb)
288 * direct lookup. 288 * direct lookup.
289 */ 289 */
290 do { 290 do {
291 unsigned int flags;
292
293 /* While we can still reduce the allocation size, don't
294 * raise a warning and allow the allocation to fail.
295 * On the last pass though, we want to try as hard
296 * as possible to perform the allocation and warn
297 * if it fails.
298 */
299 flags = GFP_TEMPORARY;
300 if (size > 1)
301 flags |= __GFP_NORETRY | __GFP_NOWARN;
302
291 eb->buckets = kzalloc(sizeof(struct hlist_head) << size, 303 eb->buckets = kzalloc(sizeof(struct hlist_head) << size,
292 GFP_TEMPORARY | 304 flags);
293 __GFP_NORETRY |
294 __GFP_NOWARN);
295 if (eb->buckets) 305 if (eb->buckets)
296 break; 306 break;
297 } while (--size); 307 } while (--size);
298 308
299 if (unlikely(!eb->buckets)) { 309 if (unlikely(!size))
300 eb->buckets = kzalloc(sizeof(struct hlist_head), 310 return -ENOMEM;
301 GFP_TEMPORARY);
302 if (unlikely(!eb->buckets))
303 return -ENOMEM;
304 }
305 311
306 eb->lut_size = size; 312 eb->lut_size = size;
307 } else { 313 } else {
@@ -452,7 +458,7 @@ eb_add_vma(struct i915_execbuffer *eb,
452 return err; 458 return err;
453 } 459 }
454 460
455 if (eb->lut_size >= 0) { 461 if (eb->lut_size > 0) {
456 vma->exec_handle = entry->handle; 462 vma->exec_handle = entry->handle;
457 hlist_add_head(&vma->exec_node, 463 hlist_add_head(&vma->exec_node,
458 &eb->buckets[hash_32(entry->handle, 464 &eb->buckets[hash_32(entry->handle,
@@ -894,7 +900,7 @@ static void eb_release_vmas(const struct i915_execbuffer *eb)
894static void eb_reset_vmas(const struct i915_execbuffer *eb) 900static void eb_reset_vmas(const struct i915_execbuffer *eb)
895{ 901{
896 eb_release_vmas(eb); 902 eb_release_vmas(eb);
897 if (eb->lut_size >= 0) 903 if (eb->lut_size > 0)
898 memset(eb->buckets, 0, 904 memset(eb->buckets, 0,
899 sizeof(struct hlist_head) << eb->lut_size); 905 sizeof(struct hlist_head) << eb->lut_size);
900} 906}
@@ -903,7 +909,7 @@ static void eb_destroy(const struct i915_execbuffer *eb)
903{ 909{
904 GEM_BUG_ON(eb->reloc_cache.rq); 910 GEM_BUG_ON(eb->reloc_cache.rq);
905 911
906 if (eb->lut_size >= 0) 912 if (eb->lut_size > 0)
907 kfree(eb->buckets); 913 kfree(eb->buckets);
908} 914}
909 915
@@ -2180,8 +2186,11 @@ i915_gem_do_execbuffer(struct drm_device *dev,
2180 } 2186 }
2181 } 2187 }
2182 2188
2183 if (eb_create(&eb)) 2189 err = eb_create(&eb);
2184 return -ENOMEM; 2190 if (err)
2191 goto err_out_fence;
2192
2193 GEM_BUG_ON(!eb.lut_size);
2185 2194
2186 /* 2195 /*
2187 * Take a local wakeref for preparing to dispatch the execbuf as 2196 * Take a local wakeref for preparing to dispatch the execbuf as
@@ -2340,6 +2349,7 @@ err_unlock:
2340err_rpm: 2349err_rpm:
2341 intel_runtime_pm_put(eb.i915); 2350 intel_runtime_pm_put(eb.i915);
2342 eb_destroy(&eb); 2351 eb_destroy(&eb);
2352err_out_fence:
2343 if (out_fence_fd != -1) 2353 if (out_fence_fd != -1)
2344 put_unused_fd(out_fence_fd); 2354 put_unused_fd(out_fence_fd);
2345err_in_fence: 2355err_in_fence: