summaryrefslogtreecommitdiff
path: root/sys/uvm
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2003-04-14 04:53:52 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2003-04-14 04:53:52 +0000
commit901c826a09497ead7016206abf7b50656baff91e (patch)
tree2721a7366483b12d83c3a02b75f402e9e3fd0860 /sys/uvm
parentbcf4f93c865e19f6d796c4f4095be600cd2b319e (diff)
There are two related changes.
The first one is an mquery(2) syscall. It's for asking the VM system about where to map things. It will be used by ld.so, read the man page for details. The second change is related and is a centralization of uvm_map hint that all callers of uvm_map calculated. This will allow us to adjust this hint on architectures that have segments for non-exec mappings. deraadt@ drahn@ ok.
Diffstat (limited to 'sys/uvm')
-rw-r--r--sys/uvm/uvm_map.c13
-rw-r--r--sys/uvm/uvm_map.h3
-rw-r--r--sys/uvm/uvm_mmap.c70
3 files changed, 78 insertions, 8 deletions
diff --git a/sys/uvm/uvm_map.c b/sys/uvm/uvm_map.c
index a7cba41ff66..30af50d1508 100644
--- a/sys/uvm/uvm_map.c
+++ b/sys/uvm/uvm_map.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_map.c,v 1.56 2002/12/09 02:35:21 art Exp $ */
+/* $OpenBSD: uvm_map.c,v 1.57 2003/04/14 04:53:51 art Exp $ */
/* $NetBSD: uvm_map.c,v 1.86 2000/11/27 08:40:03 chs Exp $ */
/*
@@ -1072,6 +1072,16 @@ uvm_map_spacefits(vm_map_t map, vaddr_t *phint, vsize_t length,
}
/*
+ * uvm_map_hint: return the beginning of the best area suitable for
+ * creating a new mapping with "prot" protection.
+ */
+vaddr_t
+uvm_map_hint(struct proc *p, vm_prot_t prot)
+{
+ return (round_page((vaddr_t)p->p_vmspace->vm_daddr + MAXDSIZ));
+}
+
+/*
* uvm_map_findspace: find "length" sized space in "map".
*
* => "hint" is a hint about where we want it, unless FINDSPACE_FIXED is
@@ -3588,7 +3598,6 @@ uvmspace_fork(vm1)
return(vm2);
}
-
#if defined(DDB)
/*
diff --git a/sys/uvm/uvm_map.h b/sys/uvm/uvm_map.h
index 8dbc4fda58b..97e23a3d830 100644
--- a/sys/uvm/uvm_map.h
+++ b/sys/uvm/uvm_map.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_map.h,v 1.28 2002/10/29 18:30:21 art Exp $ */
+/* $OpenBSD: uvm_map.h,v 1.29 2003/04/14 04:53:51 art Exp $ */
/* $NetBSD: uvm_map.h,v 1.24 2001/02/18 21:19:08 chs Exp $ */
/*
@@ -335,6 +335,7 @@ int uvm_map_extract(vm_map_t, vaddr_t, vsize_t,
vm_map_t, vaddr_t *, int);
vm_map_entry_t uvm_map_findspace(vm_map_t, vaddr_t, vsize_t, vaddr_t *,
struct uvm_object *, voff_t, vsize_t, int);
+vaddr_t uvm_map_hint(struct proc *, vm_prot_t);
int uvm_map_inherit(vm_map_t, vaddr_t, vaddr_t, vm_inherit_t);
int uvm_map_advice(vm_map_t, vaddr_t, vaddr_t, int);
void uvm_map_init(void);
diff --git a/sys/uvm/uvm_mmap.c b/sys/uvm/uvm_mmap.c
index 0e09b0096f2..0a68cc18275 100644
--- a/sys/uvm/uvm_mmap.c
+++ b/sys/uvm/uvm_mmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_mmap.c,v 1.39 2003/04/07 14:47:08 mpech Exp $ */
+/* $OpenBSD: uvm_mmap.c,v 1.40 2003/04/14 04:53:51 art Exp $ */
/* $NetBSD: uvm_mmap.c,v 1.49 2001/02/18 21:19:08 chs Exp $ */
/*
@@ -117,6 +117,68 @@ sys_sstk(p, v, retval)
}
/*
+ * sys_mquery: provide mapping hints to applications that do fixed mappings
+ *
+ * flags: 0 or MAP_FIXED (MAP_FIXED - means that we insist on this addr and
+ * don't care about PMAP_PREFER or such)
+ * addr: hint where we'd like to place the mapping.
+ * size: size of the mapping
+ * fd: fd of the file we want to map
+ * off: offset within the file
+ */
+
+/* ARGSUSED */
+int
+sys_mquery(struct proc *p, void *v, register_t *retval)
+{
+ struct sys_mquery_args /* {
+ syscallarg(int) flags;
+ syscallarg(void **) addr;
+ syscallarg(size_t) size;
+ syscallarg(int) fd;
+ syscallarg(off_t) off;
+ } */ *uap = v;
+ struct file *fp;
+ struct uvm_object *uobj;
+ voff_t uoff;
+ int error;
+ vaddr_t vaddr;
+ int flags = 0;
+ vm_prot_t prot = SCARG(uap, flags) & VM_PROT_ALL;
+
+ if (SCARG(uap, flags) & MAP_FIXED)
+ flags |= UVM_FLAG_FIXED;
+
+ if ((error = copyin(SCARG(uap, addr), &vaddr, sizeof(void *))) != 0)
+ return (error);
+
+ if (SCARG(uap, fd) >= 0) {
+ if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
+ return (error);
+ uobj = &((struct vnode *)fp->f_data)->v_uvm.u_obj;
+ uoff = SCARG(uap, off);
+ } else {
+ fp = NULL;
+ uobj = NULL;
+ uoff = 0;
+ }
+
+ if (vaddr == 0)
+ vaddr = uvm_map_hint(p, prot);
+
+ if (uvm_map_findspace(&p->p_vmspace->vm_map, vaddr, SCARG(uap, size),
+ &vaddr, uobj, uoff, 0, flags) == NULL) {
+ error = ENOMEM;
+ } else {
+ error = copyout(&vaddr, SCARG(uap, addr), sizeof(void *));
+ }
+
+ if (fp != NULL)
+ FRELE(fp);
+ return (error);
+}
+
+/*
* sys_mincore: determine if pages are in core or not.
*/
@@ -350,10 +412,8 @@ sys_mmap(p, v, retval)
* we will refine our guess later (e.g. to account for VAC, etc)
*/
- if (addr < round_page((vaddr_t)p->p_vmspace->vm_daddr +
- MAXDSIZ))
- addr = round_page((vaddr_t)p->p_vmspace->vm_daddr +
- MAXDSIZ);
+ if (addr < uvm_map_hint(p, prot))
+ addr = uvm_map_hint(p, prot);
}
/*