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/alpha/linux/linux_machdep.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2000 Marcel Moolenaar
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer
   10  *    in this position and unchanged.
   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. The name of the author may not be used to endorse or promote products
   15  *    derived from this software without specific prior written permission.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   27  */
   28 
   29 #include <sys/cdefs.h>
   30 __FBSDID("$FreeBSD: releng/5.4/sys/alpha/linux/linux_machdep.c 141333 2005-02-05 01:02:51Z das $");
   31 
   32 #include <sys/param.h>
   33 #include <sys/systm.h>
   34 #include <sys/lock.h>
   35 #include <sys/mman.h>
   36 #include <sys/mount.h>
   37 #include <sys/mutex.h>
   38 #include <sys/proc.h>
   39 #include <sys/resource.h>
   40 #include <sys/resourcevar.h>
   41 #include <sys/syscallsubr.h>
   42 #include <sys/sysproto.h>
   43 #include <sys/unistd.h>
   44 
   45 #include <machine/pcb.h>
   46 
   47 #include <vm/vm.h>
   48 #include <vm/pmap.h>
   49 #include <vm/vm_map.h>
   50 
   51 #include <alpha/linux/linux.h>
   52 #include <alpha/linux/linux_proto.h>
   53 #include <compat/linux/linux_signal.h>
   54 #include <compat/linux/linux_util.h>
   55 
   56 struct linux_select_argv {
   57         int nfds;
   58         fd_set *readfds;
   59         fd_set *writefds;
   60         fd_set *exceptfds;
   61         struct timeval *timeout;
   62 };
   63 
   64 int
   65 linux_execve(struct thread *td, struct linux_execve_args *args)
   66 {
   67         struct execve_args bsd;
   68         caddr_t sg;
   69 
   70         sg = stackgap_init();
   71         CHECKALTEXIST(td, &sg, args->path);
   72 
   73 #ifdef DEBUG
   74         if (ldebug(execve))
   75                 printf(ARGS(execve, "%s"), args->path);
   76 #endif
   77         bsd.fname = args->path;
   78         bsd.argv = args->argp;
   79         bsd.envv = args->envp;
   80         return (execve(td, &bsd));
   81 }
   82 
   83 /*
   84  * MPSAFE
   85  */
   86 int
   87 linux_fork(struct thread *td, struct linux_fork_args *args)
   88 {
   89         int error;
   90 
   91 #ifdef DEBUG
   92         if (ldebug(fork))
   93                 printf(ARGS(fork, ""));
   94 #endif
   95         if ((error = fork(td, (struct fork_args *)args)) != 0)
   96                 return (error);
   97 
   98         if (td->td_retval[1] == 1)
   99                 td->td_retval[0] = 0;
  100 
  101         return (0);
  102 }
  103 
  104 /*
  105  * MPSAFE
  106  */
  107 int
  108 linux_vfork(struct thread *td, struct linux_vfork_args *args)
  109 {
  110         int error;
  111 
  112 #ifdef DEBUG
  113         if (ldebug(vfork))
  114                 printf(ARGS(vfork, ""));
  115 #endif
  116         if ((error = vfork(td, (struct vfork_args *)args)) != 0)
  117                 return (error);
  118         /* Are we the child? */
  119         if (td->td_retval[1] == 1)
  120                 td->td_retval[0] = 0;
  121         return (0);
  122 }
  123 
  124 #define CLONE_VM        0x100
  125 #define CLONE_FS        0x200
  126 #define CLONE_FILES     0x400
  127 #define CLONE_SIGHAND   0x800
  128 #define CLONE_PID       0x1000
  129 
  130 int
  131 linux_clone(struct thread *td, struct linux_clone_args *args)
  132 {
  133         int error, ff = RFPROC | RFSTOPPED;
  134         struct proc *p2;
  135         struct thread *td2;
  136         int exit_signal;
  137 
  138 #ifdef DEBUG
  139         if (ldebug(clone)) {
  140                 printf(ARGS(clone, "flags %x, stack %p"),
  141                     (unsigned int)args->flags, args->stack);
  142                 if (args->flags & CLONE_PID)
  143                     printf(LMSG("CLONE_PID not yet supported"));
  144         }
  145 #endif
  146 
  147         if (!args->stack)
  148                 return (EINVAL);
  149 
  150         exit_signal = args->flags & 0x000000ff;
  151         if (exit_signal >= LINUX_NSIG)
  152                 return (EINVAL);
  153 
  154 /*      if (exit_signal <= LINUX_SIGTBLSZ)
  155                 exit_signal = linux_to_bsd_signal[_SIG_IDX(exit_signal)];
  156 */
  157 
  158         if (args->flags & CLONE_VM)
  159                 ff |= RFMEM;
  160         if (args->flags & CLONE_SIGHAND)
  161                 ff |= RFSIGSHARE;
  162         if (!(args->flags & CLONE_FILES))
  163                 ff |= RFFDG;
  164 
  165         error = fork1(td, ff, 0, &p2);
  166         if (error)
  167                 return (error);
  168 
  169         PROC_LOCK(p2);
  170         p2->p_sigparent = exit_signal;
  171         PROC_UNLOCK(p2);
  172         td2 = FIRST_THREAD_IN_PROC(p2);
  173         td2->td_pcb->pcb_hw.apcb_usp = (unsigned long)args->stack;
  174 
  175 #ifdef DEBUG
  176         if (ldebug(clone))
  177                 printf(LMSG("clone: successful rfork to %ld, stack %p sig = %d"),
  178                     (long)p2->p_pid, args->stack, exit_signal);
  179 #endif
  180 
  181         /*
  182          * Make this runnable after we are finished with it.
  183          */
  184         mtx_lock_spin(&sched_lock);
  185         TD_SET_CAN_RUN(td2);
  186         setrunqueue(td2, SRQ_BORING);
  187         mtx_unlock_spin(&sched_lock);
  188 
  189         td->td_retval[0] = p2->p_pid;
  190         td->td_retval[1] = 0;
  191         return (0);
  192 }
  193 
  194 #define STACK_SIZE  (2 * 1024 * 1024)
  195 #define GUARD_SIZE  (4 * PAGE_SIZE)
  196 
  197 int
  198 linux_mmap(struct thread *td, struct linux_mmap_args *linux_args)
  199 {
  200         struct mmap_args /* {
  201                 caddr_t addr;
  202                 size_t len;
  203                 int prot;
  204                 int flags;
  205                 int fd;
  206                 long pad;
  207                 off_t pos;
  208         } */ bsd_args;
  209         int error;
  210 
  211 #ifdef DEBUG
  212         if (ldebug(mmap))
  213                 printf(ARGS(mmap, "%p, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx"),
  214                     (void *)linux_args->addr, linux_args->len,
  215                     linux_args->prot, linux_args->flags, linux_args->fd,
  216                     linux_args->pos);
  217 #endif
  218         bsd_args.prot = linux_args->prot | PROT_READ;   /* always required */
  219 
  220         bsd_args.flags = 0;
  221         if (linux_args->flags & LINUX_MAP_SHARED)
  222                 bsd_args.flags |= MAP_SHARED;
  223         if (linux_args->flags & LINUX_MAP_PRIVATE)
  224                 bsd_args.flags |= MAP_PRIVATE;
  225         if (linux_args->flags & LINUX_MAP_FIXED){
  226                 bsd_args.flags |= MAP_FIXED;
  227                 bsd_args.pos = trunc_page(linux_args->pos);
  228         } else {
  229                 bsd_args.pos = linux_args->pos;
  230         }
  231         if (linux_args->flags & LINUX_MAP_ANON)
  232                 bsd_args.flags |= MAP_ANON;
  233         if (linux_args->flags & LINUX_MAP_GROWSDOWN) {
  234                 bsd_args.flags |= MAP_STACK;
  235 
  236                 /* The linux MAP_GROWSDOWN option does not limit auto
  237                  * growth of the region.  Linux mmap with this option
  238                  * takes as addr the inital BOS, and as len, the initial
  239                  * region size.  It can then grow down from addr without
  240                  * limit.  However, linux threads has an implicit internal
  241                  * limit to stack size of STACK_SIZE.  Its just not
  242                  * enforced explicitly in linux.  But, here we impose
  243                  * a limit of (STACK_SIZE - GUARD_SIZE) on the stack
  244                  * region, since we can do this with our mmap.
  245                  *
  246                  * Our mmap with MAP_STACK takes addr as the maximum
  247                  * downsize limit on BOS, and as len the max size of
  248                  * the region.  It them maps the top SGROWSIZ bytes,
  249                  * and autgrows the region down, up to the limit
  250                  * in addr.
  251                  *
  252                  * If we don't use the MAP_STACK option, the effect
  253                  * of this code is to allocate a stack region of a
  254                  * fixed size of (STACK_SIZE - GUARD_SIZE).
  255                  */
  256 
  257                 /* This gives us TOS */
  258                 bsd_args.addr = (caddr_t)(linux_args->addr + linux_args->len);
  259 
  260                 /* This gives us our maximum stack size */
  261                 if (linux_args->len > STACK_SIZE - GUARD_SIZE)
  262                         bsd_args.len = linux_args->len;
  263                 else
  264                         bsd_args.len  = STACK_SIZE - GUARD_SIZE;
  265 
  266                 /* This gives us a new BOS.  If we're using VM_STACK, then
  267                  * mmap will just map the top SGROWSIZ bytes, and let
  268                  * the stack grow down to the limit at BOS.  If we're
  269                  * not using VM_STACK we map the full stack, since we
  270                  * don't have a way to autogrow it.
  271                  */
  272                 bsd_args.addr -= bsd_args.len;
  273                 bsd_args.addr = (caddr_t)round_page(bsd_args.addr); /* XXXX */
  274         } else {
  275                 bsd_args.addr = (caddr_t)linux_args->addr;
  276                 bsd_args.len  = linux_args->len;
  277         }
  278 
  279         bsd_args.fd = linux_args->fd;
  280         if(linux_args->fd == 0)
  281                 bsd_args.fd = -1;
  282 
  283         bsd_args.pad = 0;
  284 #ifdef DEBUG
  285         if (ldebug(mmap))
  286                 printf(ARGS(mmap, "%p, 0x%lx, 0x%x, 0x%x, 0x%x, 0x%lx"),
  287                     (void *)bsd_args.addr,
  288                     bsd_args.len,
  289                     bsd_args.prot,
  290                     bsd_args.flags,
  291                     bsd_args.fd,
  292                     bsd_args.pos);
  293 #endif
  294         if (bsd_args.addr == 0)
  295                 bsd_args.addr = (caddr_t)0x40000000UL;
  296         error = mmap(td, &bsd_args);
  297 #ifdef DEBUG
  298         if (ldebug(mmap))
  299                 printf(LMSG("mmap returns %d, 0x%lx"), error, td->td_retval[0]);
  300 #endif
  301         return (error);
  302 }
  303 
  304 int
  305 linux_rt_sigsuspend(td, uap)
  306         struct thread *td;
  307         struct linux_rt_sigsuspend_args *uap;
  308 {
  309         int error;
  310         l_sigset_t lmask;
  311         sigset_t bmask;
  312 
  313 #ifdef DEBUG
  314         if (ldebug(rt_sigsuspend))
  315                 printf(ARGS(rt_sigsuspend, "%p, %zd"),
  316                     (void *)uap->newset, uap->sigsetsize);
  317 #endif
  318         if (uap->sigsetsize != sizeof(l_sigset_t))
  319                 return (EINVAL);
  320 
  321         error = copyin(uap->newset, &lmask, sizeof(l_sigset_t));
  322         if (error)
  323                 return (error);
  324 
  325         linux_to_bsd_sigset(&lmask, &bmask);
  326         return (kern_sigsuspend(td, bmask));
  327 }
  328 
  329 int
  330 linux_mprotect(td, uap)
  331         struct thread *td;
  332         struct linux_mprotect_args *uap;
  333 {
  334 
  335 #ifdef DEBUG
  336         if (ldebug(mprotect))
  337                 printf(ARGS(mprotect, "%p, 0x%zx, 0x%lx"),
  338                     (void *)uap->addr, uap->len, uap->prot);
  339 #endif
  340         return (mprotect(td, (void *)uap));
  341 }
  342 
  343 int
  344 linux_munmap(td, uap)
  345         struct thread *td;
  346         struct linux_munmap_args *uap;
  347 {
  348 
  349 #ifdef DEBUG
  350         if (ldebug(munmap))
  351                 printf(ARGS(munmap, "%p, 0x%lx"),
  352                     (void *)uap->addr, uap->len);
  353 #endif
  354         return (munmap(td, (void *)uap));
  355 }
  356 
  357 static unsigned int linux_to_bsd_resource[LINUX_RLIM_NLIMITS] = {
  358         RLIMIT_CPU, RLIMIT_FSIZE, RLIMIT_DATA, RLIMIT_STACK,
  359         RLIMIT_CORE, RLIMIT_RSS, RLIMIT_NOFILE, -1,
  360         RLIMIT_NPROC, RLIMIT_MEMLOCK
  361 };
  362 
  363 int
  364 linux_setrlimit(td, uap)
  365         struct thread *td;
  366         struct linux_setrlimit_args *uap;
  367 {
  368         struct rlimit rlim;
  369         u_int which;
  370         int error;
  371 
  372 #ifdef DEBUG
  373         if (ldebug(setrlimit))
  374                 printf(ARGS(setrlimit, "%d, %p"),
  375                     uap->resource, (void *)uap->rlim);
  376 #endif
  377         if (uap->resource >= LINUX_RLIM_NLIMITS)
  378                 return EINVAL;
  379 
  380         which = linux_to_bsd_resource[uap->resource];
  381 
  382         if (which == -1)
  383                 return EINVAL;
  384 
  385         if ((error =
  386            copyin(uap->rlim, &rlim, sizeof (struct rlimit))))
  387                 return (error);
  388         return (kern_setrlimit(td,  which, &rlim));
  389 }
  390 
  391 int
  392 linux_getrlimit(td, uap)
  393         struct thread *td;
  394         struct linux_getrlimit_args *uap;
  395 {
  396         struct rlimit rlim;
  397         u_int which;
  398         int error;
  399 
  400 #ifdef DEBUG
  401         if (ldebug(getrlimit))
  402                 printf(ARGS(getrlimit, "%d, %p"),
  403                     uap->resource, (void *)uap->rlim);
  404 #endif
  405         if (uap->resource >= LINUX_RLIM_NLIMITS)
  406                 return EINVAL;
  407 
  408         which = linux_to_bsd_resource[uap->resource];
  409 
  410         if (which == -1)
  411                 return EINVAL;
  412 
  413         PROC_LOCK(td->td_proc);
  414         lim_rlimit(td->td_proc, which, &rlim);
  415         PROC_UNLOCK(td->td_proc);
  416         error = copyout(&rlim, uap->rlim, sizeof (struct rlimit));
  417         return (error);
  418 }

Cache object: 533ec863d8d1759e5c60187fc96a13c5


[ 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.