Author: kib
Date: Wed Mar 27 11:03:07 2019
New Revision: 345572
URL: https://svnweb.freebsd.org/changeset/base/345572

Log:
  MFC r345324:
  vm_fault_copy_entry: accept invalid source pages.

Modified:
  stable/11/sys/vm/vm_fault.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/vm/vm_fault.c
==============================================================================
--- stable/11/sys/vm/vm_fault.c Wed Mar 27 10:58:37 2019        (r345571)
+++ stable/11/sys/vm/vm_fault.c Wed Mar 27 11:03:07 2019        (r345572)
@@ -1705,8 +1705,7 @@ again:
                        }
                        pmap_copy_page(src_m, dst_m);
                        VM_OBJECT_RUNLOCK(object);
-                       dst_m->valid = VM_PAGE_BITS_ALL;
-                       dst_m->dirty = VM_PAGE_BITS_ALL;
+                       dst_m->dirty = dst_m->valid = src_m->valid;
                } else {
                        dst_m = src_m;
                        if (vm_page_sleep_if_busy(dst_m, "fltupg"))
@@ -1719,8 +1718,6 @@ again:
                                 */
                                break;
                        vm_page_xbusy(dst_m);
-                       KASSERT(dst_m->valid == VM_PAGE_BITS_ALL,
-                           ("invalid dst page %p", dst_m));
                }
                VM_OBJECT_WUNLOCK(dst_object);
 
@@ -1728,9 +1725,18 @@ again:
                 * Enter it in the pmap. If a wired, copy-on-write
                 * mapping is being replaced by a write-enabled
                 * mapping, then wire that new mapping.
+                *
+                * The page can be invalid if the user called
+                * msync(MS_INVALIDATE) or truncated the backing vnode
+                * or shared memory object.  In this case, do not
+                * insert it into pmap, but still do the copy so that
+                * all copies of the wired map entry have similar
+                * backing pages.
                 */
-               pmap_enter(dst_map->pmap, vaddr, dst_m, prot,
-                   access | (upgrade ? PMAP_ENTER_WIRED : 0), 0);
+               if (dst_m->valid == VM_PAGE_BITS_ALL) {
+                       pmap_enter(dst_map->pmap, vaddr, dst_m, prot,
+                           access | (upgrade ? PMAP_ENTER_WIRED : 0), 0);
+               }
 
                /*
                 * Mark it no longer busy, and put it on the active list.
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to