1 /* $NetBSD: freebsd_sched.c,v 1.22 2014/06/28 11:06:31 maxv 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.22 2014/06/28 11:06:31 maxv 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 const struct freebsd_sched_param *freebsd_params, int *native_policy, 66 struct sched_param *native_params) 67 { 68 int p; 69 70 switch (freebsd_policy) { 71 case FREEBSD_SCHED_OTHER: 72 p = SCHED_OTHER; 73 break; 74 75 case FREEBSD_SCHED_FIFO: 76 p = SCHED_FIFO; 77 break; 78 79 case FREEBSD_SCHED_RR: 80 p = SCHED_RR; 81 break; 82 83 default: 84 return EINVAL; 85 } 86 87 if (native_policy != NULL) 88 *native_policy = p; 89 90 if (freebsd_params != NULL && native_params != NULL) { 91 /* XXX: Needs adjustment to do a proper conversion. */ 92 native_params->sched_priority = freebsd_params->sched_priority; 93 } 94 return 0; 95 } 96 97 static int 98 sched_native2freebsd(int native_policy, const struct sched_param *native_params, 99 int *freebsd_policy, struct freebsd_sched_param *freebsd_params) 100 { 101 int p; 102 103 switch (native_policy) { 104 case SCHED_OTHER: 105 p = FREEBSD_SCHED_OTHER; 106 break; 107 108 case SCHED_FIFO: 109 p = FREEBSD_SCHED_FIFO; 110 break; 111 112 case SCHED_RR: 113 p = FREEBSD_SCHED_RR; 114 break; 115 116 default: 117 return EINVAL; 118 } 119 120 if (freebsd_policy != NULL) 121 *freebsd_policy = p; 122 123 if (native_params != NULL && freebsd_params != NULL) { 124 /* XXX: Needs adjustment to do a proper conversion. */ 125 freebsd_params->sched_priority = native_params->sched_priority; 126 } 127 128 return 0; 129 } 130 131 int 132 freebsd_sys_sched_setparam(struct lwp *l, const struct freebsd_sys_sched_setparam_args *uap, register_t *retval) 133 { 134 /* { 135 syscallarg(pid_t) pid; 136 syscallarg(const struct freebsd_sched_param *) sp; 137 } */ 138 int error, policy; 139 struct freebsd_sched_param lp; 140 struct sched_param sp; 141 142 if (SCARG(uap, pid) < 0 || SCARG(uap, sp) == NULL) { 143 error = EINVAL; 144 goto out; 145 } 146 147 error = copyin(SCARG(uap, sp), &lp, sizeof(lp)); 148 if (error) 149 goto out; 150 151 /* We need the current policy in FreeBSD terms. */ 152 error = do_sched_getparam(SCARG(uap, pid), 0, &policy, NULL); 153 if (error) 154 goto out; 155 error = sched_native2freebsd(policy, NULL, &policy, NULL); 156 if (error) 157 goto out; 158 159 error = sched_freebsd2native(policy, &lp, &policy, &sp); 160 if (error) 161 goto out; 162 163 error = do_sched_setparam(SCARG(uap, pid), 0, policy, &sp); 164 if (error) 165 goto out; 166 167 out: 168 return error; 169 } 170 171 int 172 freebsd_sys_sched_getparam(struct lwp *l, const struct freebsd_sys_sched_getparam_args *uap, register_t *retval) 173 { 174 /* { 175 syscallarg(pid_t) pid; 176 syscallarg(struct freebsd_sched_param *) sp; 177 } */ 178 struct freebsd_sched_param lp; 179 struct sched_param sp; 180 int error; 181 182 if (SCARG(uap, pid) < 0 || SCARG(uap, sp) == NULL) { 183 error = EINVAL; 184 goto out; 185 } 186 187 error = do_sched_getparam(SCARG(uap, pid), 0, NULL, &sp); 188 if (error) 189 goto out; 190 191 error = sched_native2freebsd(0, &sp, NULL, &lp); 192 if (error) 193 goto out; 194 195 error = copyout(&lp, SCARG(uap, sp), sizeof(lp)); 196 if (error) 197 goto out; 198 199 out: 200 return error; 201 } 202 203 int 204 freebsd_sys_sched_setscheduler(struct lwp *l, const struct freebsd_sys_sched_setscheduler_args *uap, register_t *retval) 205 { 206 /* { 207 syscallarg(pid_t) pid; 208 syscallarg(int) policy; 209 syscallarg(cont struct freebsd_sched_scheduler *) sp; 210 } */ 211 int error, policy; 212 struct freebsd_sched_param lp; 213 struct sched_param sp; 214 215 if (SCARG(uap, pid) < 0 || SCARG(uap, sp) == NULL) { 216 error = EINVAL; 217 goto out; 218 } 219 220 error = copyin(SCARG(uap, sp), &lp, sizeof(lp)); 221 if (error) 222 goto out; 223 224 error = sched_freebsd2native(SCARG(uap, policy), &lp, &policy, &sp); 225 if (error) 226 goto out; 227 228 error = do_sched_setparam(SCARG(uap, pid), 0, policy, &sp); 229 if (error) 230 goto out; 231 232 out: 233 return error; 234 } 235 236 int 237 freebsd_sys_sched_getscheduler(struct lwp *l, const struct freebsd_sys_sched_getscheduler_args *uap, register_t *retval) 238 { 239 /* { 240 syscallarg(pid_t) pid; 241 } */ 242 int error, policy; 243 244 *retval = -1; 245 246 error = do_sched_getparam(SCARG(uap, pid), 0, &policy, NULL); 247 if (error) 248 goto out; 249 250 error = sched_native2freebsd(policy, NULL, &policy, NULL); 251 if (error) 252 goto out; 253 254 *retval = policy; 255 256 out: 257 return error; 258 } 259 260 int 261 freebsd_sys_sched_yield(struct lwp *l, const void *v, register_t *retval) 262 { 263 264 yield(); 265 return 0; 266 } 267 268 int 269 freebsd_sys_sched_get_priority_max(struct lwp *l, const struct freebsd_sys_sched_get_priority_max_args *uap, register_t *retval) 270 { 271 /* { 272 syscallarg(int) policy; 273 } */ 274 275 /* 276 * We can't emulate anything put the default scheduling policy. 277 */ 278 if (SCARG(uap, policy) != FREEBSD_SCHED_OTHER) { 279 *retval = -1; 280 return EINVAL; 281 } 282 283 *retval = 0; 284 return 0; 285 } 286 287 int 288 freebsd_sys_sched_get_priority_min(struct lwp *l, const struct freebsd_sys_sched_get_priority_min_args *uap, register_t *retval) 289 { 290 /* { 291 syscallarg(int) policy; 292 } */ 293 294 /* 295 * We can't emulate anything put the default scheduling policy. 296 */ 297 if (SCARG(uap, policy) != FREEBSD_SCHED_OTHER) { 298 *retval = -1; 299 return EINVAL; 300 } 301 302 *retval = 0; 303 return 0; 304 } 305