1 /* $NetBSD: linux_sched.c,v 1.12 2003/01/18 21:21:30 thorpej 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 * Linux compatibility module. Try to deal with scheduler related syscalls.
42 */
43
44 #include <sys/cdefs.h>
45 __KERNEL_RCSID(0, "$NetBSD: linux_sched.c,v 1.12 2003/01/18 21:21:30 thorpej 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/sa.h>
52 #include <sys/syscallargs.h>
53
54 #include <machine/cpu.h>
55
56 #include <compat/linux/common/linux_types.h>
57 #include <compat/linux/common/linux_signal.h>
58
59 #include <compat/linux/linux_syscallargs.h>
60
61 #include <compat/linux/common/linux_sched.h>
62
63 int
64 linux_sys_clone(l, v, retval)
65 struct lwp *l;
66 void *v;
67 register_t *retval;
68 {
69 struct linux_sys_clone_args /* {
70 syscallarg(int) flags;
71 syscallarg(void *) stack;
72 } */ *uap = v;
73 int flags, sig;
74
75 /*
76 * We don't support the Linux CLONE_PID or CLONE_PTRACE flags.
77 */
78 if (SCARG(uap, flags) & (LINUX_CLONE_PID|LINUX_CLONE_PTRACE))
79 return (EINVAL);
80
81 flags = 0;
82
83 if (SCARG(uap, flags) & LINUX_CLONE_VM)
84 flags |= FORK_SHAREVM;
85 if (SCARG(uap, flags) & LINUX_CLONE_FS)
86 flags |= FORK_SHARECWD;
87 if (SCARG(uap, flags) & LINUX_CLONE_FILES)
88 flags |= FORK_SHAREFILES;
89 if (SCARG(uap, flags) & LINUX_CLONE_SIGHAND)
90 flags |= FORK_SHARESIGS;
91 if (SCARG(uap, flags) & LINUX_CLONE_VFORK)
92 flags |= FORK_PPWAIT;
93
94 sig = SCARG(uap, flags) & LINUX_CLONE_CSIGNAL;
95 if (sig < 0 || sig >= LINUX__NSIG)
96 return (EINVAL);
97 sig = linux_to_native_signo[sig];
98
99 /*
100 * Note that Linux does not provide a portable way of specifying
101 * the stack area; the caller must know if the stack grows up
102 * or down. So, we pass a stack size of 0, so that the code
103 * that makes this adjustment is a noop.
104 */
105 return (fork1(l, flags, sig, SCARG(uap, stack), 0,
106 NULL, NULL, retval, NULL));
107 }
108
109 int
110 linux_sys_sched_setparam(cl, v, retval)
111 struct lwp *cl;
112 void *v;
113 register_t *retval;
114 {
115 struct linux_sys_sched_setparam_args /* {
116 syscallarg(linux_pid_t) pid;
117 syscallarg(const struct linux_sched_param *) sp;
118 } */ *uap = v;
119 struct proc *cp = cl->l_proc;
120 int error;
121 struct linux_sched_param lp;
122 struct proc *p;
123
124 /*
125 * We only check for valid parameters and return afterwards.
126 */
127
128 if (SCARG(uap, pid) < 0 || SCARG(uap, sp) == NULL)
129 return EINVAL;
130
131 error = copyin(SCARG(uap, sp), &lp, sizeof(lp));
132 if (error)
133 return error;
134
135 if (SCARG(uap, pid) != 0) {
136 struct pcred *pc = cp->p_cred;
137
138 if ((p = pfind(SCARG(uap, pid))) == NULL)
139 return ESRCH;
140 if (!(cp == p ||
141 pc->pc_ucred->cr_uid == 0 ||
142 pc->p_ruid == p->p_cred->p_ruid ||
143 pc->pc_ucred->cr_uid == p->p_cred->p_ruid ||
144 pc->p_ruid == p->p_ucred->cr_uid ||
145 pc->pc_ucred->cr_uid == p->p_ucred->cr_uid))
146 return EPERM;
147 }
148
149 return 0;
150 }
151
152 int
153 linux_sys_sched_getparam(cl, v, retval)
154 struct lwp *cl;
155 void *v;
156 register_t *retval;
157 {
158 struct linux_sys_sched_getparam_args /* {
159 syscallarg(linux_pid_t) pid;
160 syscallarg(struct linux_sched_param *) sp;
161 } */ *uap = v;
162 struct proc *cp = cl->l_proc;
163 struct proc *p;
164 struct linux_sched_param lp;
165
166 /*
167 * We only check for valid parameters and return a dummy priority afterwards.
168 */
169 if (SCARG(uap, pid) < 0 || SCARG(uap, sp) == NULL)
170 return EINVAL;
171
172 if (SCARG(uap, pid) != 0) {
173 struct pcred *pc = cp->p_cred;
174
175 if ((p = pfind(SCARG(uap, pid))) == NULL)
176 return ESRCH;
177 if (!(cp == p ||
178 pc->pc_ucred->cr_uid == 0 ||
179 pc->p_ruid == p->p_cred->p_ruid ||
180 pc->pc_ucred->cr_uid == p->p_cred->p_ruid ||
181 pc->p_ruid == p->p_ucred->cr_uid ||
182 pc->pc_ucred->cr_uid == p->p_ucred->cr_uid))
183 return EPERM;
184 }
185
186 lp.sched_priority = 0;
187 return copyout(&lp, SCARG(uap, sp), sizeof(lp));
188 }
189
190 int
191 linux_sys_sched_setscheduler(cl, v, retval)
192 struct lwp *cl;
193 void *v;
194 register_t *retval;
195 {
196 struct linux_sys_sched_setscheduler_args /* {
197 syscallarg(linux_pid_t) pid;
198 syscallarg(int) policy;
199 syscallarg(cont struct linux_sched_scheduler *) sp;
200 } */ *uap = v;
201 struct proc *cp = cl->l_proc;
202 int error;
203 struct linux_sched_param lp;
204 struct proc *p;
205
206 /*
207 * We only check for valid parameters and return afterwards.
208 */
209
210 if (SCARG(uap, pid) < 0 || SCARG(uap, sp) == NULL)
211 return EINVAL;
212
213 error = copyin(SCARG(uap, sp), &lp, sizeof(lp));
214 if (error)
215 return error;
216
217 if (SCARG(uap, pid) != 0) {
218 struct pcred *pc = cp->p_cred;
219
220 if ((p = pfind(SCARG(uap, pid))) == NULL)
221 return ESRCH;
222 if (!(cp == p ||
223 pc->pc_ucred->cr_uid == 0 ||
224 pc->p_ruid == p->p_cred->p_ruid ||
225 pc->pc_ucred->cr_uid == p->p_cred->p_ruid ||
226 pc->p_ruid == p->p_ucred->cr_uid ||
227 pc->pc_ucred->cr_uid == p->p_ucred->cr_uid))
228 return EPERM;
229 }
230
231 /*
232 * We can't emulate anything put the default scheduling policy.
233 */
234 if (SCARG(uap, policy) != LINUX_SCHED_OTHER || lp.sched_priority != 0)
235 return EINVAL;
236
237 return 0;
238 }
239
240 int
241 linux_sys_sched_getscheduler(cl, v, retval)
242 struct lwp *cl;
243 void *v;
244 register_t *retval;
245 {
246 struct linux_sys_sched_getscheduler_args /* {
247 syscallarg(linux_pid_t) pid;
248 } */ *uap = v;
249 struct proc *cp = cl->l_proc;
250 struct proc *p;
251
252 *retval = -1;
253 /*
254 * We only check for valid parameters and return afterwards.
255 */
256
257 if (SCARG(uap, pid) != 0) {
258 struct pcred *pc = cp->p_cred;
259
260 if ((p = pfind(SCARG(uap, pid))) == NULL)
261 return ESRCH;
262 if (!(cp == p ||
263 pc->pc_ucred->cr_uid == 0 ||
264 pc->p_ruid == p->p_cred->p_ruid ||
265 pc->pc_ucred->cr_uid == p->p_cred->p_ruid ||
266 pc->p_ruid == p->p_ucred->cr_uid ||
267 pc->pc_ucred->cr_uid == p->p_ucred->cr_uid))
268 return EPERM;
269 }
270
271 /*
272 * We can't emulate anything put the default scheduling policy.
273 */
274 *retval = LINUX_SCHED_OTHER;
275 return 0;
276 }
277
278 int
279 linux_sys_sched_yield(cl, v, retval)
280 struct lwp *cl;
281 void *v;
282 register_t *retval;
283 {
284
285 yield();
286 return 0;
287 }
288
289 int
290 linux_sys_sched_get_priority_max(cl, v, retval)
291 struct lwp *cl;
292 void *v;
293 register_t *retval;
294 {
295 struct linux_sys_sched_get_priority_max_args /* {
296 syscallarg(int) policy;
297 } */ *uap = v;
298
299 /*
300 * We can't emulate anything put the default scheduling policy.
301 */
302 if (SCARG(uap, policy) != LINUX_SCHED_OTHER) {
303 *retval = -1;
304 return EINVAL;
305 }
306
307 *retval = 0;
308 return 0;
309 }
310
311 int
312 linux_sys_sched_get_priority_min(cl, v, retval)
313 struct lwp *cl;
314 void *v;
315 register_t *retval;
316 {
317 struct linux_sys_sched_get_priority_min_args /* {
318 syscallarg(int) policy;
319 } */ *uap = v;
320
321 /*
322 * We can't emulate anything put the default scheduling policy.
323 */
324 if (SCARG(uap, policy) != LINUX_SCHED_OTHER) {
325 *retval = -1;
326 return EINVAL;
327 }
328
329 *retval = 0;
330 return 0;
331 }
Cache object: 5118a6f63478c1120d669594b542f0aa
|