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);