Module Name:    src
Committed By:   ad
Date:           Sun Jan 12 17:46:56 UTC 2020

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

Log Message:
- uvm_unmap_remove(): need to call pmap_update() with the object still
  locked, otherwise the page could gain a new identity and still be visible
  via a stale mapping.

- Adjust reference counts with atomics.


To generate a diff of this commit:
cvs rdiff -u -r1.370 -r1.371 src/sys/uvm/uvm_map.c
cvs rdiff -u -r1.76 -r1.77 src/sys/uvm/uvm_map.h

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.370 src/sys/uvm/uvm_map.c:1.371
--- src/sys/uvm/uvm_map.c:1.370	Sun Jan  5 15:57:15 2020
+++ src/sys/uvm/uvm_map.c	Sun Jan 12 17:46:55 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: uvm_map.c,v 1.370 2020/01/05 15:57:15 para Exp $	*/
+/*	$NetBSD: uvm_map.c,v 1.371 2020/01/12 17:46:55 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.370 2020/01/05 15:57:15 para Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.371 2020/01/12 17:46:55 ad Exp $");
 
 #include "opt_ddb.h"
 #include "opt_pax.h"
@@ -2240,7 +2240,7 @@ uvm_unmap_remove(struct vm_map *map, vad
 	}
 
 	/*
-	 * Save the free space hint
+	 * save the free space hint
 	 */
 
 	if (map->first_free != &map->header && map->first_free->start >= start)
@@ -2314,6 +2314,18 @@ uvm_unmap_remove(struct vm_map *map, vad
 
 			uvm_map_lock_entry(entry);
 			pmap_remove(map->pmap, entry->start, entry->end);
+
+			/*
+			 * note: if map is dying, leave pmap_update() for
+			 * pmap_destroy(), which will be called later.
+			 */
+
+			if ((map->flags & VM_MAP_DYING) == 0) {
+				pmap_update(vm_map_pmap(map));
+			} else {
+				KASSERT(vm_map_pmap(map) != pmap_kernel());
+			}
+
 			uvm_map_unlock_entry(entry);
 		}
 
@@ -2358,16 +2370,6 @@ uvm_unmap_remove(struct vm_map *map, vad
 		entry = next;
 	}
 
-	/*
-	 * Note: if map is dying, leave pmap_update() for pmap_destroy(),
-	 * which will be called later.
-	 */
-	if ((map->flags & VM_MAP_DYING) == 0) {
-		pmap_update(vm_map_pmap(map));
-	} else {
-		KASSERT(vm_map_pmap(map) != pmap_kernel());
-	}
-
 	uvm_map_check(map, "unmap_remove leave");
 
 	/*
@@ -4254,14 +4256,10 @@ uvmspace_exec(struct lwp *l, vaddr_t sta
 void
 uvmspace_addref(struct vmspace *vm)
 {
-	struct vm_map *map = &vm->vm_map;
-
-	KASSERT((map->flags & VM_MAP_DYING) == 0);
 
-	mutex_enter(&map->misc_lock);
+	KASSERT((vm->vm_map.flags & VM_MAP_DYING) == 0);
 	KASSERT(vm->vm_refcnt > 0);
-	vm->vm_refcnt++;
-	mutex_exit(&map->misc_lock);
+	atomic_inc_uint(&vm->vm_refcnt);
 }
 
 /*
@@ -4273,16 +4271,12 @@ uvmspace_free(struct vmspace *vm)
 {
 	struct vm_map_entry *dead_entries;
 	struct vm_map *map = &vm->vm_map;
-	int n;
 
 	UVMHIST_FUNC("uvmspace_free"); UVMHIST_CALLED(maphist);
 
 	UVMHIST_LOG(maphist,"(vm=%#jx) ref=%jd", (uintptr_t)vm, vm->vm_refcnt,
 	    0, 0);
-	mutex_enter(&map->misc_lock);
-	n = --vm->vm_refcnt;
-	mutex_exit(&map->misc_lock);
-	if (n > 0)
+	if (atomic_dec_uint_nv(&vm->vm_refcnt) > 0)
 		return;
 
 	/*
@@ -4777,15 +4771,14 @@ uvm_unmap1(struct vm_map *map, vaddr_t s
 /*
  * uvm_map_reference: add reference to a map
  *
- * => map need not be locked (we use misc_lock).
+ * => map need not be locked
  */
 
 void
 uvm_map_reference(struct vm_map *map)
 {
-	mutex_enter(&map->misc_lock);
-	map->ref_count++;
-	mutex_exit(&map->misc_lock);
+
+	atomic_inc_uint(&map->ref_count);
 }
 
 void

Index: src/sys/uvm/uvm_map.h
diff -u src/sys/uvm/uvm_map.h:1.76 src/sys/uvm/uvm_map.h:1.77
--- src/sys/uvm/uvm_map.h:1.76	Sun Jan  5 15:57:15 2020
+++ src/sys/uvm/uvm_map.h	Sun Jan 12 17:46:55 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: uvm_map.h,v 1.76 2020/01/05 15:57:15 para Exp $	*/
+/*	$NetBSD: uvm_map.h,v 1.77 2020/01/12 17:46:55 ad Exp $	*/
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -209,7 +209,7 @@ struct vm_map {
 	struct pmap *		pmap;		/* Physical map */
 	krwlock_t		lock;		/* Non-intrsafe lock */
 	struct lwp *		busy;		/* LWP holding map busy */
-	kmutex_t		misc_lock;	/* Lock for ref_count, cv */
+	kmutex_t		misc_lock;	/* Lock for cv, busy */
 	kcondvar_t		cv;		/* For signalling */
 	int			flags;		/* flags */
 	struct rb_tree		rb_tree;	/* Tree for entries */

Reply via email to