1 /* $NetBSD: osf1_mmap.c,v 1.13 2007/12/20 23:03:03 dsl Exp $ */
4 * Copyright (c) 1999 Christopher G. Demetriou. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Christopher G. Demetriou
17 * for the NetBSD Project.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: osf1_mmap.c,v 1.13 2007/12/20 23:03:03 dsl Exp $");
36 #include <sys/param.h>
37 #include <sys/systm.h>
40 #include <sys/mount.h>
41 #include <sys/syscallargs.h>
42 #include <uvm/uvm.h> /* XXX see mmap emulation */
44 #include <compat/osf1/osf1.h>
45 #include <compat/osf1/osf1_syscallargs.h>
46 #include <compat/osf1/osf1_cvt.h>
49 osf1_sys_madvise(struct lwp
*l
, const struct osf1_sys_madvise_args
*uap
, register_t
*retval
)
51 struct sys_madvise_args a
;
54 SCARG(&a
, addr
) = SCARG(uap
, addr
);
55 SCARG(&a
, len
) = SCARG(uap
, len
);
58 switch (SCARG(uap
, behav
)) {
59 case OSF1_MADV_NORMAL
:
60 SCARG(&a
, behav
) = MADV_NORMAL
;
63 case OSF1_MADV_RANDOM
:
64 SCARG(&a
, behav
) = MADV_RANDOM
;
67 case OSF1_MADV_SEQUENTIAL
:
68 SCARG(&a
, behav
) = MADV_SEQUENTIAL
;
71 case OSF1_MADV_WILLNEED
:
72 SCARG(&a
, behav
) = MADV_WILLNEED
;
75 case OSF1_MADV_DONTNEED_COMPAT
:
76 SCARG(&a
, behav
) = MADV_DONTNEED
;
79 case OSF1_MADV_SPACEAVAIL
:
80 SCARG(&a
, behav
) = MADV_SPACEAVAIL
;
83 case OSF1_MADV_DONTNEED
:
85 * XXX not supported. In Digital UNIX, this flushes all
86 * XXX data in the region and replaces it with ZFOD pages.
97 error
= sys_madvise(l
, &a
, retval
);
100 * NetBSD madvise() currently always returns ENOSYS.
101 * Digital UNIX says that non-operational requests (i.e.
102 * valid, but unimplemented 'behav') will return success.
111 osf1_sys_mmap(struct lwp
*l
, const struct osf1_sys_mmap_args
*uap
, register_t
*retval
)
113 struct proc
*p
= l
->l_proc
;
114 struct sys_mmap_args a
;
115 unsigned long leftovers
;
117 SCARG(&a
, addr
) = SCARG(uap
, addr
);
118 SCARG(&a
, len
) = SCARG(uap
, len
);
119 SCARG(&a
, fd
) = SCARG(uap
, fd
);
121 SCARG(&a
, pos
) = SCARG(uap
, pos
);
124 SCARG(&a
, prot
) = emul_flags_translate(osf1_mmap_prot_xtab
,
125 SCARG(uap
, prot
), &leftovers
);
129 /* translate flags */
130 SCARG(&a
, flags
) = emul_flags_translate(osf1_mmap_flags_xtab
,
131 SCARG(uap
, flags
), &leftovers
);
136 * XXX The following code is evil.
138 * The OSF/1 mmap() function attempts to map non-fixed entries
139 * near the address that the user specified. Therefore, for
140 * non-fixed entires we try to find space in the address space
141 * starting at that address. If the user specified zero, we
142 * start looking at at least PAGE_SIZE, so that programs can't
143 * accidentally live through deferencing NULL.
145 * The need for this kludgery is increased by the fact that
146 * the loader data segment is mapped at
147 * (end of user address space) - 1G, MAXDSIZ is 1G, and
148 * the VM system tries allocate non-fixed mappings _AFTER_
149 * (start of data) + MAXDSIZ. With the loader, of course,
150 * that means that it'll start trying at
151 * (end of user address space), and will never succeed!
155 * * Though we find space here, if something else (e.g. a second
156 * thread) were mucking with the address space the mapping
157 * we found might be used by another mmap(), and this call
158 * would clobber that region.
160 * * In general, tricks like this only work for MAP_ANON mappings,
161 * because of sharing/cache issues. That's not a problem on
162 * the Alpha, and though it's not good style to abuse that fact,
163 * there's little choice.
165 * * In order for this to be done right, the VM system should
166 * really try to use the requested 'addr' passed in to mmap()
167 * as a hint, even if non-fixed. If it's passed as zero,
168 * _maybe_ then try (start of data) + MAXDSIZ, or maybe
169 * provide a better way to avoid the data region altogether.
171 if ((SCARG(&a
, flags
) & MAP_FIXED
) == 0) {
172 vaddr_t addr
= round_page((vaddr_t
)SCARG(&a
, addr
));
173 vsize_t size
= round_page((vsize_t
)SCARG(&a
, len
));
176 vm_map_lock(&p
->p_vmspace
->vm_map
);
178 /* if non-NULL address given, start looking there */
179 if (addr
!= 0 && uvm_map_findspace(&p
->p_vmspace
->vm_map
,
180 addr
, size
, &addr
, NULL
, 0, 0, 0) != NULL
) {
185 /* didn't find anything. take it again from the top. */
186 if (uvm_map_findspace(&p
->p_vmspace
->vm_map
, PAGE_SIZE
, size
,
187 &addr
, NULL
, 0, 0, 0) != NULL
) {
193 vm_map_unlock(&p
->p_vmspace
->vm_map
);
195 SCARG(&a
, flags
) |= MAP_FIXED
;
196 SCARG(&a
, addr
) = (void *)addr
;
200 return sys_mmap(l
, &a
, retval
);
204 osf1_sys_mprotect(struct lwp
*l
, const struct osf1_sys_mprotect_args
*uap
, register_t
*retval
)
206 struct sys_mprotect_args a
;
207 unsigned long leftovers
;
209 SCARG(&a
, addr
) = SCARG(uap
, addr
);
210 SCARG(&a
, len
) = SCARG(uap
, len
);
213 SCARG(&a
, prot
) = emul_flags_translate(osf1_mmap_prot_xtab
,
214 SCARG(uap
, prot
), &leftovers
);
218 return sys_mprotect(l
, &a
, retval
);