1 /* $NetBSD: freebsd_sched.c,v 1.19 2008/04/28 20:23:41 martin 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 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 * FreeBSD compatibility module. Try to deal with scheduler related syscalls. 35 */ 36 37 #include <sys/cdefs.h> 38 __KERNEL_RCSID(0, "$NetBSD: freebsd_sched.c,v 1.19 2008/04/28 20:23:41 martin Exp $"); 39 40 #include <sys/param.h> 41 #include <sys/mount.h> 42 #include <sys/proc.h> 43 #include <sys/systm.h> 44 #include <sys/syscallargs.h> 45 #include <sys/kauth.h> 46 47 #include <sys/cpu.h> 48 49 #include <compat/freebsd/freebsd_syscallargs.h> 50 #include <compat/freebsd/freebsd_sched.h> 51 52 int 53 freebsd_sys_yield(struct lwp *l, const void *v, register_t *retval) 54 { 55 56 yield(); 57 return 0; 58 } 59 60 /* 61 * XXX: Needs adjustment to do a proper conversion. 62 */ 63 static int 64 sched_freebsd2native(int freebsd_policy, 65 struct freebsd_sched_param *freebsd_params, int *native_policy, 66 struct sched_param *native_params) 67 { 68 int error; 69 70 error = 0; 71 72 switch (freebsd_policy) { 73 case FREEBSD_SCHED_OTHER: 74 *native_policy = SCHED_OTHER; 75 break; 76 77 case FREEBSD_SCHED_FIFO: 78 *native_policy = SCHED_FIFO; 79 break; 80 81 case FREEBSD_SCHED_RR: 82 *native_policy = SCHED_RR; 83 break; 84 85 default: 86 error = EINVAL; 87 break; 88 } 89 90 if (freebsd_params != NULL && native_params != NULL && !error) { 91 native_params = (struct sched_param *)freebsd_params; 92 } 93 94 return (error); 95 } 96 97 /* 98 * XXX: Needs adjustment to do a proper conversion. 99 */ 100 static int 101 sched_native2freebsd(int native_policy, struct sched_param *native_params, 102 int *freebsd_policy, struct freebsd_sched_param *freebsd_params) 103 { 104 int error; 105 106 error = 0; 107 108 switch (native_policy) { 109 case SCHED_OTHER: 110 *freebsd_policy = FREEBSD_SCHED_OTHER; 111 break; 112 113 case SCHED_FIFO: 114 *freebsd_policy = FREEBSD_SCHED_FIFO; 115 break; 116 117 case SCHED_RR: 118 *freebsd_policy = FREEBSD_SCHED_RR; 119 break; 120 121 default: 122 error = EINVAL; 123 break; 124 } 125 126 if (native_params != NULL && freebsd_params != NULL && !error) { 127 freebsd_params = (struct freebsd_sched_param *)native_params; 128 } 129 130 return (error); 131 } 132 133 int 134 freebsd_sys_sched_setparam(struct lwp *l, const struct freebsd_sys_sched_setparam_args *uap, register_t *retval) 135 { 136 /* { 137 syscallarg(pid_t) pid; 138 syscallarg(const struct freebsd_sched_param *) sp; 139 } */ 140 int error, policy; 141 struct freebsd_sched_param lp; 142 struct sched_param sp; 143 144 if (SCARG(uap, pid) < 0 || SCARG(uap, sp) == NULL) { 145 error = EINVAL; 146 goto out; 147 } 148 149 error = copyin(SCARG(uap, sp), &lp, sizeof(lp)); 150 if (error) 151 goto out; 152 153 /* We need the current policy in FreeBSD terms. */ 154 error = do_sched_getparam(SCARG(uap, pid), 0, &policy, NULL); 155 if (error) 156 goto out; 157 error = sched_native2freebsd(policy, NULL, &policy, NULL); 158 if (error) 159 goto out; 160 161 error = sched_freebsd2native(policy, &lp, &policy, &sp); 162 if (error) 163 goto out; 164 165 error = do_sched_setparam(SCARG(uap, pid), 0, policy, &sp); 166 if (error) 167 goto out; 168 169 out: 170 return error; 171 } 172 173 int 174 freebsd_sys_sched_getparam(struct lwp *l, const struct freebsd_sys_sched_getparam_args *uap, register_t *retval) 175 { 176 /* { 177 syscallarg(pid_t) pid; 178 syscallarg(struct freebsd_sched_param *) sp; 179 } */ 180 struct freebsd_sched_param lp; 181 struct sched_param sp; 182 int error; 183 184 if (SCARG(uap, pid) < 0 || SCARG(uap, sp) == NULL) { 185 error = EINVAL; 186 goto out; 187 } 188 189 error = do_sched_getparam(SCARG(uap, pid), 0, NULL, &sp); 190 if (error) 191 goto out; 192 193 error = sched_native2freebsd(0, &sp, NULL, &lp); 194 if (error) 195 goto out; 196 197 error = copyout(&lp, SCARG(uap, sp), sizeof(lp)); 198 if (error) 199 goto out; 200 201 out: 202 return (error); 203 } 204 205 int 206 freebsd_sys_sched_setscheduler(struct lwp *l, const struct freebsd_sys_sched_setscheduler_args *uap, register_t *retval) 207 { 208 /* { 209 syscallarg(pid_t) pid; 210 syscallarg(int) policy; 211 syscallarg(cont struct freebsd_sched_scheduler *) sp; 212 } */ 213 int error, policy; 214 struct freebsd_sched_param lp; 215 struct sched_param sp; 216 217 if (SCARG(uap, pid) < 0 || SCARG(uap, sp) == NULL) { 218 error = EINVAL; 219 goto out; 220 } 221 222 error = copyin(SCARG(uap, sp), &lp, sizeof(lp)); 223 if (error) 224 goto out; 225 226 error = sched_freebsd2native(SCARG(uap, policy), &lp, &policy, &sp); 227 if (error) 228 goto out; 229 230 error = do_sched_setparam(SCARG(uap, pid), 0, policy, &sp); 231 if (error) 232 goto out; 233 234 out: 235 return error; 236 } 237 238 int 239 freebsd_sys_sched_getscheduler(struct lwp *l, const struct freebsd_sys_sched_getscheduler_args *uap, register_t *retval) 240 { 241 /* { 242 syscallarg(pid_t) pid; 243 } */ 244 int error, policy; 245 246 *retval = -1; 247 248 error = do_sched_getparam(SCARG(uap, pid), 0, &policy, NULL); 249 if (error) 250 goto out; 251 252 error = sched_native2freebsd(policy, NULL, &policy, NULL); 253 if (error) 254 goto out; 255 256 *retval = policy; 257 258 out: 259 return error; 260 } 261 262 int 263 freebsd_sys_sched_yield(struct lwp *l, const void *v, register_t *retval) 264 { 265 266 yield(); 267 return 0; 268 } 269 270 int 271 freebsd_sys_sched_get_priority_max(struct lwp *l, const struct freebsd_sys_sched_get_priority_max_args *uap, register_t *retval) 272 { 273 /* { 274 syscallarg(int) policy; 275 } */ 276 277 /* 278 * We can't emulate anything put the default scheduling policy. 279 */ 280 if (SCARG(uap, policy) != FREEBSD_SCHED_OTHER) { 281 *retval = -1; 282 return EINVAL; 283 } 284 285 *retval = 0; 286 return 0; 287 } 288 289 int 290 freebsd_sys_sched_get_priority_min(struct lwp *l, const struct freebsd_sys_sched_get_priority_min_args *uap, register_t *retval) 291 { 292 /* { 293 syscallarg(int) policy; 294 } */ 295 296 /* 297 * We can't emulate anything put the default scheduling policy. 298 */ 299 if (SCARG(uap, policy) != FREEBSD_SCHED_OTHER) { 300 *retval = -1; 301 return EINVAL; 302 } 303 304 *retval = 0; 305 return 0; 306 } 307