root/compat/linux/linux_sched.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. linux_sys_clone
  2. linux_sys_sched_setparam
  3. linux_sys_sched_getparam
  4. linux_sys_sched_setscheduler
  5. linux_sys_sched_getscheduler
  6. linux_sys_sched_yield
  7. linux_sys_sched_get_priority_max
  8. linux_sys_sched_get_priority_min

    1 /*      $OpenBSD: linux_sched.c,v 1.5 2004/11/23 19:08:52 miod Exp $    */
    2 /*      $NetBSD: linux_sched.c,v 1.6 2000/05/28 05:49:05 thorpej Exp $  */
    3 
    4 /*-
    5  * Copyright (c) 1999 The NetBSD Foundation, Inc.
    6  * All rights reserved.
    7  *
    8  * This code is derived from software contributed to The NetBSD Foundation
    9  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
   10  * NASA Ames Research Center; by Matthias Scheler.
   11  *
   12  * Redistribution and use in source and binary forms, with or without
   13  * modification, are permitted provided that the following conditions
   14  * are met:
   15  * 1. Redistributions of source code must retain the above copyright
   16  *    notice, this list of conditions and the following disclaimer.
   17  * 2. Redistributions in binary form must reproduce the above copyright
   18  *    notice, this list of conditions and the following disclaimer in the
   19  *    documentation and/or other materials provided with the distribution.
   20  * 3. All advertising materials mentioning features or use of this software
   21  *    must display the following acknowledgement:
   22  *      This product includes software developed by the NetBSD
   23  *      Foundation, Inc. and its contributors.
   24  * 4. Neither the name of The NetBSD Foundation nor the names of its
   25  *    contributors may be used to endorse or promote products derived
   26  *    from this software without specific prior written permission.
   27  *
   28  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   29  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   31  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   32  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   38  * POSSIBILITY OF SUCH DAMAGE.
   39  */
   40 
   41 /*
   42  * Linux compatibility module. Try to deal with scheduler related syscalls.
   43  */
   44 
   45 #include <sys/types.h>
   46 #include <sys/param.h>
   47 #include <sys/mount.h>
   48 #include <sys/proc.h>
   49 #include <sys/systm.h>
   50 #include <sys/syscallargs.h>
   51 
   52 #include <machine/cpu.h>
   53 
   54 #include <compat/linux/linux_types.h>
   55 #include <compat/linux/linux_sched.h>
   56 #include <compat/linux/linux_signal.h>
   57 #include <compat/linux/linux_syscallargs.h>
   58 
   59 int
   60 linux_sys_clone(p, v, retval)
   61         struct proc *p;
   62         void *v;
   63         register_t *retval;
   64 {
   65         struct linux_sys_clone_args /* {
   66                 syscallarg(int) flags;
   67                 syscallarg(void *) stack;
   68         } */ *uap = v;
   69         int flags = FORK_RFORK, sig;
   70 
   71         /*
   72          * We don't support the Linux CLONE_PID or CLONE_PTRACE flags.
   73          */
   74         if (SCARG(uap, flags) & (LINUX_CLONE_PID | LINUX_CLONE_PTRACE))
   75                 return (EINVAL);
   76 
   77         if (SCARG(uap, flags) & LINUX_CLONE_VM)
   78                 flags |= FORK_SHAREVM;
   79         /* XXX We pretend to support CLONE_FS for the moment.  */
   80         if (SCARG(uap, flags) & LINUX_CLONE_FILES)
   81                 flags |= FORK_SHAREFILES;
   82         if (SCARG(uap, flags) & LINUX_CLONE_SIGHAND)
   83                 flags |= FORK_SIGHAND;
   84         if (SCARG(uap, flags) & LINUX_CLONE_VFORK) {
   85                 flags |= FORK_PPWAIT;
   86         }
   87 
   88         sig = SCARG(uap, flags) & LINUX_CLONE_CSIGNAL;
   89         if (sig < 0 || sig >= LINUX__NSIG)
   90                 return (EINVAL);
   91         sig = linux_to_bsd_sig[sig];
   92 
   93         /*
   94          * Note that Linux does not provide a portable way of specifying
   95          * the stack area; the caller must know if the stack grows up
   96          * or down.  So, we pass a stack size of 0, so that the code
   97          * that makes this adjustment is a noop.
   98          */
   99         return (fork1(p, sig, flags, SCARG(uap, stack), 0, NULL, NULL, retval,
  100             NULL));
  101 }
  102 
  103 int
  104 linux_sys_sched_setparam(cp, v, retval)
  105         struct proc *cp;
  106         void *v;
  107         register_t *retval;
  108 {
  109         struct linux_sys_sched_setparam_args /* {
  110                 syscallarg(linux_pid_t) pid;
  111                 syscallarg(const struct linux_sched_param *) sp;
  112         } */ *uap = v;
  113         int error;
  114         struct linux_sched_param lp;
  115         struct proc *p;
  116 
  117         /*
  118          * We only check for valid parameters and return afterwards.
  119          */
  120 
  121         if (SCARG(uap, pid) < 0 || SCARG(uap, sp) == NULL)
  122                 return (EINVAL);
  123 
  124         error = copyin(SCARG(uap, sp), &lp, sizeof(lp));
  125         if (error)
  126                 return (error);
  127 
  128         if (SCARG(uap, pid) != 0) {
  129                 struct pcred *pc = cp->p_cred;
  130 
  131                 if ((p = pfind(SCARG(uap, pid))) == NULL)
  132                         return (ESRCH);
  133                 if (!(cp == p ||
  134                       pc->pc_ucred->cr_uid == 0 ||
  135                       pc->p_ruid == p->p_cred->p_ruid ||
  136                       pc->pc_ucred->cr_uid == p->p_cred->p_ruid ||
  137                       pc->p_ruid == p->p_ucred->cr_uid ||
  138                       pc->pc_ucred->cr_uid == p->p_ucred->cr_uid))
  139                         return (EPERM);
  140         }
  141 
  142         return (0);
  143 }
  144 
  145 int
  146 linux_sys_sched_getparam(cp, v, retval)
  147         struct proc *cp;
  148         void *v;
  149         register_t *retval;
  150 {
  151         struct linux_sys_sched_getparam_args /* {
  152                 syscallarg(linux_pid_t) pid;
  153                 syscallarg(struct linux_sched_param *) sp;
  154         } */ *uap = v;
  155         struct proc *p;
  156         struct linux_sched_param lp;
  157 
  158         /*
  159          * We only check for valid parameters and return a dummy priority
  160          * afterwards.
  161          */
  162         if (SCARG(uap, pid) < 0 || SCARG(uap, sp) == NULL)
  163                 return (EINVAL);
  164 
  165         if (SCARG(uap, pid) != 0) {
  166                 struct pcred *pc = cp->p_cred;
  167 
  168                 if ((p = pfind(SCARG(uap, pid))) == NULL)
  169                         return (ESRCH);
  170                 if (!(cp == p ||
  171                       pc->pc_ucred->cr_uid == 0 ||
  172                       pc->p_ruid == p->p_cred->p_ruid ||
  173                       pc->pc_ucred->cr_uid == p->p_cred->p_ruid ||
  174                       pc->p_ruid == p->p_ucred->cr_uid ||
  175                       pc->pc_ucred->cr_uid == p->p_ucred->cr_uid))
  176                         return (EPERM);
  177         }
  178 
  179         lp.sched_priority = 0;
  180         return (copyout(&lp, SCARG(uap, sp), sizeof lp));
  181 }
  182 
  183 int
  184 linux_sys_sched_setscheduler(cp, v, retval)
  185         struct proc *cp;
  186         void *v;
  187         register_t *retval;
  188 {
  189         struct linux_sys_sched_setscheduler_args /* {
  190                 syscallarg(linux_pid_t) pid;
  191                 syscallarg(int) policy;
  192                 syscallarg(cont struct linux_sched_scheduler *) sp;
  193         } */ *uap = v;
  194         int error;
  195         struct linux_sched_param lp;
  196         struct proc *p;
  197 
  198         /*
  199          * We only check for valid parameters and return afterwards.
  200          */
  201 
  202         if (SCARG(uap, pid) < 0 || SCARG(uap, sp) == NULL)
  203                 return (EINVAL);
  204 
  205         error = copyin(SCARG(uap, sp), &lp, sizeof(lp));
  206         if (error)
  207                 return (error);
  208 
  209         if (SCARG(uap, pid) != 0) {
  210                 struct pcred *pc = cp->p_cred;
  211 
  212                 if ((p = pfind(SCARG(uap, pid))) == NULL)
  213                         return (ESRCH);
  214                 if (!(cp == p ||
  215                       pc->pc_ucred->cr_uid == 0 ||
  216                       pc->p_ruid == p->p_cred->p_ruid ||
  217                       pc->pc_ucred->cr_uid == p->p_cred->p_ruid ||
  218                       pc->p_ruid == p->p_ucred->cr_uid ||
  219                       pc->pc_ucred->cr_uid == p->p_ucred->cr_uid))
  220                         return (EPERM);
  221         }
  222 
  223         /*
  224          * We can't emulate anything but the default scheduling policy.
  225          */
  226         if (SCARG(uap, policy) != LINUX_SCHED_OTHER || lp.sched_priority != 0)
  227                 return (EINVAL);
  228 
  229         return (0);
  230 }
  231 
  232 int
  233 linux_sys_sched_getscheduler(cp, v, retval)
  234         struct proc *cp;
  235         void *v;
  236         register_t *retval;
  237 {
  238         struct linux_sys_sched_getscheduler_args /* {
  239                 syscallarg(linux_pid_t) pid;
  240         } */ *uap = v;
  241         struct proc *p;
  242 
  243         *retval = -1;
  244 
  245         /*
  246          * We only check for valid parameters and return afterwards.
  247          */
  248 
  249         if (SCARG(uap, pid) != 0) {
  250                 struct pcred *pc = cp->p_cred;
  251 
  252                 if ((p = pfind(SCARG(uap, pid))) == NULL)
  253                         return (ESRCH);
  254                 if (!(cp == p ||
  255                       pc->pc_ucred->cr_uid == 0 ||
  256                       pc->p_ruid == p->p_cred->p_ruid ||
  257                       pc->pc_ucred->cr_uid == p->p_cred->p_ruid ||
  258                       pc->p_ruid == p->p_ucred->cr_uid ||
  259                       pc->pc_ucred->cr_uid == p->p_ucred->cr_uid))
  260                         return (EPERM);
  261         }
  262 
  263         /*
  264          * We can't emulate anything but the default scheduling policy.
  265          */
  266         *retval = LINUX_SCHED_OTHER;
  267         return (0);
  268 }
  269 
  270 int
  271 linux_sys_sched_yield(cp, v, retval)
  272         struct proc *cp;
  273         void *v;
  274         register_t *retval;
  275 {
  276         need_resched(curcpu());
  277         return (0);
  278 }
  279 
  280 int
  281 linux_sys_sched_get_priority_max(cp, v, retval)
  282         struct proc *cp;
  283         void *v;
  284         register_t *retval;
  285 {
  286         struct linux_sys_sched_get_priority_max_args /* {
  287                 syscallarg(int) policy;
  288         } */ *uap = v;
  289 
  290         /*
  291          * We can't emulate anything but the default scheduling policy.
  292          */
  293         if (SCARG(uap, policy) != LINUX_SCHED_OTHER) {
  294                 *retval = -1;
  295                 return (EINVAL);
  296         }
  297 
  298         *retval = 0;
  299         return (0);
  300 }
  301 
  302 int
  303 linux_sys_sched_get_priority_min(cp, v, retval)
  304         struct proc *cp;
  305         void *v;
  306         register_t *retval;
  307 {
  308         struct linux_sys_sched_get_priority_min_args /* {
  309                 syscallarg(int) policy;
  310         } */ *uap = v;
  311 
  312         /*
  313          * We can't emulate anything but the default scheduling policy.
  314          */
  315         if (SCARG(uap, policy) != LINUX_SCHED_OTHER) {
  316                 *retval = -1;
  317                 return (EINVAL);
  318         }
  319 
  320         *retval = 0;
  321         return (0);
  322 }

/* [<][>][^][v][top][bottom][index][help] */