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