diff options
author | 2021-03-15 09:17:54 -0300 | |
---|---|---|
committer | 2021-03-15 09:17:54 -0300 | |
commit | 689bb69093d7ac9e12ab058ba2611ad5eb9347c3 (patch) | |
tree | abb9131ea54d7c9df78e192b31a0c09635f8acab /mm/memory.c | |
parent | perf synthetic events: Avoid write of uninitialized memory when generating PERF_RECORD_MMAP* records (diff) | |
parent | Linux 5.12-rc3 (diff) | |
download | linux-rng-689bb69093d7ac9e12ab058ba2611ad5eb9347c3.tar.xz linux-rng-689bb69093d7ac9e12ab058ba2611ad5eb9347c3.zip |
Merge remote-tracking branch 'torvalds/master' into perf/urgent
To update kernel headers and check if some need syncing.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'mm/memory.c')
-rw-r--r-- | mm/memory.c | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/mm/memory.c b/mm/memory.c index c8e357627318..5efa07fb6cdc 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -809,12 +809,8 @@ copy_present_page(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma pte_t *dst_pte, pte_t *src_pte, unsigned long addr, int *rss, struct page **prealloc, pte_t pte, struct page *page) { - struct mm_struct *src_mm = src_vma->vm_mm; struct page *new_page; - if (!is_cow_mapping(src_vma->vm_flags)) - return 1; - /* * What we want to do is to check whether this page may * have been pinned by the parent process. If so, @@ -828,9 +824,7 @@ copy_present_page(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma * the page count. That might give false positives for * for pinning, but it will work correctly. */ - if (likely(!atomic_read(&src_mm->has_pinned))) - return 1; - if (likely(!page_maybe_dma_pinned(page))) + if (likely(!page_needs_cow_for_dma(src_vma, page))) return 1; new_page = *prealloc; @@ -3103,6 +3097,14 @@ static vm_fault_t do_wp_page(struct vm_fault *vmf) return handle_userfault(vmf, VM_UFFD_WP); } + /* + * Userfaultfd write-protect can defer flushes. Ensure the TLB + * is flushed in this case before copying. + */ + if (unlikely(userfaultfd_wp(vmf->vma) && + mm_tlb_flush_pending(vmf->vma->vm_mm))) + flush_tlb_page(vmf->vma, vmf->address); + vmf->page = vm_normal_page(vma, vmf->address, vmf->orig_pte); if (!vmf->page) { /* |