diff options
-rw-r--r-- | lib/libc/shlib_version | 2 | ||||
-rw-r--r-- | lib/libc/sys/Makefile.inc | 8 | ||||
-rw-r--r-- | lib/libc/sys/mquery.2 | 127 | ||||
-rw-r--r-- | lib/libc/sys/mquery.c | 17 | ||||
-rw-r--r-- | sys/kern/init_sysent.c | 4 | ||||
-rw-r--r-- | sys/kern/kern_exec.c | 4 | ||||
-rw-r--r-- | sys/kern/syscalls.c | 3 | ||||
-rw-r--r-- | sys/kern/syscalls.master | 4 | ||||
-rw-r--r-- | sys/kern/sysv_shm.c | 5 | ||||
-rw-r--r-- | sys/sys/mman.h | 4 | ||||
-rw-r--r-- | sys/sys/syscall.h | 7 | ||||
-rw-r--r-- | sys/sys/syscallargs.h | 11 | ||||
-rw-r--r-- | sys/uvm/uvm_map.c | 13 | ||||
-rw-r--r-- | sys/uvm/uvm_map.h | 3 | ||||
-rw-r--r-- | sys/uvm/uvm_mmap.c | 70 |
15 files changed, 256 insertions, 26 deletions
diff --git a/lib/libc/shlib_version b/lib/libc/shlib_version index a048d137bb3..7b897a195c1 100644 --- a/lib/libc/shlib_version +++ b/lib/libc/shlib_version @@ -1,2 +1,2 @@ major=29 -minor=0 # note: remember to update minor in ../libpthread/shlib_version +minor=1 # note: remember to update minor in ../libpthread/shlib_version diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc index e6030715104..4501f4d6445 100644 --- a/lib/libc/sys/Makefile.inc +++ b/lib/libc/sys/Makefile.inc @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile.inc,v 1.64 2003/01/31 21:47:46 millert Exp $ +# $OpenBSD: Makefile.inc,v 1.65 2003/04/14 04:53:50 art Exp $ # $NetBSD: Makefile.inc,v 1.35 1995/10/16 23:49:07 jtc Exp $ # @(#)Makefile.inc 8.1 (Berkeley) 6/17/93 @@ -21,7 +21,7 @@ DPSRCS+= Lint_Ovfork.c Lint_brk.c Lint_exect.c Lint_fork.c \ # glue to provide compatibility between GCC 1.X and 2.X and for compat # with old syscall interfaces. -SRCS+= ftruncate.c lseek.c mmap.c ptrace.c semctl.c truncate.c \ +SRCS+= ftruncate.c lseek.c mquery.c mmap.c ptrace.c semctl.c truncate.c \ timer_create.c timer_delete.c timer_getoverrun.c timer_gettime.c \ timer_settime.c pread.c preadv.c pwrite.c pwritev.c @@ -216,8 +216,8 @@ MAN+= accept.2 access.2 acct.2 adjtime.2 bind.2 brk.2 chdir.2 chflags.2 \ getpid.2 getpriority.2 getrlimit.2 getrusage.2 getsid.2 getsockname.2 \ getsockopt.2 gettimeofday.2 getuid.2 intro.2 issetugid.2 ioctl.2 \ kill.2 kqueue.2 ktrace.2 link.2 \ - listen.2 lseek.2 mkdir.2 mkfifo.2 mknod.2 madvise.2 mincore.2 \ - minherit.2 mlock.2 mlockall.2 \ + listen.2 lseek.2 mkdir.2 mkfifo.2 mknod.2 madvise.2 \ + mquery.2 mincore.2 minherit.2 mlock.2 mlockall.2 \ mmap.2 mount.2 mprotect.2 msync.2 munmap.2 nanosleep.2 \ nfssvc.2 open.2 pathconf.2 \ pipe.2 profil.2 poll.2 ptrace.2 quotactl.2 read.2 readlink.2 reboot.2 \ diff --git a/lib/libc/sys/mquery.2 b/lib/libc/sys/mquery.2 new file mode 100644 index 00000000000..9e835bc4233 --- /dev/null +++ b/lib/libc/sys/mquery.2 @@ -0,0 +1,127 @@ +.\" $OpenBSD: mquery.2,v 1.1 2003/04/14 04:53:50 art Exp $ +.\" +.\" Copyright (c) 2003 Artur Grabowski <art@openbsd.org> +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +.\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +.\" THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +.\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +.\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +.\" OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd April 2, 2003 +.Dt MQUERY 2 +.Os +.Sh NAME +.Nm mquery +.Nd provide mapping hints to applications +.Sh SYNOPSIS +.Fd #include <sys/types.h> +.Fd #include <sys/mman.h> +.Ft int +.Fn mquery "int flags" "void **addr" "size_t size" "int fd" "off_t off" +.Sh DESCRIPTION +The +.Nm mqeury +system call checks the existing memory mappings of a process and returns +hints to the caller about where to put a memory mapping. +This hint can be later used when performing memory mappings with the +.Fn mmap +system call with +.Dv MAP_FIXED +in the flags. +The +.Fa addr +argument should point to a memory location that stores a pointer +which is used both as an input argument where the caller specifies the +preferred address and as an output of the resulting hint. +The +.Fa size +argument specifies the requested size of the memory area the caller +is looking for. +The +.Fa fd +and +.Fa off +arguments specify the file that will be mapped and the offset in it, +this is the same as the corresponding arguments to +.Fn mmap . +.Pp +The behavior of the function depends on the +.Fa flags +argument. +If set to +.Dv MAP_FIXED +the pointer +.Fa *addr +is used as a fixed hint and +.Fn mquery +will return \-1 and set +.Va errno +to +.Dv ENOMEM +if there is not +.Fa size +bytes free after that address. +Otherwise it will return 0 and +.Fa *addr +will not be changed. +If no flags are set +.Fn mquery +will use +.Fa *addr +as a starting point in memory and will search forward to find +a memory area with +.Fa size +bytes free and that will be suitable for creating a mapping for the +file and offset specified in the +.Fa fd +and +.Fa off +arguments. +When no such area can be found +.Fn mquery +will return \-1 and set +.Va errno +to +.Dv ENOMEM . +.Sh RETURN VALUES +When a memory range satisfying the request is found +.Fn mquery +returns 0. +Otherwise, \-1 is returned and +.Va errno +is set to indicate the error. +.Sh ERRORS +.Fn mquery +will fail if: +.Bl -tag -width ENOMEM +.It Bq Er ENOMEM +.Dv MAP_FIXED +was specified and the requested memory area is unavailable. +.It Bq Er ENOMEM +There was not enough memory left after the hint specified. +.It Bq Er EBADF +.Fa fd +is not a valid open file descriptor. +.Sh SEE ALSO +.Xr mmap 2 +.Sh HISTORY +The +.Fn mquery +function first appeared in +.Ox 3.4 . diff --git a/lib/libc/sys/mquery.c b/lib/libc/sys/mquery.c new file mode 100644 index 00000000000..2cb28e27a9b --- /dev/null +++ b/lib/libc/sys/mquery.c @@ -0,0 +1,17 @@ +/* $OpenBSD: mquery.c,v 1.1 2003/04/14 04:53:50 art Exp $ */ +/* + * Written by Artur Grabowski <art@openbsd.org> Public Domain + */ + +#include <sys/types.h> +#include <sys/mman.h> +#include <sys/syscall.h> + +/* + * This function provides 64-bit offset padding. + */ +int +mquery(int flags, void **addr, size_t size, int fd, off_t off) +{ + return(__syscall((quad_t)SYS_mquery, flags, addr, size, fd, off)); +} diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index 1ad052d3757..a95f5062910 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: init_sysent.c,v 1.59 2003/01/30 15:32:44 millert Exp $ */ +/* $OpenBSD: init_sysent.c,v 1.60 2003/04/14 04:53:50 art Exp $ */ /* * System call switch table. @@ -746,5 +746,7 @@ struct sysent sysent[] = { sys_getresgid }, /* 283 = getresgid */ { 3, s(struct sys_setresgid_args), sys_setresgid }, /* 284 = setresgid */ + { 5, s(struct sys_mquery_args), + sys_mquery }, /* 285 = mquery */ }; diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 77faaf4960f..9504237bc22 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_exec.c,v 1.76 2003/03/09 01:27:50 millert Exp $ */ +/* $OpenBSD: kern_exec.c,v 1.77 2003/04/14 04:53:50 art Exp $ */ /* $NetBSD: kern_exec.c,v 1.75 1996/02/09 18:59:28 christos Exp $ */ /*- @@ -732,7 +732,7 @@ exec_sigcode_map(struct proc *p, struct emul *e) } /* Just a hint to uvm_mmap where to put it. */ - p->p_sigcode = round_page((vaddr_t)p->p_vmspace->vm_daddr + MAXDSIZ); + p->p_sigcode = uvm_map_hint(p, VM_PROT_READ|VM_PROT_EXECUTE); uao_reference(e->e_sigobject); if (uvm_map(&p->p_vmspace->vm_map, &p->p_sigcode, round_page(sz), e->e_sigobject, 0, 0, UVM_MAPFLAG(UVM_PROT_RX, UVM_PROT_RX, diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index 86cedb94c6c..01a67ae9d07 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -1,4 +1,4 @@ -/* $OpenBSD: syscalls.c,v 1.59 2003/01/30 03:32:44 millert Exp $ */ +/* $OpenBSD: syscalls.c,v 1.60 2003/04/14 04:53:50 art Exp $ */ /* * System call names. @@ -380,4 +380,5 @@ char *syscallnames[] = { "setresuid", /* 282 = setresuid */ "getresgid", /* 283 = getresgid */ "setresgid", /* 284 = setresgid */ + "mquery", /* 285 = mquery */ }; diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index b427bc216ee..e414ac0e100 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -1,4 +1,4 @@ -; $OpenBSD: syscalls.master,v 1.52 2003/01/30 03:29:49 millert Exp $ +; $OpenBSD: syscalls.master,v 1.53 2003/04/14 04:53:50 art Exp $ ; $NetBSD: syscalls.master,v 1.32 1996/04/23 10:24:21 mycroft Exp $ ; @(#)syscalls.master 8.2 (Berkeley) 1/13/94 @@ -570,3 +570,5 @@ gid_t *sgid); } 284 STD { int sys_setresgid(gid_t rgid, gid_t egid, \ gid_t sgid); } +285 STD { int sys_mquery(int flags, void **addr, size_t size, \ + int fd, off_t off); } diff --git a/sys/kern/sysv_shm.c b/sys/kern/sysv_shm.c index aaf85095b1a..56b473ccce1 100644 --- a/sys/kern/sysv_shm.c +++ b/sys/kern/sysv_shm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sysv_shm.c,v 1.33 2003/01/07 00:34:41 millert Exp $ */ +/* $OpenBSD: sysv_shm.c,v 1.34 2003/04/14 04:53:50 art Exp $ */ /* $NetBSD: sysv_shm.c,v 1.50 1998/10/21 22:24:29 tron Exp $ */ /* @@ -273,8 +273,7 @@ sys_shmat(struct proc *p, void *v, register_t *retval) return (EINVAL); } else { /* This is just a hint to uvm_map() about where to put it. */ - attach_va = round_page((vaddr_t)p->p_vmspace->vm_taddr + - MAXTSIZ + MAXDSIZ); + attach_va = uvm_map_hint(p, prot); } shm_handle = shmseg->shm_internal; uao_reference(shm_handle->shm_object); diff --git a/sys/sys/mman.h b/sys/sys/mman.h index 2676f153f05..180c57726a8 100644 --- a/sys/sys/mman.h +++ b/sys/sys/mman.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mman.h,v 1.11 2002/03/14 01:27:14 millert Exp $ */ +/* $OpenBSD: mman.h,v 1.12 2003/04/14 04:53:50 art Exp $ */ /* $NetBSD: mman.h,v 1.11 1995/03/26 20:24:23 jtc Exp $ */ /*- @@ -106,7 +106,6 @@ #define MCL_CURRENT 0x01 /* lock all pages currently mapped */ #define MCL_FUTURE 0x02 /* lock all pages mapped in the future */ - #ifndef _KERNEL #include <sys/cdefs.h> @@ -124,6 +123,7 @@ int munlockall(void); int madvise(void *, size_t, int); int mincore(void *, size_t, char *); int minherit(void *, size_t, int); +int mquery(int flags, void **addr, size_t size, int fd, off_t off); __END_DECLS #endif /* !_KERNEL */ diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h index c1af409324c..5ca97f3505b 100644 --- a/sys/sys/syscall.h +++ b/sys/sys/syscall.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.h,v 1.58 2003/01/30 03:32:44 millert Exp $ */ +/* $OpenBSD: syscall.h,v 1.59 2003/04/14 04:53:50 art Exp $ */ /* * System call numbers. @@ -668,4 +668,7 @@ /* syscall: "setresgid" ret: "int" args: "gid_t" "gid_t" "gid_t" */ #define SYS_setresgid 284 -#define SYS_MAXSYSCALL 285 +/* syscall: "mquery" ret: "int" args: "int" "void **" "size_t" "int" "off_t" */ +#define SYS_mquery 285 + +#define SYS_MAXSYSCALL 286 diff --git a/sys/sys/syscallargs.h b/sys/sys/syscallargs.h index 420bd13bbb3..e2d70e279d8 100644 --- a/sys/sys/syscallargs.h +++ b/sys/sys/syscallargs.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscallargs.h,v 1.60 2003/01/30 03:32:44 millert Exp $ */ +/* $OpenBSD: syscallargs.h,v 1.61 2003/04/14 04:53:50 art Exp $ */ /* * System call argument lists. @@ -1203,6 +1203,14 @@ struct sys_setresgid_args { syscallarg(gid_t) sgid; }; +struct sys_mquery_args { + syscallarg(int) flags; + syscallarg(void **) addr; + syscallarg(size_t) size; + syscallarg(int) fd; + syscallarg(off_t) off; +}; + /* * System call prototypes. */ @@ -1492,3 +1500,4 @@ int sys_getresuid(struct proc *, void *, register_t *); int sys_setresuid(struct proc *, void *, register_t *); int sys_getresgid(struct proc *, void *, register_t *); int sys_setresgid(struct proc *, void *, register_t *); +int sys_mquery(struct proc *, void *, register_t *); 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); } /* |