forked from Minki/linux
drm/i915: Pin pages whilst allocating for dma-buf vmap()
During the vmap() routine for the dma-buf, we first grab the pages and then try to allocate a temporary array to pass to the vmap(). However, the shrinker can and will reap any object that is unbound if the allocation for the array first fails. This includes the object which we are attempting to vmap(). The solution is to mark the object's pages as pinned whilst we try the allocation to prevent the use-after-free introduced by the potential shrinkage. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
parent
0bf2134780
commit
993fc6ebaf
@ -125,13 +125,15 @@ static void *i915_gem_dmabuf_vmap(struct dma_buf *dma_buf)
|
||||
|
||||
ret = i915_gem_object_get_pages(obj);
|
||||
if (ret)
|
||||
goto error;
|
||||
goto err;
|
||||
|
||||
i915_gem_object_pin_pages(obj);
|
||||
|
||||
ret = -ENOMEM;
|
||||
|
||||
pages = drm_malloc_ab(obj->base.size >> PAGE_SHIFT, sizeof(*pages));
|
||||
if (pages == NULL)
|
||||
goto error;
|
||||
goto err_unpin;
|
||||
|
||||
i = 0;
|
||||
for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, 0)
|
||||
@ -141,15 +143,16 @@ static void *i915_gem_dmabuf_vmap(struct dma_buf *dma_buf)
|
||||
drm_free_large(pages);
|
||||
|
||||
if (!obj->dma_buf_vmapping)
|
||||
goto error;
|
||||
goto err_unpin;
|
||||
|
||||
obj->vmapping_count = 1;
|
||||
i915_gem_object_pin_pages(obj);
|
||||
out_unlock:
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
return obj->dma_buf_vmapping;
|
||||
|
||||
error:
|
||||
err_unpin:
|
||||
i915_gem_object_unpin_pages(obj);
|
||||
err:
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user