summaryrefslogtreecommitdiff
path: root/sys/uvm
diff options
context:
space:
mode:
Diffstat (limited to 'sys/uvm')
-rw-r--r--sys/uvm/uvm_extern.h3
-rw-r--r--sys/uvm/uvm_glue.c20
-rw-r--r--sys/uvm/uvm_io.c4
-rw-r--r--sys/uvm/uvm_map.c20
-rw-r--r--sys/uvm/uvm_map.h5
5 files changed, 40 insertions, 12 deletions
diff --git a/sys/uvm/uvm_extern.h b/sys/uvm/uvm_extern.h
index faa4a2e5449..980c97422ef 100644
--- a/sys/uvm/uvm_extern.h
+++ b/sys/uvm/uvm_extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_extern.h,v 1.158 2021/06/28 11:19:01 mpi Exp $ */
+/* $OpenBSD: uvm_extern.h,v 1.159 2022/03/11 19:24:19 kettenis Exp $ */
/* $NetBSD: uvm_extern.h,v 1.57 2001/03/09 01:02:12 chs Exp $ */
/*
@@ -291,6 +291,7 @@ void uvm_init_percpu(void);
int uvm_io(vm_map_t, struct uio *, int);
#define UVM_IO_FIXPROT 0x01
+#define UVM_IO_RDLOCKED 0x02
vaddr_t uvm_km_alloc1(vm_map_t, vsize_t, vsize_t, boolean_t);
void uvm_km_free(vm_map_t, vaddr_t, vsize_t);
diff --git a/sys/uvm/uvm_glue.c b/sys/uvm/uvm_glue.c
index 206b84e88e2..d8ca78859ea 100644
--- a/sys/uvm/uvm_glue.c
+++ b/sys/uvm/uvm_glue.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_glue.c,v 1.81 2022/02/18 09:04:38 kettenis Exp $ */
+/* $OpenBSD: uvm_glue.c,v 1.82 2022/03/11 19:24:19 kettenis Exp $ */
/* $NetBSD: uvm_glue.c,v 1.44 2001/02/06 19:54:44 eeh Exp $ */
/*
@@ -110,13 +110,26 @@ uvm_vslock(struct proc *p, caddr_t addr, size_t len, vm_prot_t access_type)
{
struct vm_map *map = &p->p_vmspace->vm_map;
vaddr_t start, end;
+ int error, mapv;
start = trunc_page((vaddr_t)addr);
end = round_page((vaddr_t)addr + len);
if (end <= start)
return (EINVAL);
- return uvm_fault_wire(map, start, end, access_type);
+ vm_map_lock_read(map);
+retry:
+ mapv = map->timestamp;
+ vm_map_unlock_read(map);
+
+ if ((error = uvm_fault_wire(map, start, end, access_type)))
+ return (error);
+
+ vm_map_lock_read(map);
+ if (mapv != map->timestamp)
+ goto retry;
+
+ return (0);
}
/*
@@ -133,7 +146,8 @@ uvm_vsunlock(struct proc *p, caddr_t addr, size_t len)
end = round_page((vaddr_t)addr + len);
KASSERT(end > start);
- uvm_fault_unwire(&p->p_vmspace->vm_map, start, end);
+ uvm_fault_unwire_locked(&p->p_vmspace->vm_map, start, end);
+ vm_map_unlock_read(&p->p_vmspace->vm_map);
}
/*
diff --git a/sys/uvm/uvm_io.c b/sys/uvm/uvm_io.c
index 96a9ba543b1..e18df842fe1 100644
--- a/sys/uvm/uvm_io.c
+++ b/sys/uvm/uvm_io.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_io.c,v 1.27 2021/03/20 10:24:21 mpi Exp $ */
+/* $OpenBSD: uvm_io.c,v 1.28 2022/03/11 19:24:19 kettenis Exp $ */
/* $NetBSD: uvm_io.c,v 1.12 2000/06/27 17:29:23 mrg Exp $ */
/*
@@ -86,6 +86,8 @@ uvm_io(vm_map_t map, struct uio *uio, int flags)
extractflags = 0;
if (flags & UVM_IO_FIXPROT)
extractflags |= UVM_EXTRACT_FIXPROT;
+ if (flags & UVM_IO_RDLOCKED)
+ extractflags |= UVM_EXTRACT_RDLOCKED;
/*
* step 1: main loop... while we've got data to move
diff --git a/sys/uvm/uvm_map.c b/sys/uvm/uvm_map.c
index ab114029180..98aa7d4326e 100644
--- a/sys/uvm/uvm_map.c
+++ b/sys/uvm/uvm_map.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_map.c,v 1.288 2022/02/15 11:54:19 kn Exp $ */
+/* $OpenBSD: uvm_map.c,v 1.289 2022/03/11 19:24:19 kettenis Exp $ */
/* $NetBSD: uvm_map.c,v 1.86 2000/11/27 08:40:03 chs Exp $ */
/*
@@ -4522,7 +4522,12 @@ uvm_map_extract(struct vm_map *srcmap, vaddr_t start, vsize_t len,
return 0;
/* Acquire lock on srcmap. */
- vm_map_lock(srcmap);
+ if (flags & UVM_EXTRACT_RDLOCKED) {
+ vm_map_busy(srcmap);
+ vm_map_upgrade(srcmap);
+ vm_map_unbusy(srcmap);
+ } else
+ vm_map_lock(srcmap);
/* Lock srcmap, lookup first and last entry in <start,len>. */
first = uvm_map_entrybyaddr(&srcmap->addr, start);
@@ -4624,7 +4629,10 @@ fail2:
vm_map_unlock(kernel_map);
fail:
- vm_map_unlock(srcmap);
+ if (flags & UVM_EXTRACT_RDLOCKED)
+ vm_map_downgrade(srcmap);
+ else
+ vm_map_unlock(srcmap);
uvm_unmap_detach(&dead, 0);
@@ -5581,7 +5589,9 @@ uvm_map_fill_vmmap(struct vm_map *map, struct kinfo_vmentry *kve,
*/
start = (vaddr_t)kve[0].kve_start;
- vm_map_lock(map);
+ vm_map_busy(map);
+ vm_map_upgrade(map);
+ vm_map_unbusy(map);
RBT_FOREACH(entry, uvm_map_addr, &map->addr) {
if (cnt == maxcnt) {
error = ENOMEM;
@@ -5605,7 +5615,7 @@ uvm_map_fill_vmmap(struct vm_map *map, struct kinfo_vmentry *kve,
kve++;
cnt++;
}
- vm_map_unlock(map);
+ vm_map_downgrade(map);
KASSERT(cnt <= maxcnt);
diff --git a/sys/uvm/uvm_map.h b/sys/uvm/uvm_map.h
index 24bf9fd7ad1..8d0d1c289f7 100644
--- a/sys/uvm/uvm_map.h
+++ b/sys/uvm/uvm_map.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_map.h,v 1.73 2022/02/11 09:25:04 kn Exp $ */
+/* $OpenBSD: uvm_map.h,v 1.74 2022/03/11 19:24:19 kettenis Exp $ */
/* $NetBSD: uvm_map.h,v 1.24 2001/02/18 21:19:08 chs Exp $ */
/*
@@ -116,7 +116,8 @@
/*
* extract flags
*/
-#define UVM_EXTRACT_FIXPROT 0x8 /* set prot to maxprot as we go */
+#define UVM_EXTRACT_FIXPROT 0x1 /* set prot to maxprot as we go */
+#define UVM_EXTRACT_RDLOCKED 0x2 /* map is already read-locked */
#endif /* _KERNEL */