freebsd_sched.c revision 1.10 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