1 /* $NetBSD: freebsd_sched.c,v 1.11 2007/12/08 18:35:58 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.11 2007/12/08 18:35:58 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, void *v, 61 register_t *retval) 62 { 63 64 yield(); 65 return 0; 66 } 67 68 /* 69 * Verify access to the target process. 70 * If we did any work this would need to return a reference to the 71 * proc and have the mutex still held. 72 * But we don't do anything, so it is ok. 73 */ 74 static int 75 check_proc_access(struct lwp *l, pid_t pid) 76 { 77 struct proc *p; 78 kauth_cred_t pc; 79 80 if (pid == 0) 81 return 0; 82 if (pid < 0) 83 return EINVAL; 84 85 mutex_enter(&proclist_lock); 86 87 p = p_find(pid, PFIND_LOCKED | PFIND_UNLOCK_FAIL); 88 if (p == NULL) 89 return ESRCH; 90 91 pc = l->l_cred; 92 93 if (!(l->l_proc == p || 94 kauth_cred_getuid(pc) == kauth_cred_getuid(p->p_cred) || 95 kauth_cred_geteuid(pc) == kauth_cred_getuid(p->p_cred) || 96 kauth_cred_getuid(pc) == kauth_cred_geteuid(p->p_cred) || 97 kauth_cred_geteuid(pc) == kauth_cred_geteuid(p->p_cred))) { 98 mutex_exit(&proclist_lock); 99 if (kauth_authorize_generic(pc, KAUTH_GENERIC_ISSUSER, NULL) != 0) 100 return EPERM; 101 } else 102 mutex_exit(&proclist_lock); 103 104 return 0; 105 } 106 107 int 108 freebsd_sys_sched_setparam(struct lwp *l, void *v, register_t *retval) 109 { 110 struct freebsd_sys_sched_setparam_args /* { 111 syscallarg(pid_t) pid; 112 syscallarg(const struct freebsd_sched_param *) sp; 113 } */ *uap = v; 114 int error; 115 struct freebsd_sched_param lp; 116 117 /* 118 * We only check for valid parameters and return afterwards. 119 */ 120 if (SCARG(uap, sp) == NULL) 121 return EINVAL; 122 123 error = copyin(SCARG(uap, sp), &lp, sizeof(lp)); 124 if (error) 125 return error; 126 127 error = check_proc_access(l, SCARG(uap, pid)); 128 if (error) 129 return error; 130 131 return 0; 132 } 133 134 int 135 freebsd_sys_sched_getparam(struct lwp *l, void *v, register_t *retval) 136 { 137 struct freebsd_sys_sched_getparam_args /* { 138 syscallarg(pid_t) pid; 139 syscallarg(struct freebsd_sched_param *) sp; 140 } */ *uap = v; 141 struct freebsd_sched_param lp; 142 int error; 143 144 /* 145 * We only check for valid parameters and return a dummy 146 * priority afterwards. 147 */ 148 if (SCARG(uap, sp) == NULL) 149 return EINVAL; 150 151 error = check_proc_access(l, SCARG(uap, pid)); 152 if (error) 153 return error; 154 155 lp.sched_priority = 0; 156 return copyout(&lp, SCARG(uap, sp), sizeof(lp)); 157 } 158 159 int 160 freebsd_sys_sched_setscheduler(struct lwp *l, void *v, 161 register_t *retval) 162 { 163 struct freebsd_sys_sched_setscheduler_args /* { 164 syscallarg(pid_t) pid; 165 syscallarg(int) policy; 166 syscallarg(cont struct freebsd_sched_scheduler *) sp; 167 } */ *uap = v; 168 int error; 169 struct freebsd_sched_param lp; 170 171 /* 172 * We only check for valid parameters and return afterwards. 173 */ 174 if (SCARG(uap, sp) == NULL) 175 return EINVAL; 176 177 error = copyin(SCARG(uap, sp), &lp, sizeof(lp)); 178 if (error) 179 return error; 180 181 error = check_proc_access(l, SCARG(uap, pid)); 182 if (error) 183 return error; 184 185 /* 186 * We can't emulate anything put the default scheduling policy. 187 */ 188 if (SCARG(uap, policy) != FREEBSD_SCHED_OTHER || lp.sched_priority != 0) 189 return EINVAL; 190 191 return 0; 192 } 193 194 int 195 freebsd_sys_sched_getscheduler(struct lwp *l, void *v, register_t *retval) 196 { 197 struct freebsd_sys_sched_getscheduler_args /* { 198 syscallarg(pid_t) pid; 199 } */ *uap = v; 200 int error; 201 202 *retval = -1; 203 204 /* 205 * We only check for valid parameters and return afterwards. 206 */ 207 208 error = check_proc_access(l, SCARG(uap, pid)); 209 if (error) 210 return error; 211 212 /* 213 * We can't emulate anything put the default scheduling policy. 214 */ 215 *retval = FREEBSD_SCHED_OTHER; 216 return 0; 217 } 218 219 int 220 freebsd_sys_sched_yield(struct lwp *l, void *v, 221 register_t *retval) 222 { 223 224 yield(); 225 return 0; 226 } 227 228 int 229 freebsd_sys_sched_get_priority_max(struct lwp *l, void *v, 230 register_t *retval) 231 { 232 struct freebsd_sys_sched_get_priority_max_args /* { 233 syscallarg(int) policy; 234 } */ *uap = v; 235 236 /* 237 * We can't emulate anything put the default scheduling policy. 238 */ 239 if (SCARG(uap, policy) != FREEBSD_SCHED_OTHER) { 240 *retval = -1; 241 return EINVAL; 242 } 243 244 *retval = 0; 245 return 0; 246 } 247 248 int 249 freebsd_sys_sched_get_priority_min(struct lwp *l, void *v, 250 register_t *retval) 251 { 252 struct freebsd_sys_sched_get_priority_min_args /* { 253 syscallarg(int) policy; 254 } */ *uap = v; 255 256 /* 257 * We can't emulate anything put the default scheduling policy. 258 */ 259 if (SCARG(uap, policy) != FREEBSD_SCHED_OTHER) { 260 *retval = -1; 261 return EINVAL; 262 } 263 264 *retval = 0; 265 return 0; 266 } 267