Module Name:    src
Committed By:   kre
Date:           Thu Mar 14 19:10:04 UTC 2019

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

Log Message:
Avoid a panic from the sequence

        mlock(buf, 0);
        munlock(buf, 0);
        mlock(buf, page);
        munlock(buf, page);

where buf is page aligned, and page is actually anything > 0
(but not too big) which will get rounded up to the next multiple
of the page size.

In that sequence, it is possible that the 1st munlock() is optional.

Add a KASSERT() (or two) to detect the first effects of the problem
(without that, or in !DIAGNOSTIC kernels) the problem eventually
causes some kind of problem or other (most often still a panic.)

After this, mlock(anything, 0) (or munlock) validates "anything"
but is otherwise a no-op (regardless of the alignment of anything).

Also, don't treat mlock(buf, verybig) as equivalent to mlock(buf, 0)
which is (more or less) what we had been doing.

XXX pullup -8 (maybe -7 as well, need to check).


To generate a diff of this commit:
cvs rdiff -u -r1.358 -r1.359 src/sys/uvm/uvm_map.c
cvs rdiff -u -r1.169 -r1.170 src/sys/uvm/uvm_mmap.c
cvs rdiff -u -r1.198 -r1.199 src/sys/uvm/uvm_page.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.358 src/sys/uvm/uvm_map.c:1.359
--- src/sys/uvm/uvm_map.c:1.358	Sun Mar  3 17:37:36 2019
+++ src/sys/uvm/uvm_map.c	Thu Mar 14 19:10:04 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: uvm_map.c,v 1.358 2019/03/03 17:37:36 maxv Exp $	*/
+/*	$NetBSD: uvm_map.c,v 1.359 2019/03/14 19:10:04 kre 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.358 2019/03/03 17:37:36 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.359 2019/03/14 19:10:04 kre Exp $");
 
 #include "opt_ddb.h"
 #include "opt_pax.h"
@@ -3359,6 +3359,14 @@ uvm_map_pageable(struct vm_map *map, vad
 	}
 	entry = start_entry;
 
+	if (start == end) {		/* nothing required */
+		if ((lockflags & UVM_LK_EXIT) == 0)
+			vm_map_unlock(map);
+
+		UVMHIST_LOG(maphist,"<- done (nothing)",0,0,0,0);
+		return 0;
+	}
+
 	/*
 	 * handle wiring and unwiring separately.
 	 */

Index: src/sys/uvm/uvm_mmap.c
diff -u src/sys/uvm/uvm_mmap.c:1.169 src/sys/uvm/uvm_mmap.c:1.170
--- src/sys/uvm/uvm_mmap.c:1.169	Tue Dec 19 18:34:47 2017
+++ src/sys/uvm/uvm_mmap.c	Thu Mar 14 19:10:04 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: uvm_mmap.c,v 1.169 2017/12/19 18:34:47 kamil Exp $	*/
+/*	$NetBSD: uvm_mmap.c,v 1.170 2019/03/14 19:10:04 kre Exp $	*/
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -46,7 +46,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_mmap.c,v 1.169 2017/12/19 18:34:47 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_mmap.c,v 1.170 2019/03/14 19:10:04 kre Exp $");
 
 #include "opt_compat_netbsd.h"
 #include "opt_pax.h"
@@ -759,8 +759,12 @@ sys_mlock(struct lwp *l, const struct sy
 
 	pageoff = (addr & PAGE_MASK);
 	addr -= pageoff;
-	size += pageoff;
-	size = (vsize_t)round_page(size);
+	if (size != 0) {
+		size += pageoff;
+		size = (vsize_t)round_page(size);
+	}
+	if (addr + size < addr)
+		return ENOMEM;
 
 	error = range_test(&p->p_vmspace->vm_map, addr, size, false);
 	if (error)
@@ -810,8 +814,12 @@ sys_munlock(struct lwp *l, const struct 
 
 	pageoff = (addr & PAGE_MASK);
 	addr -= pageoff;
-	size += pageoff;
-	size = (vsize_t)round_page(size);
+	if (size != 0) {
+		size += pageoff;
+		size = (vsize_t)round_page(size);
+	}
+	if (addr + size < addr)
+		return ENOMEM;
 
 	error = range_test(&p->p_vmspace->vm_map, addr, size, false);
 	if (error)

Index: src/sys/uvm/uvm_page.c
diff -u src/sys/uvm/uvm_page.c:1.198 src/sys/uvm/uvm_page.c:1.199
--- src/sys/uvm/uvm_page.c:1.198	Sat May 19 15:03:26 2018
+++ src/sys/uvm/uvm_page.c	Thu Mar 14 19:10:04 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: uvm_page.c,v 1.198 2018/05/19 15:03:26 jdolecek Exp $	*/
+/*	$NetBSD: uvm_page.c,v 1.199 2019/03/14 19:10:04 kre Exp $	*/
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_page.c,v 1.198 2018/05/19 15:03:26 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_page.c,v 1.199 2019/03/14 19:10:04 kre Exp $");
 
 #include "opt_ddb.h"
 #include "opt_uvm.h"
@@ -1605,9 +1605,11 @@ void
 uvm_pageunwire(struct vm_page *pg)
 {
 	KASSERT(mutex_owned(&uvm_pageqlock));
+	KASSERT(pg->wire_count != 0);
 	pg->wire_count--;
 	if (pg->wire_count == 0) {
 		uvm_pageactivate(pg);
+		KASSERT(uvmexp.wired != 0);
 		uvmexp.wired--;
 	}
 }

Reply via email to