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