These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / mm / mprotect.c
index 8858483..ef5be8e 100644 (file)
@@ -29,6 +29,8 @@
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 
+#include "internal.h"
+
 /*
  * For a prot_numa update we only hold mmap_sem for read so there is a
  * potential race with faulting where a pmd was temporarily none. This
@@ -290,7 +292,8 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
         */
        pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
        *pprev = vma_merge(mm, *pprev, start, end, newflags,
-                       vma->anon_vma, vma->vm_file, pgoff, vma_policy(vma));
+                          vma->anon_vma, vma->vm_file, pgoff, vma_policy(vma),
+                          vma->vm_userfaultfd_ctx);
        if (*pprev) {
                vma = *pprev;
                goto success;
@@ -322,6 +325,15 @@ success:
        change_protection(vma, start, end, vma->vm_page_prot,
                          dirty_accountable, 0);
 
+       /*
+        * Private VM_LOCKED VMA becoming writable: trigger COW to avoid major
+        * fault on access.
+        */
+       if ((oldflags & (VM_WRITE | VM_SHARED | VM_LOCKED)) == VM_LOCKED &&
+                       (newflags & VM_WRITE)) {
+               populate_vma_page_range(vma, start, end, NULL);
+       }
+
        vm_stat_account(mm, oldflags, vma->vm_file, -nrpages);
        vm_stat_account(mm, newflags, vma->vm_file, nrpages);
        perf_event_mmap(vma);