The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/compat/osf1/osf1_mmap.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* $NetBSD: osf1_mmap.c,v 1.13 2007/12/20 23:03:03 dsl Exp $ */
    2 
    3 /*
    4  * Copyright (c) 1999 Christopher G. Demetriou.  All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    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
   20  *
   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.
   31  */
   32 
   33 #include <sys/cdefs.h>
   34 __KERNEL_RCSID(0, "$NetBSD: osf1_mmap.c,v 1.13 2007/12/20 23:03:03 dsl Exp $");
   35 
   36 #include <sys/param.h>
   37 #include <sys/systm.h>
   38 #include <sys/proc.h>
   39 #include <sys/mman.h>
   40 #include <sys/mount.h>
   41 #include <sys/syscallargs.h>
   42 #include <uvm/uvm.h>                            /* XXX see mmap emulation */
   43 
   44 #include <compat/osf1/osf1.h>
   45 #include <compat/osf1/osf1_syscallargs.h>
   46 #include <compat/osf1/osf1_cvt.h>
   47 
   48 int
   49 osf1_sys_madvise(struct lwp *l, const struct osf1_sys_madvise_args *uap, register_t *retval)
   50 {
   51         struct sys_madvise_args a;
   52         int error;
   53 
   54         SCARG(&a, addr) = SCARG(uap, addr);
   55         SCARG(&a, len) = SCARG(uap, len);
   56 
   57         error = 0;
   58         switch (SCARG(uap, behav)) {
   59         case OSF1_MADV_NORMAL:
   60                 SCARG(&a, behav) = MADV_NORMAL;
   61                 break;
   62 
   63         case OSF1_MADV_RANDOM:
   64                 SCARG(&a, behav) = MADV_RANDOM;
   65                 break;
   66 
   67         case OSF1_MADV_SEQUENTIAL:
   68                 SCARG(&a, behav) = MADV_SEQUENTIAL;
   69                 break;
   70 
   71         case OSF1_MADV_WILLNEED:
   72                 SCARG(&a, behav) = MADV_WILLNEED;
   73                 break;
   74 
   75         case OSF1_MADV_DONTNEED_COMPAT:
   76                 SCARG(&a, behav) = MADV_DONTNEED;
   77                 break;
   78 
   79         case OSF1_MADV_SPACEAVAIL:
   80                 SCARG(&a, behav) = MADV_SPACEAVAIL;
   81                 break;
   82 
   83         case OSF1_MADV_DONTNEED:
   84                 /*
   85                  * XXX not supported.  In Digital UNIX, this flushes all
   86                  * XXX data in the region and replaces it with ZFOD pages.
   87                  */
   88                 error = EINVAL;
   89                 break;
   90 
   91         default:
   92                 error = EINVAL;
   93                 break;
   94         }
   95 
   96         if (error == 0) {
   97                 error = sys_madvise(l, &a, retval);
   98 
   99                 /*
  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.
  103                  */
  104                 if (error == ENOSYS)
  105                         error = 0;
  106         }
  107         return (error);
  108 }
  109 
  110 int
  111 osf1_sys_mmap(struct lwp *l, const struct osf1_sys_mmap_args *uap, register_t *retval)
  112 {
  113         struct proc *p = l->l_proc;
  114         struct sys_mmap_args a;
  115         unsigned long leftovers;
  116 
  117         SCARG(&a, addr) = SCARG(uap, addr);
  118         SCARG(&a, len) = SCARG(uap, len);
  119         SCARG(&a, fd) = SCARG(uap, fd);
  120         SCARG(&a, pad) = 0;
  121         SCARG(&a, pos) = SCARG(uap, pos);
  122 
  123         /* translate prot */
  124         SCARG(&a, prot) = emul_flags_translate(osf1_mmap_prot_xtab,
  125             SCARG(uap, prot), &leftovers);
  126         if (leftovers != 0)
  127                 return (EINVAL);
  128 
  129         /* translate flags */
  130         SCARG(&a, flags) = emul_flags_translate(osf1_mmap_flags_xtab,
  131             SCARG(uap, flags), &leftovers);
  132         if (leftovers != 0)
  133                 return (EINVAL);
  134 
  135         /*
  136          * XXX The following code is evil.
  137          *
  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.
  144          *
  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!
  152          *
  153          * Notes:
  154          *
  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.
  159          *
  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.
  164          *
  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.
  170          */
  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));
  174                 int fixed = 0;
  175 
  176                 vm_map_lock(&p->p_vmspace->vm_map);
  177 
  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) {
  181                         fixed = 1;
  182                         goto done;
  183                 }
  184 
  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) {
  188                         fixed = 1;
  189                         goto done;
  190                 }
  191 
  192 done:
  193                 vm_map_unlock(&p->p_vmspace->vm_map);
  194                 if (fixed) {
  195                         SCARG(&a, flags) |= MAP_FIXED;
  196                         SCARG(&a, addr) = (void *)addr;
  197                 }
  198         }
  199 
  200         return sys_mmap(l, &a, retval);
  201 }
  202 
  203 int
  204 osf1_sys_mprotect(struct lwp *l, const struct osf1_sys_mprotect_args *uap, register_t *retval)
  205 {
  206         struct sys_mprotect_args a;
  207         unsigned long leftovers;
  208 
  209         SCARG(&a, addr) = SCARG(uap, addr);
  210         SCARG(&a, len) = SCARG(uap, len);
  211 
  212         /* translate prot */
  213         SCARG(&a, prot) = emul_flags_translate(osf1_mmap_prot_xtab,
  214             SCARG(uap, prot), &leftovers);
  215         if (leftovers != 0)
  216                 return (EINVAL);
  217 
  218         return sys_mprotect(l, &a, retval);
  219 }

Cache object: 1d704affb86ac5fc6cfe0bc76ef03c73


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.