Address the case 2b version of inconsistent view across threads of
authorguenther <guenther@openbsd.org>
Tue, 5 Sep 2023 05:08:26 +0000 (05:08 +0000)
committerguenther <guenther@openbsd.org>
Tue, 5 Sep 2023 05:08:26 +0000 (05:08 +0000)
a page undergoing copy-on-write faulting.  We fixed the case 1b
version in rev 1.125 (2022-02-01), but missed this other path.

jsg@ noted that in NetBSD Chuck Silvers had a relevant commit, their
rev 1.234 (2023-08-13), which looks like it fixed both cases due
to their refactoring of common code into a uvmfault_promote()
function.

ok mpi@ jca@

sys/uvm/uvm_fault.c

index 28fa1da..1ae20b5 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uvm_fault.c,v 1.134 2023/09/02 08:24:40 mpi Exp $     */
+/*     $OpenBSD: uvm_fault.c,v 1.135 2023/09/05 05:08:26 guenther Exp $        */
 /*     $NetBSD: uvm_fault.c,v 1.51 2000/08/06 00:22:53 thorpej Exp $   */
 
 /*
@@ -1455,7 +1455,20 @@ uvm_fault_lower(struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
                         */
                        if ((amap_flags(amap) & AMAP_SHARED) != 0) {
                                pmap_page_protect(uobjpage, PROT_NONE);
-                               }
+                       }
+#if defined(MULTIPROCESSOR) && !defined(__HAVE_PMAP_MPSAFE_ENTER_COW)
+                       /*
+                        * Otherwise:
+                        * If there are multiple threads, either uvm or the
+                        * pmap has to make sure no threads see the old RO
+                        * mapping once any have seen the new RW mapping.
+                        * uvm does it here by forcing it to PROT_NONE before
+                        * inserting the new mapping.
+                        */
+                       else if (P_HASSIBLING(curproc)) {
+                               pmap_page_protect(uobjpage, PROT_NONE);
+                       }
+#endif
 
                        /* dispose of uobjpage. drop handle to uobj as well. */
                        if (uobjpage->pg_flags & PG_WANTED)