.. | .. |
---|
623 | 623 | result = SCAN_PTE_NON_PRESENT; |
---|
624 | 624 | goto out; |
---|
625 | 625 | } |
---|
| 626 | + if (pte_uffd_wp(pteval)) { |
---|
| 627 | + result = SCAN_PTE_UFFD_WP; |
---|
| 628 | + goto out; |
---|
| 629 | + } |
---|
626 | 630 | page = vm_normal_page(vma, address, pteval); |
---|
627 | 631 | if (unlikely(!page)) { |
---|
628 | 632 | result = SCAN_PAGE_NULL; |
---|
.. | .. |
---|
1464 | 1468 | if (!hugepage_vma_check(vma, vma->vm_flags | VM_HUGEPAGE)) |
---|
1465 | 1469 | return; |
---|
1466 | 1470 | |
---|
1467 | | - /* |
---|
1468 | | - * Symmetry with retract_page_tables(): Exclude MAP_PRIVATE mappings |
---|
1469 | | - * that got written to. Without this, we'd have to also lock the |
---|
1470 | | - * anon_vma if one exists. |
---|
1471 | | - */ |
---|
1472 | | - if (vma->anon_vma) |
---|
1473 | | - return; |
---|
1474 | | - |
---|
1475 | 1471 | hpage = find_lock_page(vma->vm_file->f_mapping, |
---|
1476 | 1472 | linear_page_index(vma, haddr)); |
---|
1477 | 1473 | if (!hpage) |
---|
.. | .. |
---|
1545 | 1541 | } |
---|
1546 | 1542 | |
---|
1547 | 1543 | /* step 4: collapse pmd */ |
---|
| 1544 | + /* we make no change to anon, but protect concurrent anon page lookup */ |
---|
| 1545 | + if (vma->anon_vma) |
---|
| 1546 | + anon_vma_lock_write(vma->anon_vma); |
---|
| 1547 | + |
---|
1548 | 1548 | mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, NULL, mm, haddr, |
---|
1549 | 1549 | haddr + HPAGE_PMD_SIZE); |
---|
1550 | 1550 | mmu_notifier_invalidate_range_start(&range); |
---|
.. | .. |
---|
1555 | 1555 | mmu_notifier_invalidate_range_end(&range); |
---|
1556 | 1556 | pte_free(mm, pmd_pgtable(_pmd)); |
---|
1557 | 1557 | |
---|
| 1558 | + if (vma->anon_vma) |
---|
| 1559 | + anon_vma_unlock_write(vma->anon_vma); |
---|
1558 | 1560 | i_mmap_unlock_write(vma->vm_file->f_mapping); |
---|
1559 | 1561 | |
---|
1560 | 1562 | drop_hpage: |
---|