aboutsummaryrefslogtreecommitdiffstats
path: root/fs/userfaultfd.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/userfaultfd.c')
-rw-r--r--fs/userfaultfd.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
index 85959d8324df..d96e2f30084b 100644
--- a/fs/userfaultfd.c
+++ b/fs/userfaultfd.c
@@ -257,9 +257,9 @@ out:
257 * fatal_signal_pending()s, and the mmap_sem must be released before 257 * fatal_signal_pending()s, and the mmap_sem must be released before
258 * returning it. 258 * returning it.
259 */ 259 */
260int handle_userfault(struct fault_env *fe, unsigned long reason) 260int handle_userfault(struct vm_fault *vmf, unsigned long reason)
261{ 261{
262 struct mm_struct *mm = fe->vma->vm_mm; 262 struct mm_struct *mm = vmf->vma->vm_mm;
263 struct userfaultfd_ctx *ctx; 263 struct userfaultfd_ctx *ctx;
264 struct userfaultfd_wait_queue uwq; 264 struct userfaultfd_wait_queue uwq;
265 int ret; 265 int ret;
@@ -268,7 +268,7 @@ int handle_userfault(struct fault_env *fe, unsigned long reason)
268 BUG_ON(!rwsem_is_locked(&mm->mmap_sem)); 268 BUG_ON(!rwsem_is_locked(&mm->mmap_sem));
269 269
270 ret = VM_FAULT_SIGBUS; 270 ret = VM_FAULT_SIGBUS;
271 ctx = fe->vma->vm_userfaultfd_ctx.ctx; 271 ctx = vmf->vma->vm_userfaultfd_ctx.ctx;
272 if (!ctx) 272 if (!ctx)
273 goto out; 273 goto out;
274 274
@@ -301,17 +301,18 @@ int handle_userfault(struct fault_env *fe, unsigned long reason)
301 * without first stopping userland access to the memory. For 301 * without first stopping userland access to the memory. For
302 * VM_UFFD_MISSING userfaults this is enough for now. 302 * VM_UFFD_MISSING userfaults this is enough for now.
303 */ 303 */
304 if (unlikely(!(fe->flags & FAULT_FLAG_ALLOW_RETRY))) { 304 if (unlikely(!(vmf->flags & FAULT_FLAG_ALLOW_RETRY))) {
305 /* 305 /*
306 * Validate the invariant that nowait must allow retry 306 * Validate the invariant that nowait must allow retry
307 * to be sure not to return SIGBUS erroneously on 307 * to be sure not to return SIGBUS erroneously on
308 * nowait invocations. 308 * nowait invocations.
309 */ 309 */
310 BUG_ON(fe->flags & FAULT_FLAG_RETRY_NOWAIT); 310 BUG_ON(vmf->flags & FAULT_FLAG_RETRY_NOWAIT);
311#ifdef CONFIG_DEBUG_VM 311#ifdef CONFIG_DEBUG_VM
312 if (printk_ratelimit()) { 312 if (printk_ratelimit()) {
313 printk(KERN_WARNING 313 printk(KERN_WARNING
314 "FAULT_FLAG_ALLOW_RETRY missing %x\n", fe->flags); 314 "FAULT_FLAG_ALLOW_RETRY missing %x\n",
315 vmf->flags);
315 dump_stack(); 316 dump_stack();
316 } 317 }
317#endif 318#endif
@@ -323,7 +324,7 @@ int handle_userfault(struct fault_env *fe, unsigned long reason)
323 * and wait. 324 * and wait.
324 */ 325 */
325 ret = VM_FAULT_RETRY; 326 ret = VM_FAULT_RETRY;
326 if (fe->flags & FAULT_FLAG_RETRY_NOWAIT) 327 if (vmf->flags & FAULT_FLAG_RETRY_NOWAIT)
327 goto out; 328 goto out;
328 329
329 /* take the reference before dropping the mmap_sem */ 330 /* take the reference before dropping the mmap_sem */
@@ -331,11 +332,11 @@ int handle_userfault(struct fault_env *fe, unsigned long reason)
331 332
332 init_waitqueue_func_entry(&uwq.wq, userfaultfd_wake_function); 333 init_waitqueue_func_entry(&uwq.wq, userfaultfd_wake_function);
333 uwq.wq.private = current; 334 uwq.wq.private = current;
334 uwq.msg = userfault_msg(fe->address, fe->flags, reason); 335 uwq.msg = userfault_msg(vmf->address, vmf->flags, reason);
335 uwq.ctx = ctx; 336 uwq.ctx = ctx;
336 337
337 return_to_userland = 338 return_to_userland =
338 (fe->flags & (FAULT_FLAG_USER|FAULT_FLAG_KILLABLE)) == 339 (vmf->flags & (FAULT_FLAG_USER|FAULT_FLAG_KILLABLE)) ==
339 (FAULT_FLAG_USER|FAULT_FLAG_KILLABLE); 340 (FAULT_FLAG_USER|FAULT_FLAG_KILLABLE);
340 341
341 spin_lock(&ctx->fault_pending_wqh.lock); 342 spin_lock(&ctx->fault_pending_wqh.lock);
@@ -353,7 +354,8 @@ int handle_userfault(struct fault_env *fe, unsigned long reason)
353 TASK_KILLABLE); 354 TASK_KILLABLE);
354 spin_unlock(&ctx->fault_pending_wqh.lock); 355 spin_unlock(&ctx->fault_pending_wqh.lock);
355 356
356 must_wait = userfaultfd_must_wait(ctx, fe->address, fe->flags, reason); 357 must_wait = userfaultfd_must_wait(ctx, vmf->address, vmf->flags,
358 reason);
357 up_read(&mm->mmap_sem); 359 up_read(&mm->mmap_sem);
358 360
359 if (likely(must_wait && !ACCESS_ONCE(ctx->released) && 361 if (likely(must_wait && !ACCESS_ONCE(ctx->released) &&