Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4ad72b7f authored by Chris Wilson's avatar Chris Wilson Committed by Daniel Vetter
Browse files

drm/i915: Fix unsafe vma iteration in i915_drop_caches



When unbinding, there is a possibility that we drop the active reference
on the object, thereby freeing it. If that happens, we may destroy the
vm link as well as the object and vma. So iterate carefully.

Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 8fe8a3fe
Loading
Loading
Loading
Loading
+11 −6
Original line number Diff line number Diff line
@@ -3812,8 +3812,6 @@ i915_drop_caches_set(void *data, u64 val)
	struct drm_device *dev = data;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct drm_i915_gem_object *obj, *next;
	struct i915_address_space *vm;
	struct i915_vma *vma, *x;
	int ret;

	DRM_DEBUG("Dropping caches: 0x%08llx\n", val);
@@ -3834,16 +3832,23 @@ i915_drop_caches_set(void *data, u64 val)
		i915_gem_retire_requests(dev);

	if (val & DROP_BOUND) {
		list_for_each_entry(vm, &dev_priv->vm_list, global_link) {
			list_for_each_entry_safe(vma, x, &vm->inactive_list,
						 mm_list) {
		list_for_each_entry_safe(obj, next, &dev_priv->mm.bound_list,
					 global_list) {
			struct i915_vma *vma, *v;

			ret = 0;
			drm_gem_object_reference(&obj->base);
			list_for_each_entry_safe(vma, v, &obj->vma_list, vma_link) {
				if (vma->pin_count)
					continue;

				ret = i915_vma_unbind(vma);
				if (ret)
					goto unlock;
					break;
			}
			drm_gem_object_unreference(&obj->base);
			if (ret)
				goto unlock;
		}
	}