3.16.36-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> commit db9f9203e27495b2d151b695504e286eec026e9b upstream. Holding a reference to the containing task_struct is not sufficient to prevent the mm_struct from being reaped under memory pressure. If this happens whilst we are calling get_user_pages(), explosions erupt - sometimes an immediate GPF, sometimes page flag corruption. To prevent the target mm from being reaped as we are reading from it, acquire a reference before we begin. Testcase: igt/gem_shrink/*userptr Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> Cc: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx> Cc: Michał Winiarski <michal.winiarski@xxxxxxxxx> Reviewed-by: Michał Winiarski <michal.winiarski@xxxxxxxxx> Link: http://patchwork.freedesktop.org/patch/msgid/1459864801-28606-2-git-send-email-chris@xxxxxxxxxxxxxxxxxx (cherry picked from commit 40313f0cd0b711a7a5905e5182422799e157d8aa) Signed-off-by: Jani Nikula <jani.nikula@xxxxxxxxx> [bwh: Backported to 3.16: - s/get_user_pages_remote/get_user_pages/ - s/npages/num_pages/] Signed-off-by: Ben Hutchings <ben@xxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/i915_gem_userptr.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -411,19 +411,24 @@ __i915_gem_userptr_get_pages_worker(stru if (pvec != NULL) { struct mm_struct *mm = obj->userptr.mm; - down_read(&mm->mmap_sem); - while (pinned < num_pages) { - ret = get_user_pages(work->task, mm, - obj->userptr.ptr + pinned * PAGE_SIZE, - num_pages - pinned, - !obj->userptr.read_only, 0, - pvec + pinned, NULL); - if (ret < 0) - break; + ret = -EFAULT; + if (atomic_inc_not_zero(&mm->mm_users)) { + down_read(&mm->mmap_sem); + while (pinned < num_pages) { + ret = get_user_pages + (work->task, mm, + obj->userptr.ptr + pinned * PAGE_SIZE, + num_pages - pinned, + !obj->userptr.read_only, 0, + pvec + pinned, NULL); + if (ret < 0) + break; - pinned += ret; + pinned += ret; + } + up_read(&mm->mmap_sem); + mmput(mm); } - up_read(&mm->mmap_sem); } mutex_lock(&dev->struct_mutex); -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html