Module Name:    src
Committed By:   ad
Date:           Fri Apr 10 17:26:47 UTC 2020

Modified Files:
        src/sys/uvm: uvm_map.c

Log Message:
uvmspace_exec(): set VM_MAP_DYING for the duration, so pmap_update() is not
called until the pmap has been totally cleared out after pmap_remove_all(),
or it can confuse some pmap implementations.


To generate a diff of this commit:
cvs rdiff -u -r1.377 -r1.378 src/sys/uvm/uvm_map.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/uvm/uvm_map.c
diff -u src/sys/uvm/uvm_map.c:1.377 src/sys/uvm/uvm_map.c:1.378
--- src/sys/uvm/uvm_map.c:1.377	Sat Apr  4 21:17:02 2020
+++ src/sys/uvm/uvm_map.c	Fri Apr 10 17:26:46 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: uvm_map.c,v 1.377 2020/04/04 21:17:02 ad Exp $	*/
+/*	$NetBSD: uvm_map.c,v 1.378 2020/04/10 17:26:46 ad Exp $	*/
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.377 2020/04/04 21:17:02 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.378 2020/04/10 17:26:46 ad Exp $");
 
 #include "opt_ddb.h"
 #include "opt_pax.h"
@@ -2266,7 +2266,10 @@ uvm_unmap_remove(struct vm_map *map, vad
 
 			/*
 			 * note: if map is dying, leave pmap_update() for
-			 * pmap_destroy(), which will be called later.
+			 * later.  if the map is to be reused (exec) then
+			 * pmap_update() will be called.  if the map is
+			 * being disposed of (exit) then pmap_destroy()
+			 * will be called.
 			 */
 
 			if ((map->flags & VM_MAP_DYING) == 0) {
@@ -4167,11 +4170,23 @@ uvmspace_exec(struct lwp *l, vaddr_t sta
 		map->flags &= ~VM_MAP_WIREFUTURE;
 
 		/*
-		 * now unmap the old program
+		 * now unmap the old program.
+		 * 
+		 * XXX set VM_MAP_DYING for the duration, so pmap_update()
+		 * is not called until the pmap has been totally cleared out
+		 * after pmap_remove_all(), or it can confuse some pmap
+		 * implementations.  it would be nice to handle this by
+		 * deferring the pmap_update() while it is known the address
+		 * space is not visible to any user LWP other than curlwp,
+		 * but there isn't an elegant way of inferring that right
+		 * now.
 		 */
 
 		flags = pmap_remove_all(map->pmap) ? UVM_FLAG_VAONLY : 0;
+		map->flags |= VM_MAP_DYING;
 		uvm_unmap1(map, vm_map_min(map), vm_map_max(map), flags);
+		map->flags &= ~VM_MAP_DYING;
+		pmap_update(map->pmap);
 		KASSERT(map->header.prev == &map->header);
 		KASSERT(map->nentries == 0);
 

Reply via email to