aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-07-23 23:18:51 +0100
committerEric Anholt <eric@anholt.net>2010-08-01 19:56:29 -0700
commit8dc1775dce10d5e47d2805665804fddf39ea3a90 (patch)
treec8929cedb667faacd988eb22312dbe7c72728c0a
parentbe72615bcf4d5b7b314d836c5e1b4baa4b65dad1 (diff)
downloadkernel_samsung_tuna-8dc1775dce10d5e47d2805665804fddf39ea3a90.zip
kernel_samsung_tuna-8dc1775dce10d5e47d2805665804fddf39ea3a90.tar.gz
kernel_samsung_tuna-8dc1775dce10d5e47d2805665804fddf39ea3a90.tar.bz2
drm/i915: Attempt to uncouple object after catastrophic failure in unbind
If we fail to flush outstanding GPU writes but return the memory to the system, we risk corrupting memory should the GPU recovery and complete those writes. On the other hand, if we bail early and free the object then we have a definite use-after-free and real memory corruption. Choose the lesser of two evils, since in order to recover from the hung GPU we need to completely reset it, those pending writes should never happen. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Eric Anholt <eric@anholt.net>
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index f45f385..eeb7688 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1967,11 +1967,12 @@ i915_gem_object_unbind(struct drm_gem_object *obj)
* before we unbind.
*/
ret = i915_gem_object_set_to_cpu_domain(obj, 1);
- if (ret) {
- if (ret != -ERESTARTSYS)
- DRM_ERROR("set_domain failed: %d\n", ret);
+ if (ret == -ERESTARTSYS)
return ret;
- }
+ /* Continue on if we fail due to EIO, the GPU is hung so we
+ * should be safe and we need to cleanup or else we might
+ * cause memory corruption through use-after-free.
+ */
BUG_ON(obj_priv->active);
@@ -2007,7 +2008,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj)
trace_i915_gem_object_unbind(obj);
- return 0;
+ return ret;
}
static struct drm_gem_object *