Skip to content

Commit

Permalink
drm/i915: Prevent a race during I915_GEM_MMAP ioctl with WC set
Browse files Browse the repository at this point in the history
Make sure the underlying VMA in the process address space is the
same as it was during vm_mmap to avoid applying WC to wrong VMA.

A more long-term solution would be to have vm_mmap_locked variant
in linux/mmap.h for when caller wants to hold mmap_sem for an
extended duration.

v2:
- Refactor the compare function

Fixes: 1816f92 ("drm/i915: Support creation of unbound wc user mappings for objects")
Reported-by: Adam Zabrocki <[email protected]>
Suggested-by: Linus Torvalds <[email protected]>
Signed-off-by: Joonas Lahtinen <[email protected]>
Cc: <[email protected]> # v4.0+
Cc: Akash Goel <[email protected]>
Cc: Chris Wilson <[email protected]>
Cc: Tvrtko Ursulin <[email protected]>
Cc: Adam Zabrocki <[email protected]>
Reviewed-by: Chris Wilson <[email protected]>
Reviewed-by: Tvrtko Ursulin <[email protected]> #v1
Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
(cherry picked from commit 5c4604e)
Signed-off-by: Jani Nikula <[email protected]>
  • Loading branch information
jlahtine-intel authored and jnikula committed Feb 12, 2019
1 parent e8a8fed commit 2e7bd10
Showing 1 changed file with 11 additions and 1 deletion.
12 changes: 11 additions & 1 deletion drivers/gpu/drm/i915/i915_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -1824,6 +1824,16 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
return 0;
}

static inline bool
__vma_matches(struct vm_area_struct *vma, struct file *filp,
unsigned long addr, unsigned long size)
{
if (vma->vm_file != filp)
return false;

return vma->vm_start == addr && (vma->vm_end - vma->vm_start) == size;
}

/**
* i915_gem_mmap_ioctl - Maps the contents of an object, returning the address
* it is mapped to.
Expand Down Expand Up @@ -1882,7 +1892,7 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
return -EINTR;
}
vma = find_vma(mm, addr);
if (vma)
if (vma && __vma_matches(vma, obj->base.filp, addr, args->size))
vma->vm_page_prot =
pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
else
Expand Down

0 comments on commit 2e7bd10

Please sign in to comment.