summaryrefslogtreecommitdiffstats
path: root/mm/memory.c
diff options
context:
space:
mode:
authorBorislav Petkov <bp@suse.de>2021-03-15 10:49:00 +0100
committerBorislav Petkov <bp@suse.de>2021-03-15 10:49:00 +0100
commitaa7680f6fe21ba92c3d633e345f85d4125cd56f1 (patch)
tree238310342ae16eb5a2cdc9e032d972936cc3fe77 /mm/memory.c
parentd0962f2b24c99889a386f0658c71535f56358f77 (diff)
parent1e28eed17697bcf343c6743f0028cc3b5dd88bf0 (diff)
downloadlinux-aa7680f6fe21ba92c3d633e345f85d4125cd56f1.tar.gz
linux-aa7680f6fe21ba92c3d633e345f85d4125cd56f1.tar.bz2
linux-aa7680f6fe21ba92c3d633e345f85d4125cd56f1.zip
Merge tag 'v5.12-rc3' into x86/core
Pick up dependent SEV-ES urgent changes to base new work ontop. Signed-off-by: Borislav Petkov <bp@suse.de>
Diffstat (limited to 'mm/memory.c')
-rw-r--r--mm/memory.c16
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) {
/*