diff options
author | Sean Paul <seanpaul@chromium.org> | 2018-01-19 18:32:05 +0100 |
---|---|---|
committer | Sean Paul <seanpaul@chromium.org> | 2018-01-19 18:32:05 +0100 |
commit | 54156da8937c9f5f84b4215e239a61ecc7c29275 (patch) | |
tree | 7fb1e07ebedc5fbd35a29f5d450dee538763efdb /fs/userfaultfd.c | |
parent | drm: add kernel doc for exported gem dmabuf_ops (diff) | |
parent | BackMerge tag 'v4.15-rc8' into drm-next (diff) | |
download | linux-54156da8937c9f5f84b4215e239a61ecc7c29275.tar.xz linux-54156da8937c9f5f84b4215e239a61ecc7c29275.zip |
Merge airlied/drm-next into drm-misc-next
It's been a while since we've backmerged drm-next. Dave just brought
back 4.15-rc8, so now's a good time to freshen things up around here.
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Diffstat (limited to 'fs/userfaultfd.c')
-rw-r--r-- | fs/userfaultfd.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c index ac9a4e65ca49..41a75f9f23fd 100644 --- a/fs/userfaultfd.c +++ b/fs/userfaultfd.c @@ -570,11 +570,14 @@ out: static void userfaultfd_event_wait_completion(struct userfaultfd_ctx *ctx, struct userfaultfd_wait_queue *ewq) { + struct userfaultfd_ctx *release_new_ctx; + if (WARN_ON_ONCE(current->flags & PF_EXITING)) goto out; ewq->ctx = ctx; init_waitqueue_entry(&ewq->wq, current); + release_new_ctx = NULL; spin_lock(&ctx->event_wqh.lock); /* @@ -601,8 +604,7 @@ static void userfaultfd_event_wait_completion(struct userfaultfd_ctx *ctx, new = (struct userfaultfd_ctx *) (unsigned long) ewq->msg.arg.reserved.reserved1; - - userfaultfd_ctx_put(new); + release_new_ctx = new; } break; } @@ -617,6 +619,20 @@ static void userfaultfd_event_wait_completion(struct userfaultfd_ctx *ctx, __set_current_state(TASK_RUNNING); spin_unlock(&ctx->event_wqh.lock); + if (release_new_ctx) { + struct vm_area_struct *vma; + struct mm_struct *mm = release_new_ctx->mm; + + /* the various vma->vm_userfaultfd_ctx still points to it */ + down_write(&mm->mmap_sem); + for (vma = mm->mmap; vma; vma = vma->vm_next) + if (vma->vm_userfaultfd_ctx.ctx == release_new_ctx) + vma->vm_userfaultfd_ctx = NULL_VM_UFFD_CTX; + up_write(&mm->mmap_sem); + + userfaultfd_ctx_put(release_new_ctx); + } + /* * ctx may go away after this if the userfault pseudo fd is * already released. |