diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c index 9ffc80d0a51b..519be02fad38 100644 --- a/mm/userfaultfd.c +++ b/mm/userfaultfd.c @@ -910,8 +910,17 @@ static __always_inline ssize_t mfill_atomic(struct userfaultfd_ctx *ctx, while (state.src_addr < src_start + len) { VM_WARN_ON_ONCE(state.dst_addr >= dst_start + len); + if (state.dst_addr < state.vma->vm_start || + state.dst_addr >= state.vma->vm_end) { + mfill_put_vma(&state); + state.dst_start = state.dst_addr; + state.len = dst_start + len - state.dst_addr; + err = mfill_get_vma(&state); + if (err) + break; + } - err = mfill_get_pmd(&state); + err = mfill_get_pmd(&state); if (err) break;