1 /* $NetBSD: freebsd_sched.c,v 1.10 2007/10/19 12:16:36 ad 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.10 2007/10/19 12:16:36 ad 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(l, v, retval) 196 struct lwp *l; 197 void *v; 198 register_t *retval; 199 { 200 struct freebsd_sys_sched_getscheduler_args /* { 201 syscallarg(pid_t) pid; 202 } */ *uap = v; 203 int error; 204 205 *retval = -1; 206 207 /* 208 * We only check for valid parameters and return afterwards. 209 */ 210 211 error = check_proc_access(l, SCARG(uap, pid)); 212 if (error) 213 return error; 214 215 /* 216 * We can't emulate anything put the default scheduling policy. 217 */ 218 *retval = FREEBSD_SCHED_OTHER; 219 return 0; 220 } 221 222 int 223 freebsd_sys_sched_yield(struct lwp *l, void *v, 224 register_t *retval) 225 { 226 227 yield(); 228 return 0; 229 } 230 231 int 232 freebsd_sys_sched_get_priority_max(struct lwp *l, void *v, 233 register_t *retval) 234 { 235 struct freebsd_sys_sched_get_priority_max_args /* { 236 syscallarg(int) policy; 237 } */ *uap = v; 238 239 /* 240 * We can't emulate anything put the default scheduling policy. 241 */ 242 if (SCARG(uap, policy) != FREEBSD_SCHED_OTHER) { 243 *retval = -1; 244 return EINVAL; 245 } 246 247 *retval = 0; 248 return 0; 249 } 250 251 int 252 freebsd_sys_sched_get_priority_min(struct lwp *l, void *v, 253 register_t *retval) 254 { 255 struct freebsd_sys_sched_get_priority_min_args /* { 256 syscallarg(int) policy; 257 } */ *uap = v; 258 259 /* 260 * We can't emulate anything put the default scheduling policy. 261 */ 262 if (SCARG(uap, policy) != FREEBSD_SCHED_OTHER) { 263 *retval = -1; 264 return EINVAL; 265 } 266 267 *retval = 0; 268 return 0; 269 } 270