diff options
Diffstat (limited to 'sys/uvm')
-rw-r--r-- | sys/uvm/uvm_extern.h | 3 | ||||
-rw-r--r-- | sys/uvm/uvm_glue.c | 20 | ||||
-rw-r--r-- | sys/uvm/uvm_io.c | 4 | ||||
-rw-r--r-- | sys/uvm/uvm_map.c | 20 | ||||
-rw-r--r-- | sys/uvm/uvm_map.h | 5 |
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 */ |