Annotation of sys/compat/osf1/osf1_mmap.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: osf1_mmap.c,v 1.6 2006/03/04 19:33:21 miod Exp $ */
! 2: /* $NetBSD: osf1_mmap.c,v 1.5 2000/04/11 05:26:27 chs Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 1999 Christopher G. Demetriou. All rights reserved.
! 6: *
! 7: * Redistribution and use in source and binary forms, with or without
! 8: * modification, are permitted provided that the following conditions
! 9: * are met:
! 10: * 1. Redistributions of source code must retain the above copyright
! 11: * notice, this list of conditions and the following disclaimer.
! 12: * 2. Redistributions in binary form must reproduce the above copyright
! 13: * notice, this list of conditions and the following disclaimer in the
! 14: * documentation and/or other materials provided with the distribution.
! 15: * 3. All advertising materials mentioning features or use of this software
! 16: * must display the following acknowledgement:
! 17: * This product includes software developed by Christopher G. Demetriou
! 18: * for the NetBSD Project.
! 19: * 4. The name of the author may not be used to endorse or promote products
! 20: * derived from this software without specific prior written permission
! 21: *
! 22: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 23: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
! 24: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
! 25: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
! 26: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
! 27: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
! 28: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
! 29: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
! 30: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
! 31: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 32: */
! 33:
! 34: #include <sys/param.h>
! 35: #include <sys/systm.h>
! 36: #include <sys/proc.h>
! 37: #include <sys/mman.h>
! 38: #include <sys/mount.h>
! 39: #include <sys/syscallargs.h>
! 40: #include <uvm/uvm.h>
! 41:
! 42: #include <compat/osf1/osf1.h>
! 43: #include <compat/osf1/osf1_syscallargs.h>
! 44: #include <compat/osf1/osf1_cvt.h>
! 45:
! 46: int
! 47: osf1_sys_madvise(p, v, retval)
! 48: struct proc *p;
! 49: void *v;
! 50: register_t *retval;
! 51: {
! 52: struct osf1_sys_madvise_args *uap = v;
! 53: struct sys_madvise_args a;
! 54: int error;
! 55:
! 56: SCARG(&a, addr) = SCARG(uap, addr);
! 57: SCARG(&a, len) = SCARG(uap, len);
! 58:
! 59: error = 0;
! 60: switch (SCARG(uap, behav)) {
! 61: case OSF1_MADV_NORMAL:
! 62: SCARG(&a, behav) = MADV_NORMAL;
! 63: break;
! 64:
! 65: case OSF1_MADV_RANDOM:
! 66: SCARG(&a, behav) = MADV_RANDOM;
! 67: break;
! 68:
! 69: case OSF1_MADV_SEQUENTIAL:
! 70: SCARG(&a, behav) = MADV_SEQUENTIAL;
! 71: break;
! 72:
! 73: case OSF1_MADV_WILLNEED:
! 74: SCARG(&a, behav) = MADV_WILLNEED;
! 75: break;
! 76:
! 77: case OSF1_MADV_DONTNEED_COMPAT:
! 78: SCARG(&a, behav) = MADV_DONTNEED;
! 79: break;
! 80: #if 0
! 81: case OSF1_MADV_SPACEAVAIL:
! 82: SCARG(&a, behav) = MADV_SPACEAVAIL;
! 83: break;
! 84: #endif
! 85: case OSF1_MADV_DONTNEED:
! 86: /*
! 87: * XXX not supported. In Digital UNIX, this flushes all
! 88: * XXX data in the region and replaces it with ZFOD pages.
! 89: */
! 90: error = EINVAL;
! 91: break;
! 92:
! 93: default:
! 94: error = EINVAL;
! 95: break;
! 96: }
! 97:
! 98: if (error == 0) {
! 99: error = sys_madvise(p, &a, retval);
! 100:
! 101: /*
! 102: * NetBSD madvise() currently always returns ENOSYS.
! 103: * Digital UNIX says that non-operational requests (i.e.
! 104: * valid, but unimplemented 'behav') will return success.
! 105: */
! 106: if (error == ENOSYS)
! 107: error = 0;
! 108: }
! 109: return (error);
! 110: }
! 111:
! 112: int
! 113: osf1_sys_mmap(p, v, retval)
! 114: struct proc *p;
! 115: void *v;
! 116: register_t *retval;
! 117: {
! 118: struct osf1_sys_mmap_args *uap = v;
! 119: struct sys_mmap_args a;
! 120: unsigned long leftovers;
! 121:
! 122: SCARG(&a, addr) = SCARG(uap, addr);
! 123: SCARG(&a, len) = SCARG(uap, len);
! 124: SCARG(&a, fd) = SCARG(uap, fd);
! 125: SCARG(&a, pad) = 0;
! 126: SCARG(&a, pos) = SCARG(uap, pos);
! 127:
! 128: /* translate prot */
! 129: SCARG(&a, prot) = emul_flags_translate(osf1_mmap_prot_xtab,
! 130: SCARG(uap, prot), &leftovers);
! 131: if (leftovers != 0)
! 132: return (EINVAL);
! 133:
! 134: /* translate flags */
! 135: SCARG(&a, flags) = emul_flags_translate(osf1_mmap_flags_xtab,
! 136: SCARG(uap, flags), &leftovers);
! 137: if (leftovers != 0)
! 138: return (EINVAL);
! 139:
! 140: /*
! 141: * XXX The following code is evil.
! 142: *
! 143: * The OSF/1 mmap() function attempts to map non-fixed entries
! 144: * near the address that the user specified. Therefore, for
! 145: * non-fixed entries we try to find space in the address space
! 146: * starting at that address. If the user specified zero, we
! 147: * start looking at at least NBPG, so that programs can't
! 148: * accidentally live through deferencing NULL.
! 149: *
! 150: * The need for this kludgery is increased by the fact that
! 151: * the loader data segment is mapped at
! 152: * (end of user address space) - 1G, MAXDSIZ is 1G, and
! 153: * the VM system tries allocate non-fixed mappings _AFTER_
! 154: * (start of data) + MAXDSIZ. With the loader, of course,
! 155: * that means that it'll start trying at
! 156: * (end of user address space), and will never succeed!
! 157: *
! 158: * Notes:
! 159: *
! 160: * * Though we find space here, if something else (e.g. a second
! 161: * thread) were mucking with the address space the mapping
! 162: * we found might be used by another mmap(), and this call
! 163: * would clobber that region.
! 164: *
! 165: * * In general, tricks like this only work for MAP_ANON mappings,
! 166: * because of sharing/cache issues. That's not a problem on
! 167: * the Alpha, and though it's not good style to abuse that fact,
! 168: * there's little choice.
! 169: *
! 170: * * In order for this to be done right, the VM system should
! 171: * really try to use the requested 'addr' passed in to mmap()
! 172: * as a hint, even if non-fixed. If it's passed as zero,
! 173: * _maybe_ then try (start of data) + MAXDSIZ, or maybe
! 174: * provide a better way to avoid the data region altogether.
! 175: */
! 176: if ((SCARG(&a, flags) & MAP_FIXED) == 0) {
! 177: vaddr_t addr = round_page((vaddr_t)SCARG(&a, addr));
! 178: vsize_t size = round_page((vsize_t)SCARG(&a, len));
! 179: int fixed = 0;
! 180:
! 181: vm_map_lock(&p->p_vmspace->vm_map);
! 182:
! 183: /* if non-NULL address given, start looking there */
! 184: /* XXX - UVM */
! 185: if (addr != 0 && uvm_map_findspace(&p->p_vmspace->vm_map,
! 186: addr, size, &addr, NULL, 0, 0, 0) != NULL) {
! 187: fixed = 1;
! 188: goto done;
! 189: }
! 190:
! 191: /* didn't find anything. take it again from the top. */
! 192: if (uvm_map_findspace(&p->p_vmspace->vm_map, NBPG, size, &addr,
! 193: NULL, 0, 0, 0) != NULL) {
! 194: fixed = 1;
! 195: goto done;
! 196: }
! 197:
! 198: done:
! 199: vm_map_unlock(&p->p_vmspace->vm_map);
! 200: if (fixed) {
! 201: SCARG(&a, flags) |= MAP_FIXED;
! 202: SCARG(&a, addr) = (void *)addr;
! 203: }
! 204: }
! 205:
! 206: return sys_mmap(p, &a, retval);
! 207: }
! 208:
! 209: int
! 210: osf1_sys_mprotect(p, v, retval)
! 211: struct proc *p;
! 212: void *v;
! 213: register_t *retval;
! 214: {
! 215: struct osf1_sys_mprotect_args *uap = v;
! 216: struct sys_mprotect_args a;
! 217: unsigned long leftovers;
! 218:
! 219: SCARG(&a, addr) = SCARG(uap, addr);
! 220: SCARG(&a, len) = SCARG(uap, len);
! 221:
! 222: /* translate prot */
! 223: SCARG(&a, prot) = emul_flags_translate(osf1_mmap_prot_xtab,
! 224: SCARG(uap, prot), &leftovers);
! 225: if (leftovers != 0)
! 226: return (EINVAL);
! 227:
! 228: return sys_mprotect(p, &a, retval);
! 229: }
CVSweb