Home | History | Annotate | Line # | Download | only in freebsd
freebsd_sched.c revision 1.12
      1 /*	$NetBSD: freebsd_sched.c,v 1.12 2007/12/20 23:02:47 dsl Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1999 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
      9  * NASA Ames Research Center; by Matthias Scheler.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions and the following disclaimer.
     16  * 2. Redistributions in binary form must reproduce the above copyright
     17  *    notice, this list of conditions and the following disclaimer in the
     18  *    documentation and/or other materials provided with the distribution.
     19  * 3. All advertising materials mentioning features or use of this software
     20  *    must display the following acknowledgement:
     21  *	This product includes software developed by the NetBSD
     22  *	Foundation, Inc. and its contributors.
     23  * 4. Neither the name of The NetBSD Foundation nor the names of its
     24  *    contributors may be used to endorse or promote products derived
     25  *    from this software without specific prior written permission.
     26  *
     27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     37  * POSSIBILITY OF SUCH DAMAGE.
     38  */
     39 
     40 /*
     41  * FreeBSD compatibility module. Try to deal with scheduler related syscalls.
     42  */
     43 
     44 #include <sys/cdefs.h>
     45 __KERNEL_RCSID(0, "$NetBSD: freebsd_sched.c,v 1.12 2007/12/20 23:02:47 dsl Exp $");
     46 
     47 #include <sys/param.h>
     48 #include <sys/mount.h>
     49 #include <sys/proc.h>
     50 #include <sys/systm.h>
     51 #include <sys/syscallargs.h>
     52 #include <sys/kauth.h>
     53 
     54 #include <sys/cpu.h>
     55 
     56 #include <compat/freebsd/freebsd_syscallargs.h>
     57 #include <compat/freebsd/freebsd_sched.h>
     58 
     59 int
     60 freebsd_sys_yield(struct lwp *l, const void *v, register_t *retval)
     61 {
     62 
     63 	yield();
     64 	return 0;
     65 }
     66 
     67 /*
     68  * Verify access to the target process.
     69  * If we did any work this would need to return a reference to the
     70  * proc and have the mutex still held.
     71  * But we don't do anything, so it is ok.
     72  */
     73 static int
     74 check_proc_access(struct lwp *l, pid_t pid)
     75 {
     76 	struct proc *p;
     77 	kauth_cred_t pc;
     78 
     79 	if (pid == 0)
     80 		return 0;
     81 	if (pid < 0)
     82 		return EINVAL;
     83 
     84 	mutex_enter(&proclist_lock);
     85 
     86 	p = p_find(pid, PFIND_LOCKED | PFIND_UNLOCK_FAIL);
     87 	if (p == NULL)
     88 		return ESRCH;
     89 
     90 	pc = l->l_cred;
     91 
     92 	if (!(l->l_proc == p ||
     93 	    kauth_cred_getuid(pc) == kauth_cred_getuid(p->p_cred) ||
     94 	    kauth_cred_geteuid(pc) == kauth_cred_getuid(p->p_cred) ||
     95 	    kauth_cred_getuid(pc) == kauth_cred_geteuid(p->p_cred) ||
     96 	    kauth_cred_geteuid(pc) == kauth_cred_geteuid(p->p_cred))) {
     97 		mutex_exit(&proclist_lock);
     98 		if (kauth_authorize_generic(pc, KAUTH_GENERIC_ISSUSER, NULL) != 0)
     99 		    return EPERM;
    100 	} else
    101 		mutex_exit(&proclist_lock);
    102 
    103 	return 0;
    104 }
    105 
    106 int
    107 freebsd_sys_sched_setparam(struct lwp *l, const struct freebsd_sys_sched_setparam_args *uap, register_t *retval)
    108 {
    109 	/* {
    110 		syscallarg(pid_t) pid;
    111 		syscallarg(const struct freebsd_sched_param *) sp;
    112 	} */
    113 	int error;
    114 	struct freebsd_sched_param lp;
    115 
    116 	/*
    117 	 * We only check for valid parameters and return afterwards.
    118 	 */
    119 	if (SCARG(uap, sp) == NULL)
    120 		return EINVAL;
    121 
    122 	error = copyin(SCARG(uap, sp), &lp, sizeof(lp));
    123 	if (error)
    124 		return error;
    125 
    126 	error = check_proc_access(l, SCARG(uap, pid));
    127 	if (error)
    128 		return error;
    129 
    130 	return 0;
    131 }
    132 
    133 int
    134 freebsd_sys_sched_getparam(struct lwp *l, const struct freebsd_sys_sched_getparam_args *uap, register_t *retval)
    135 {
    136 	/* {
    137 		syscallarg(pid_t) pid;
    138 		syscallarg(struct freebsd_sched_param *) sp;
    139 	} */
    140 	struct freebsd_sched_param lp;
    141 	int error;
    142 
    143 	/*
    144 	 * We only check for valid parameters and return a dummy
    145 	 * priority afterwards.
    146 	 */
    147 	if (SCARG(uap, sp) == NULL)
    148 		return EINVAL;
    149 
    150 	error = check_proc_access(l, SCARG(uap, pid));
    151 	if (error)
    152 		return error;
    153 
    154 	lp.sched_priority = 0;
    155 	return copyout(&lp, SCARG(uap, sp), sizeof(lp));
    156 }
    157 
    158 int
    159 freebsd_sys_sched_setscheduler(struct lwp *l, const struct freebsd_sys_sched_setscheduler_args *uap, register_t *retval)
    160 {
    161 	/* {
    162 		syscallarg(pid_t) pid;
    163 		syscallarg(int) policy;
    164 		syscallarg(cont struct freebsd_sched_scheduler *) sp;
    165 	} */
    166 	int error;
    167 	struct freebsd_sched_param lp;
    168 
    169 	/*
    170 	 * We only check for valid parameters and return afterwards.
    171 	 */
    172 	if (SCARG(uap, sp) == NULL)
    173 		return EINVAL;
    174 
    175 	error = copyin(SCARG(uap, sp), &lp, sizeof(lp));
    176 	if (error)
    177 		return error;
    178 
    179 	error = check_proc_access(l, SCARG(uap, pid));
    180 	if (error)
    181 		return error;
    182 
    183 	/*
    184 	 * We can't emulate anything put the default scheduling policy.
    185 	 */
    186 	if (SCARG(uap, policy) != FREEBSD_SCHED_OTHER || lp.sched_priority != 0)
    187 		return EINVAL;
    188 
    189 	return 0;
    190 }
    191 
    192 int
    193 freebsd_sys_sched_getscheduler(struct lwp *l, const struct freebsd_sys_sched_getscheduler_args *uap, register_t *retval)
    194 {
    195 	/* {
    196 		syscallarg(pid_t) pid;
    197 	} */
    198 	int error;
    199 
    200 	*retval = -1;
    201 
    202 	/*
    203 	 * We only check for valid parameters and return afterwards.
    204 	 */
    205 
    206 	error = check_proc_access(l, SCARG(uap, pid));
    207 	if (error)
    208 		return error;
    209 
    210 	/*
    211 	 * We can't emulate anything put the default scheduling policy.
    212 	 */
    213 	*retval = FREEBSD_SCHED_OTHER;
    214 	return 0;
    215 }
    216 
    217 int
    218 freebsd_sys_sched_yield(struct lwp *l, const void *v, register_t *retval)
    219 {
    220 
    221 	yield();
    222 	return 0;
    223 }
    224 
    225 int
    226 freebsd_sys_sched_get_priority_max(struct lwp *l, const struct freebsd_sys_sched_get_priority_max_args *uap, register_t *retval)
    227 {
    228 	/* {
    229 		syscallarg(int) policy;
    230 	} */
    231 
    232 	/*
    233 	 * We can't emulate anything put the default scheduling policy.
    234 	 */
    235 	if (SCARG(uap, policy) != FREEBSD_SCHED_OTHER) {
    236 		*retval = -1;
    237 		return EINVAL;
    238 	}
    239 
    240 	*retval = 0;
    241 	return 0;
    242 }
    243 
    244 int
    245 freebsd_sys_sched_get_priority_min(struct lwp *l, const struct freebsd_sys_sched_get_priority_min_args *uap, register_t *retval)
    246 {
    247 	/* {
    248 		syscallarg(int) policy;
    249 	} */
    250 
    251 	/*
    252 	 * We can't emulate anything put the default scheduling policy.
    253 	 */
    254 	if (SCARG(uap, policy) != FREEBSD_SCHED_OTHER) {
    255 		*retval = -1;
    256 		return EINVAL;
    257 	}
    258 
    259 	*retval = 0;
    260 	return 0;
    261 }
    262