[BACK]Return to linux_sched.c CVS log [TXT][DIR] Up to [local] / sys / compat / linux

Annotation of sys/compat/linux/linux_sched.c, Revision 1.1.1.1

1.1       nbrk        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: }

CVSweb