diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2015-10-01 20:27:52 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2015-10-01 20:27:52 +0000 |
commit | e6a0a6e216ba3a5bebbb9dc72bd315eb388b8083 (patch) | |
tree | 7a7d2ad7d9e91dd1b8caf11601760b6f9ba0875e /sys/uvm | |
parent | e0593ea460688731a4e2540aee568dad68a40c53 (diff) |
In uvm_map_splitentry(), grab the kernel lock before calling into the amap
or pager code. We may end up here without holding the kernel lock from
uvm_unmap().
"ja ja" tedu@
Diffstat (limited to 'sys/uvm')
-rw-r--r-- | sys/uvm/uvm_map.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/sys/uvm/uvm_map.c b/sys/uvm/uvm_map.c index c03d8aee300..cc0f914dcf1 100644 --- a/sys/uvm/uvm_map.c +++ b/sys/uvm/uvm_map.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_map.c,v 1.201 2015/09/28 18:33:42 tedu Exp $ */ +/* $OpenBSD: uvm_map.c,v 1.202 2015/10/01 20:27:51 kettenis Exp $ */ /* $NetBSD: uvm_map.c,v 1.86 2000/11/27 08:40:03 chs Exp $ */ /* @@ -2573,16 +2573,21 @@ uvm_map_splitentry(struct vm_map *map, struct vm_map_entry *orig, orig->guard = 0; orig->end = next->start = split; - if (next->aref.ar_amap) + if (next->aref.ar_amap) { + KERNEL_LOCK(); amap_splitref(&orig->aref, &next->aref, adj); + KERNEL_UNLOCK(); + } if (UVM_ET_ISSUBMAP(orig)) { uvm_map_reference(next->object.sub_map); next->offset += adj; } else if (UVM_ET_ISOBJ(orig)) { if (next->object.uvm_obj->pgops && next->object.uvm_obj->pgops->pgo_reference) { + KERNEL_LOCK(); next->object.uvm_obj->pgops->pgo_reference( next->object.uvm_obj); + KERNEL_UNLOCK(); } next->offset += adj; } |