userfaultfd.c (18981B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * mm/userfaultfd.c 4 * 5 * Copyright (C) 2015 Red Hat, Inc. 6 */ 7 8#include <linux/mm.h> 9#include <linux/sched/signal.h> 10#include <linux/pagemap.h> 11#include <linux/rmap.h> 12#include <linux/swap.h> 13#include <linux/swapops.h> 14#include <linux/userfaultfd_k.h> 15#include <linux/mmu_notifier.h> 16#include <linux/hugetlb.h> 17#include <linux/shmem_fs.h> 18#include <asm/tlbflush.h> 19#include <asm/tlb.h> 20#include "internal.h" 21 22static __always_inline 23struct vm_area_struct *find_dst_vma(struct mm_struct *dst_mm, 24 unsigned long dst_start, 25 unsigned long len) 26{ 27 /* 28 * Make sure that the dst range is both valid and fully within a 29 * single existing vma. 30 */ 31 struct vm_area_struct *dst_vma; 32 33 dst_vma = find_vma(dst_mm, dst_start); 34 if (!dst_vma) 35 return NULL; 36 37 if (dst_start < dst_vma->vm_start || 38 dst_start + len > dst_vma->vm_end) 39 return NULL; 40 41 /* 42 * Check the vma is registered in uffd, this is required to 43 * enforce the VM_MAYWRITE check done at uffd registration 44 * time. 45 */ 46 if (!dst_vma->vm_userfaultfd_ctx.ctx) 47 return NULL; 48 49 return dst_vma; 50} 51 52/* 53 * Install PTEs, to map dst_addr (within dst_vma) to page. 54 * 55 * This function handles both MCOPY_ATOMIC_NORMAL and _CONTINUE for both shmem 56 * and anon, and for both shared and private VMAs. 57 */ 58int mfill_atomic_install_pte(struct mm_struct *dst_mm, pmd_t *dst_pmd, 59 struct vm_area_struct *dst_vma, 60 unsigned long dst_addr, struct page *page, 61 bool newly_allocated, bool wp_copy) 62{ 63 int ret; 64 pte_t _dst_pte, *dst_pte; 65 bool writable = dst_vma->vm_flags & VM_WRITE; 66 bool vm_shared = dst_vma->vm_flags & VM_SHARED; 67 bool page_in_cache = page->mapping; 68 spinlock_t *ptl; 69 struct inode *inode; 70 pgoff_t offset, max_off; 71 72 _dst_pte = mk_pte(page, dst_vma->vm_page_prot); 73 _dst_pte = pte_mkdirty(_dst_pte); 74 if (page_in_cache && !vm_shared) 75 writable = false; 76 77 /* 78 * Always mark a PTE as write-protected when needed, regardless of 79 * VM_WRITE, which the user might change. 80 */ 81 if (wp_copy) { 82 _dst_pte = pte_mkuffd_wp(_dst_pte); 83 writable = false; 84 } 85 86 if (writable) 87 _dst_pte = pte_mkwrite(_dst_pte); 88 else 89 /* 90 * We need this to make sure write bit removed; as mk_pte() 91 * could return a pte with write bit set. 92 */ 93 _dst_pte = pte_wrprotect(_dst_pte); 94 95 dst_pte = pte_offset_map_lock(dst_mm, dst_pmd, dst_addr, &ptl); 96 97 if (vma_is_shmem(dst_vma)) { 98 /* serialize against truncate with the page table lock */ 99 inode = dst_vma->vm_file->f_inode; 100 offset = linear_page_index(dst_vma, dst_addr); 101 max_off = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE); 102 ret = -EFAULT; 103 if (unlikely(offset >= max_off)) 104 goto out_unlock; 105 } 106 107 ret = -EEXIST; 108 /* 109 * We allow to overwrite a pte marker: consider when both MISSING|WP 110 * registered, we firstly wr-protect a none pte which has no page cache 111 * page backing it, then access the page. 112 */ 113 if (!pte_none_mostly(*dst_pte)) 114 goto out_unlock; 115 116 if (page_in_cache) { 117 /* Usually, cache pages are already added to LRU */ 118 if (newly_allocated) 119 lru_cache_add(page); 120 page_add_file_rmap(page, dst_vma, false); 121 } else { 122 page_add_new_anon_rmap(page, dst_vma, dst_addr); 123 lru_cache_add_inactive_or_unevictable(page, dst_vma); 124 } 125 126 /* 127 * Must happen after rmap, as mm_counter() checks mapping (via 128 * PageAnon()), which is set by __page_set_anon_rmap(). 129 */ 130 inc_mm_counter(dst_mm, mm_counter(page)); 131 132 set_pte_at(dst_mm, dst_addr, dst_pte, _dst_pte); 133 134 /* No need to invalidate - it was non-present before */ 135 update_mmu_cache(dst_vma, dst_addr, dst_pte); 136 ret = 0; 137out_unlock: 138 pte_unmap_unlock(dst_pte, ptl); 139 return ret; 140} 141 142static int mcopy_atomic_pte(struct mm_struct *dst_mm, 143 pmd_t *dst_pmd, 144 struct vm_area_struct *dst_vma, 145 unsigned long dst_addr, 146 unsigned long src_addr, 147 struct page **pagep, 148 bool wp_copy) 149{ 150 void *page_kaddr; 151 int ret; 152 struct page *page; 153 154 if (!*pagep) { 155 ret = -ENOMEM; 156 page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, dst_vma, dst_addr); 157 if (!page) 158 goto out; 159 160 page_kaddr = kmap_atomic(page); 161 ret = copy_from_user(page_kaddr, 162 (const void __user *) src_addr, 163 PAGE_SIZE); 164 kunmap_atomic(page_kaddr); 165 166 /* fallback to copy_from_user outside mmap_lock */ 167 if (unlikely(ret)) { 168 ret = -ENOENT; 169 *pagep = page; 170 /* don't free the page */ 171 goto out; 172 } 173 174 flush_dcache_page(page); 175 } else { 176 page = *pagep; 177 *pagep = NULL; 178 } 179 180 /* 181 * The memory barrier inside __SetPageUptodate makes sure that 182 * preceding stores to the page contents become visible before 183 * the set_pte_at() write. 184 */ 185 __SetPageUptodate(page); 186 187 ret = -ENOMEM; 188 if (mem_cgroup_charge(page_folio(page), dst_mm, GFP_KERNEL)) 189 goto out_release; 190 191 ret = mfill_atomic_install_pte(dst_mm, dst_pmd, dst_vma, dst_addr, 192 page, true, wp_copy); 193 if (ret) 194 goto out_release; 195out: 196 return ret; 197out_release: 198 put_page(page); 199 goto out; 200} 201 202static int mfill_zeropage_pte(struct mm_struct *dst_mm, 203 pmd_t *dst_pmd, 204 struct vm_area_struct *dst_vma, 205 unsigned long dst_addr) 206{ 207 pte_t _dst_pte, *dst_pte; 208 spinlock_t *ptl; 209 int ret; 210 pgoff_t offset, max_off; 211 struct inode *inode; 212 213 _dst_pte = pte_mkspecial(pfn_pte(my_zero_pfn(dst_addr), 214 dst_vma->vm_page_prot)); 215 dst_pte = pte_offset_map_lock(dst_mm, dst_pmd, dst_addr, &ptl); 216 if (dst_vma->vm_file) { 217 /* the shmem MAP_PRIVATE case requires checking the i_size */ 218 inode = dst_vma->vm_file->f_inode; 219 offset = linear_page_index(dst_vma, dst_addr); 220 max_off = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE); 221 ret = -EFAULT; 222 if (unlikely(offset >= max_off)) 223 goto out_unlock; 224 } 225 ret = -EEXIST; 226 if (!pte_none(*dst_pte)) 227 goto out_unlock; 228 set_pte_at(dst_mm, dst_addr, dst_pte, _dst_pte); 229 /* No need to invalidate - it was non-present before */ 230 update_mmu_cache(dst_vma, dst_addr, dst_pte); 231 ret = 0; 232out_unlock: 233 pte_unmap_unlock(dst_pte, ptl); 234 return ret; 235} 236 237/* Handles UFFDIO_CONTINUE for all shmem VMAs (shared or private). */ 238static int mcontinue_atomic_pte(struct mm_struct *dst_mm, 239 pmd_t *dst_pmd, 240 struct vm_area_struct *dst_vma, 241 unsigned long dst_addr, 242 bool wp_copy) 243{ 244 struct inode *inode = file_inode(dst_vma->vm_file); 245 pgoff_t pgoff = linear_page_index(dst_vma, dst_addr); 246 struct page *page; 247 int ret; 248 249 ret = shmem_getpage(inode, pgoff, &page, SGP_READ); 250 if (ret) 251 goto out; 252 if (!page) { 253 ret = -EFAULT; 254 goto out; 255 } 256 257 if (PageHWPoison(page)) { 258 ret = -EIO; 259 goto out_release; 260 } 261 262 ret = mfill_atomic_install_pte(dst_mm, dst_pmd, dst_vma, dst_addr, 263 page, false, wp_copy); 264 if (ret) 265 goto out_release; 266 267 unlock_page(page); 268 ret = 0; 269out: 270 return ret; 271out_release: 272 unlock_page(page); 273 put_page(page); 274 goto out; 275} 276 277static pmd_t *mm_alloc_pmd(struct mm_struct *mm, unsigned long address) 278{ 279 pgd_t *pgd; 280 p4d_t *p4d; 281 pud_t *pud; 282 283 pgd = pgd_offset(mm, address); 284 p4d = p4d_alloc(mm, pgd, address); 285 if (!p4d) 286 return NULL; 287 pud = pud_alloc(mm, p4d, address); 288 if (!pud) 289 return NULL; 290 /* 291 * Note that we didn't run this because the pmd was 292 * missing, the *pmd may be already established and in 293 * turn it may also be a trans_huge_pmd. 294 */ 295 return pmd_alloc(mm, pud, address); 296} 297 298#ifdef CONFIG_HUGETLB_PAGE 299/* 300 * __mcopy_atomic processing for HUGETLB vmas. Note that this routine is 301 * called with mmap_lock held, it will release mmap_lock before returning. 302 */ 303static __always_inline ssize_t __mcopy_atomic_hugetlb(struct mm_struct *dst_mm, 304 struct vm_area_struct *dst_vma, 305 unsigned long dst_start, 306 unsigned long src_start, 307 unsigned long len, 308 enum mcopy_atomic_mode mode, 309 bool wp_copy) 310{ 311 int vm_shared = dst_vma->vm_flags & VM_SHARED; 312 ssize_t err; 313 pte_t *dst_pte; 314 unsigned long src_addr, dst_addr; 315 long copied; 316 struct page *page; 317 unsigned long vma_hpagesize; 318 pgoff_t idx; 319 u32 hash; 320 struct address_space *mapping; 321 322 /* 323 * There is no default zero huge page for all huge page sizes as 324 * supported by hugetlb. A PMD_SIZE huge pages may exist as used 325 * by THP. Since we can not reliably insert a zero page, this 326 * feature is not supported. 327 */ 328 if (mode == MCOPY_ATOMIC_ZEROPAGE) { 329 mmap_read_unlock(dst_mm); 330 return -EINVAL; 331 } 332 333 src_addr = src_start; 334 dst_addr = dst_start; 335 copied = 0; 336 page = NULL; 337 vma_hpagesize = vma_kernel_pagesize(dst_vma); 338 339 /* 340 * Validate alignment based on huge page size 341 */ 342 err = -EINVAL; 343 if (dst_start & (vma_hpagesize - 1) || len & (vma_hpagesize - 1)) 344 goto out_unlock; 345 346retry: 347 /* 348 * On routine entry dst_vma is set. If we had to drop mmap_lock and 349 * retry, dst_vma will be set to NULL and we must lookup again. 350 */ 351 if (!dst_vma) { 352 err = -ENOENT; 353 dst_vma = find_dst_vma(dst_mm, dst_start, len); 354 if (!dst_vma || !is_vm_hugetlb_page(dst_vma)) 355 goto out_unlock; 356 357 err = -EINVAL; 358 if (vma_hpagesize != vma_kernel_pagesize(dst_vma)) 359 goto out_unlock; 360 361 vm_shared = dst_vma->vm_flags & VM_SHARED; 362 } 363 364 /* 365 * If not shared, ensure the dst_vma has a anon_vma. 366 */ 367 err = -ENOMEM; 368 if (!vm_shared) { 369 if (unlikely(anon_vma_prepare(dst_vma))) 370 goto out_unlock; 371 } 372 373 while (src_addr < src_start + len) { 374 BUG_ON(dst_addr >= dst_start + len); 375 376 /* 377 * Serialize via i_mmap_rwsem and hugetlb_fault_mutex. 378 * i_mmap_rwsem ensures the dst_pte remains valid even 379 * in the case of shared pmds. fault mutex prevents 380 * races with other faulting threads. 381 */ 382 mapping = dst_vma->vm_file->f_mapping; 383 i_mmap_lock_read(mapping); 384 idx = linear_page_index(dst_vma, dst_addr); 385 hash = hugetlb_fault_mutex_hash(mapping, idx); 386 mutex_lock(&hugetlb_fault_mutex_table[hash]); 387 388 err = -ENOMEM; 389 dst_pte = huge_pte_alloc(dst_mm, dst_vma, dst_addr, vma_hpagesize); 390 if (!dst_pte) { 391 mutex_unlock(&hugetlb_fault_mutex_table[hash]); 392 i_mmap_unlock_read(mapping); 393 goto out_unlock; 394 } 395 396 if (mode != MCOPY_ATOMIC_CONTINUE && 397 !huge_pte_none_mostly(huge_ptep_get(dst_pte))) { 398 err = -EEXIST; 399 mutex_unlock(&hugetlb_fault_mutex_table[hash]); 400 i_mmap_unlock_read(mapping); 401 goto out_unlock; 402 } 403 404 err = hugetlb_mcopy_atomic_pte(dst_mm, dst_pte, dst_vma, 405 dst_addr, src_addr, mode, &page, 406 wp_copy); 407 408 mutex_unlock(&hugetlb_fault_mutex_table[hash]); 409 i_mmap_unlock_read(mapping); 410 411 cond_resched(); 412 413 if (unlikely(err == -ENOENT)) { 414 mmap_read_unlock(dst_mm); 415 BUG_ON(!page); 416 417 err = copy_huge_page_from_user(page, 418 (const void __user *)src_addr, 419 vma_hpagesize / PAGE_SIZE, 420 true); 421 if (unlikely(err)) { 422 err = -EFAULT; 423 goto out; 424 } 425 mmap_read_lock(dst_mm); 426 427 dst_vma = NULL; 428 goto retry; 429 } else 430 BUG_ON(page); 431 432 if (!err) { 433 dst_addr += vma_hpagesize; 434 src_addr += vma_hpagesize; 435 copied += vma_hpagesize; 436 437 if (fatal_signal_pending(current)) 438 err = -EINTR; 439 } 440 if (err) 441 break; 442 } 443 444out_unlock: 445 mmap_read_unlock(dst_mm); 446out: 447 if (page) 448 put_page(page); 449 BUG_ON(copied < 0); 450 BUG_ON(err > 0); 451 BUG_ON(!copied && !err); 452 return copied ? copied : err; 453} 454#else /* !CONFIG_HUGETLB_PAGE */ 455/* fail at build time if gcc attempts to use this */ 456extern ssize_t __mcopy_atomic_hugetlb(struct mm_struct *dst_mm, 457 struct vm_area_struct *dst_vma, 458 unsigned long dst_start, 459 unsigned long src_start, 460 unsigned long len, 461 enum mcopy_atomic_mode mode, 462 bool wp_copy); 463#endif /* CONFIG_HUGETLB_PAGE */ 464 465static __always_inline ssize_t mfill_atomic_pte(struct mm_struct *dst_mm, 466 pmd_t *dst_pmd, 467 struct vm_area_struct *dst_vma, 468 unsigned long dst_addr, 469 unsigned long src_addr, 470 struct page **page, 471 enum mcopy_atomic_mode mode, 472 bool wp_copy) 473{ 474 ssize_t err; 475 476 if (mode == MCOPY_ATOMIC_CONTINUE) { 477 return mcontinue_atomic_pte(dst_mm, dst_pmd, dst_vma, dst_addr, 478 wp_copy); 479 } 480 481 /* 482 * The normal page fault path for a shmem will invoke the 483 * fault, fill the hole in the file and COW it right away. The 484 * result generates plain anonymous memory. So when we are 485 * asked to fill an hole in a MAP_PRIVATE shmem mapping, we'll 486 * generate anonymous memory directly without actually filling 487 * the hole. For the MAP_PRIVATE case the robustness check 488 * only happens in the pagetable (to verify it's still none) 489 * and not in the radix tree. 490 */ 491 if (!(dst_vma->vm_flags & VM_SHARED)) { 492 if (mode == MCOPY_ATOMIC_NORMAL) 493 err = mcopy_atomic_pte(dst_mm, dst_pmd, dst_vma, 494 dst_addr, src_addr, page, 495 wp_copy); 496 else 497 err = mfill_zeropage_pte(dst_mm, dst_pmd, 498 dst_vma, dst_addr); 499 } else { 500 err = shmem_mfill_atomic_pte(dst_mm, dst_pmd, dst_vma, 501 dst_addr, src_addr, 502 mode != MCOPY_ATOMIC_NORMAL, 503 wp_copy, page); 504 } 505 506 return err; 507} 508 509static __always_inline ssize_t __mcopy_atomic(struct mm_struct *dst_mm, 510 unsigned long dst_start, 511 unsigned long src_start, 512 unsigned long len, 513 enum mcopy_atomic_mode mcopy_mode, 514 atomic_t *mmap_changing, 515 __u64 mode) 516{ 517 struct vm_area_struct *dst_vma; 518 ssize_t err; 519 pmd_t *dst_pmd; 520 unsigned long src_addr, dst_addr; 521 long copied; 522 struct page *page; 523 bool wp_copy; 524 525 /* 526 * Sanitize the command parameters: 527 */ 528 BUG_ON(dst_start & ~PAGE_MASK); 529 BUG_ON(len & ~PAGE_MASK); 530 531 /* Does the address range wrap, or is the span zero-sized? */ 532 BUG_ON(src_start + len <= src_start); 533 BUG_ON(dst_start + len <= dst_start); 534 535 src_addr = src_start; 536 dst_addr = dst_start; 537 copied = 0; 538 page = NULL; 539retry: 540 mmap_read_lock(dst_mm); 541 542 /* 543 * If memory mappings are changing because of non-cooperative 544 * operation (e.g. mremap) running in parallel, bail out and 545 * request the user to retry later 546 */ 547 err = -EAGAIN; 548 if (mmap_changing && atomic_read(mmap_changing)) 549 goto out_unlock; 550 551 /* 552 * Make sure the vma is not shared, that the dst range is 553 * both valid and fully within a single existing vma. 554 */ 555 err = -ENOENT; 556 dst_vma = find_dst_vma(dst_mm, dst_start, len); 557 if (!dst_vma) 558 goto out_unlock; 559 560 err = -EINVAL; 561 /* 562 * shmem_zero_setup is invoked in mmap for MAP_ANONYMOUS|MAP_SHARED but 563 * it will overwrite vm_ops, so vma_is_anonymous must return false. 564 */ 565 if (WARN_ON_ONCE(vma_is_anonymous(dst_vma) && 566 dst_vma->vm_flags & VM_SHARED)) 567 goto out_unlock; 568 569 /* 570 * validate 'mode' now that we know the dst_vma: don't allow 571 * a wrprotect copy if the userfaultfd didn't register as WP. 572 */ 573 wp_copy = mode & UFFDIO_COPY_MODE_WP; 574 if (wp_copy && !(dst_vma->vm_flags & VM_UFFD_WP)) 575 goto out_unlock; 576 577 /* 578 * If this is a HUGETLB vma, pass off to appropriate routine 579 */ 580 if (is_vm_hugetlb_page(dst_vma)) 581 return __mcopy_atomic_hugetlb(dst_mm, dst_vma, dst_start, 582 src_start, len, mcopy_mode, 583 wp_copy); 584 585 if (!vma_is_anonymous(dst_vma) && !vma_is_shmem(dst_vma)) 586 goto out_unlock; 587 if (!vma_is_shmem(dst_vma) && mcopy_mode == MCOPY_ATOMIC_CONTINUE) 588 goto out_unlock; 589 590 /* 591 * Ensure the dst_vma has a anon_vma or this page 592 * would get a NULL anon_vma when moved in the 593 * dst_vma. 594 */ 595 err = -ENOMEM; 596 if (!(dst_vma->vm_flags & VM_SHARED) && 597 unlikely(anon_vma_prepare(dst_vma))) 598 goto out_unlock; 599 600 while (src_addr < src_start + len) { 601 pmd_t dst_pmdval; 602 603 BUG_ON(dst_addr >= dst_start + len); 604 605 dst_pmd = mm_alloc_pmd(dst_mm, dst_addr); 606 if (unlikely(!dst_pmd)) { 607 err = -ENOMEM; 608 break; 609 } 610 611 dst_pmdval = pmd_read_atomic(dst_pmd); 612 /* 613 * If the dst_pmd is mapped as THP don't 614 * override it and just be strict. 615 */ 616 if (unlikely(pmd_trans_huge(dst_pmdval))) { 617 err = -EEXIST; 618 break; 619 } 620 if (unlikely(pmd_none(dst_pmdval)) && 621 unlikely(__pte_alloc(dst_mm, dst_pmd))) { 622 err = -ENOMEM; 623 break; 624 } 625 /* If an huge pmd materialized from under us fail */ 626 if (unlikely(pmd_trans_huge(*dst_pmd))) { 627 err = -EFAULT; 628 break; 629 } 630 631 BUG_ON(pmd_none(*dst_pmd)); 632 BUG_ON(pmd_trans_huge(*dst_pmd)); 633 634 err = mfill_atomic_pte(dst_mm, dst_pmd, dst_vma, dst_addr, 635 src_addr, &page, mcopy_mode, wp_copy); 636 cond_resched(); 637 638 if (unlikely(err == -ENOENT)) { 639 void *page_kaddr; 640 641 mmap_read_unlock(dst_mm); 642 BUG_ON(!page); 643 644 page_kaddr = kmap(page); 645 err = copy_from_user(page_kaddr, 646 (const void __user *) src_addr, 647 PAGE_SIZE); 648 kunmap(page); 649 if (unlikely(err)) { 650 err = -EFAULT; 651 goto out; 652 } 653 flush_dcache_page(page); 654 goto retry; 655 } else 656 BUG_ON(page); 657 658 if (!err) { 659 dst_addr += PAGE_SIZE; 660 src_addr += PAGE_SIZE; 661 copied += PAGE_SIZE; 662 663 if (fatal_signal_pending(current)) 664 err = -EINTR; 665 } 666 if (err) 667 break; 668 } 669 670out_unlock: 671 mmap_read_unlock(dst_mm); 672out: 673 if (page) 674 put_page(page); 675 BUG_ON(copied < 0); 676 BUG_ON(err > 0); 677 BUG_ON(!copied && !err); 678 return copied ? copied : err; 679} 680 681ssize_t mcopy_atomic(struct mm_struct *dst_mm, unsigned long dst_start, 682 unsigned long src_start, unsigned long len, 683 atomic_t *mmap_changing, __u64 mode) 684{ 685 return __mcopy_atomic(dst_mm, dst_start, src_start, len, 686 MCOPY_ATOMIC_NORMAL, mmap_changing, mode); 687} 688 689ssize_t mfill_zeropage(struct mm_struct *dst_mm, unsigned long start, 690 unsigned long len, atomic_t *mmap_changing) 691{ 692 return __mcopy_atomic(dst_mm, start, 0, len, MCOPY_ATOMIC_ZEROPAGE, 693 mmap_changing, 0); 694} 695 696ssize_t mcopy_continue(struct mm_struct *dst_mm, unsigned long start, 697 unsigned long len, atomic_t *mmap_changing) 698{ 699 return __mcopy_atomic(dst_mm, start, 0, len, MCOPY_ATOMIC_CONTINUE, 700 mmap_changing, 0); 701} 702 703int mwriteprotect_range(struct mm_struct *dst_mm, unsigned long start, 704 unsigned long len, bool enable_wp, 705 atomic_t *mmap_changing) 706{ 707 struct vm_area_struct *dst_vma; 708 unsigned long page_mask; 709 struct mmu_gather tlb; 710 pgprot_t newprot; 711 int err; 712 713 /* 714 * Sanitize the command parameters: 715 */ 716 BUG_ON(start & ~PAGE_MASK); 717 BUG_ON(len & ~PAGE_MASK); 718 719 /* Does the address range wrap, or is the span zero-sized? */ 720 BUG_ON(start + len <= start); 721 722 mmap_read_lock(dst_mm); 723 724 /* 725 * If memory mappings are changing because of non-cooperative 726 * operation (e.g. mremap) running in parallel, bail out and 727 * request the user to retry later 728 */ 729 err = -EAGAIN; 730 if (mmap_changing && atomic_read(mmap_changing)) 731 goto out_unlock; 732 733 err = -ENOENT; 734 dst_vma = find_dst_vma(dst_mm, start, len); 735 736 if (!dst_vma) 737 goto out_unlock; 738 if (!userfaultfd_wp(dst_vma)) 739 goto out_unlock; 740 if (!vma_can_userfault(dst_vma, dst_vma->vm_flags)) 741 goto out_unlock; 742 743 if (is_vm_hugetlb_page(dst_vma)) { 744 err = -EINVAL; 745 page_mask = vma_kernel_pagesize(dst_vma) - 1; 746 if ((start & page_mask) || (len & page_mask)) 747 goto out_unlock; 748 } 749 750 if (enable_wp) 751 newprot = vm_get_page_prot(dst_vma->vm_flags & ~(VM_WRITE)); 752 else 753 newprot = vm_get_page_prot(dst_vma->vm_flags); 754 755 tlb_gather_mmu(&tlb, dst_mm); 756 change_protection(&tlb, dst_vma, start, start + len, newprot, 757 enable_wp ? MM_CP_UFFD_WP : MM_CP_UFFD_WP_RESOLVE); 758 tlb_finish_mmu(&tlb); 759 760 err = 0; 761out_unlock: 762 mmap_read_unlock(dst_mm); 763 return err; 764}