summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkettenis <kettenis@openbsd.org>2015-09-26 17:55:00 +0000
committerkettenis <kettenis@openbsd.org>2015-09-26 17:55:00 +0000
commit30cd453528f457f0faf4cb341d4eb43948c6ce08 (patch)
treea5c6ec4a2686a7dd08bec1861ada8519bab6b476
parentUse ASN1_item_dup() instead of ASN1_dup(). (diff)
downloadwireguard-openbsd-30cd453528f457f0faf4cb341d4eb43948c6ce08.tar.xz
wireguard-openbsd-30cd453528f457f0faf4cb341d4eb43948c6ce08.zip
Protect the list of free map entries with a mutex. This should fix the
crashes seen by sthen@ on i386. ok visa@, guenther@, tedu@
-rw-r--r--sys/uvm/uvm_km.c4
-rw-r--r--sys/uvm/uvm_map.c16
2 files changed, 11 insertions, 9 deletions
diff --git a/sys/uvm/uvm_km.c b/sys/uvm/uvm_km.c
index 96ba63600bc..f76bd87c493 100644
--- a/sys/uvm/uvm_km.c
+++ b/sys/uvm/uvm_km.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_km.c,v 1.127 2015/09/17 18:04:49 kettenis Exp $ */
+/* $OpenBSD: uvm_km.c,v 1.128 2015/09/26 17:55:00 kettenis Exp $ */
/* $NetBSD: uvm_km.c,v 1.42 2001/01/14 02:10:01 thorpej Exp $ */
/*
@@ -703,6 +703,8 @@ uvm_km_thread(void *arg)
int flags;
struct uvm_km_free_page *fp = NULL;
+ KERNEL_UNLOCK();
+
for (;;) {
mtx_enter(&uvm_km_pages.mtx);
if (uvm_km_pages.free >= uvm_km_pages.lowat &&
diff --git a/sys/uvm/uvm_map.c b/sys/uvm/uvm_map.c
index 2ead35caee6..c760418dda4 100644
--- a/sys/uvm/uvm_map.c
+++ b/sys/uvm/uvm_map.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_map.c,v 1.199 2015/09/12 18:54:47 kettenis Exp $ */
+/* $OpenBSD: uvm_map.c,v 1.200 2015/09/26 17:55:00 kettenis Exp $ */
/* $NetBSD: uvm_map.c,v 1.86 2000/11/27 08:40:03 chs Exp $ */
/*
@@ -285,6 +285,7 @@ int uvm_map_printlocks = 0;
#define LPRINTF(_args) do {} while (0)
#endif
+static struct mutex uvm_kmapent_mtx;
static struct timeval uvm_kmapent_last_warn_time;
static struct timeval uvm_kmapent_warn_rate = { 10, 0 };
@@ -1638,15 +1639,15 @@ struct vm_map_entry *
uvm_mapent_alloc(struct vm_map *map, int flags)
{
struct vm_map_entry *me, *ne;
- int s, i;
int pool_flags;
+ int i;
pool_flags = PR_WAITOK;
if (flags & UVM_FLAG_TRYLOCK)
pool_flags = PR_NOWAIT;
if (map->flags & VM_MAP_INTRSAFE || cold) {
- s = splvm();
+ mtx_enter(&uvm_kmapent_mtx);
me = uvm.kentry_free;
if (me == NULL) {
ne = km_alloc(PAGE_SIZE, &kv_page, &kp_dirty,
@@ -1667,7 +1668,7 @@ uvm_mapent_alloc(struct vm_map *map, int flags)
}
uvm.kentry_free = RB_LEFT(me, daddrs.addr_entry);
uvmexp.kmapent++;
- splx(s);
+ mtx_leave(&uvm_kmapent_mtx);
me->flags = UVM_MAP_STATIC;
} else if (map == kernel_map) {
splassert(IPL_NONE);
@@ -1701,14 +1702,12 @@ out:
void
uvm_mapent_free(struct vm_map_entry *me)
{
- int s;
-
if (me->flags & UVM_MAP_STATIC) {
- s = splvm();
+ mtx_enter(&uvm_kmapent_mtx);
RB_LEFT(me, daddrs.addr_entry) = uvm.kentry_free;
uvm.kentry_free = me;
uvmexp.kmapent--;
- splx(s);
+ mtx_leave(&uvm_kmapent_mtx);
} else if (me->flags & UVM_MAP_KMEM) {
splassert(IPL_NONE);
pool_put(&uvm_map_entry_kmem_pool, me);
@@ -2778,6 +2777,7 @@ uvm_map_init(void)
int lcv;
/* now set up static pool of kernel map entries ... */
+ mtx_init(&uvm_kmapent_mtx, IPL_VM);
uvm.kentry_free = NULL;
for (lcv = 0 ; lcv < MAX_KMAPENT ; lcv++) {
RB_LEFT(&kernel_map_entry[lcv], daddrs.addr_entry) =