aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorAlan Cox <alc@FreeBSD.org>2002-03-17 03:19:31 +0000
committerAlan Cox <alc@FreeBSD.org>2002-03-17 03:19:31 +0000
commit2f6c16e1e89de3523e1b5f09e53832746d5cf6df (patch)
tree3fd13b03ff318882c0192220ac50fc5876b14702 /sys
parent9bc8610af503367fd5a7312075f0260700404eda (diff)
downloadsrc-2f6c16e1e89de3523e1b5f09e53832746d5cf6df.tar.gz
src-2f6c16e1e89de3523e1b5f09e53832746d5cf6df.zip
Acquire a read lock on the map inside of vm_map_check_protection() rather
than expecting the caller to do so. This (1) eliminates duplicated code in kernacc() and useracc() and (2) fixes missing synchronization in munmap().
Notes
Notes: svn path=/head/; revision=92466
Diffstat (limited to 'sys')
-rw-r--r--sys/vm/vm_glue.c5
-rw-r--r--sys/vm/vm_map.c6
2 files changed, 7 insertions, 4 deletions
diff --git a/sys/vm/vm_glue.c b/sys/vm/vm_glue.c
index 678da3b64402..3263180e5b59 100644
--- a/sys/vm/vm_glue.c
+++ b/sys/vm/vm_glue.c
@@ -128,9 +128,7 @@ kernacc(addr, len, rw)
prot = rw;
saddr = trunc_page((vm_offset_t)addr);
eaddr = round_page((vm_offset_t)addr + len);
- vm_map_lock_read(kernel_map);
rv = vm_map_check_protection(kernel_map, saddr, eaddr, prot);
- vm_map_unlock_read(kernel_map);
return (rv == TRUE);
}
@@ -163,7 +161,7 @@ useracc(addr, len, rw)
return (FALSE);
}
map = &curproc->p_vmspace->vm_map;
- vm_map_lock_read(map);
+
/*
* We save the map hint, and restore it. Useracc appears to distort
* the map hint unnecessarily.
@@ -172,7 +170,6 @@ useracc(addr, len, rw)
rv = vm_map_check_protection(map,
trunc_page((vm_offset_t)addr), round_page((vm_offset_t)addr + len), prot);
map->hint = save_hint;
- vm_map_unlock_read(map);
return (rv == TRUE);
}
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index 3e1b4ab9845c..094372aee544 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -2071,31 +2071,37 @@ vm_map_check_protection(vm_map_t map, vm_offset_t start, vm_offset_t end,
GIANT_REQUIRED;
+ vm_map_lock_read(map);
if (!vm_map_lookup_entry(map, start, &tmp_entry)) {
+ vm_map_unlock_read(map);
return (FALSE);
}
entry = tmp_entry;
while (start < end) {
if (entry == &map->header) {
+ vm_map_unlock_read(map);
return (FALSE);
}
/*
* No holes allowed!
*/
if (start < entry->start) {
+ vm_map_unlock_read(map);
return (FALSE);
}
/*
* Check protection associated with entry.
*/
if ((entry->protection & protection) != protection) {
+ vm_map_unlock_read(map);
return (FALSE);
}
/* go to next entry */
start = entry->end;
entry = entry->next;
}
+ vm_map_unlock_read(map);
return (TRUE);
}