freebsd_sched.c revision 1.12 1 /* $NetBSD: freebsd_sched.c,v 1.12 2007/12/20 23:02:47 dsl 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.12 2007/12/20 23:02:47 dsl 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, const void *v, register_t *retval)
61 {
62
63 yield();
64 return 0;
65 }
66
67 /*
68 * Verify access to the target process.
69 * If we did any work this would need to return a reference to the
70 * proc and have the mutex still held.
71 * But we don't do anything, so it is ok.
72 */
73 static int
74 check_proc_access(struct lwp *l, pid_t pid)
75 {
76 struct proc *p;
77 kauth_cred_t pc;
78
79 if (pid == 0)
80 return 0;
81 if (pid < 0)
82 return EINVAL;
83
84 mutex_enter(&proclist_lock);
85
86 p = p_find(pid, PFIND_LOCKED | PFIND_UNLOCK_FAIL);
87 if (p == NULL)
88 return ESRCH;
89
90 pc = l->l_cred;
91
92 if (!(l->l_proc == p ||
93 kauth_cred_getuid(pc) == kauth_cred_getuid(p->p_cred) ||
94 kauth_cred_geteuid(pc) == kauth_cred_getuid(p->p_cred) ||
95 kauth_cred_getuid(pc) == kauth_cred_geteuid(p->p_cred) ||
96 kauth_cred_geteuid(pc) == kauth_cred_geteuid(p->p_cred))) {
97 mutex_exit(&proclist_lock);
98 if (kauth_authorize_generic(pc, KAUTH_GENERIC_ISSUSER, NULL) != 0)
99 return EPERM;
100 } else
101 mutex_exit(&proclist_lock);
102
103 return 0;
104 }
105
106 int
107 freebsd_sys_sched_setparam(struct lwp *l, const struct freebsd_sys_sched_setparam_args *uap, register_t *retval)
108 {
109 /* {
110 syscallarg(pid_t) pid;
111 syscallarg(const struct freebsd_sched_param *) sp;
112 } */
113 int error;
114 struct freebsd_sched_param lp;
115
116 /*
117 * We only check for valid parameters and return afterwards.
118 */
119 if (SCARG(uap, sp) == NULL)
120 return EINVAL;
121
122 error = copyin(SCARG(uap, sp), &lp, sizeof(lp));
123 if (error)
124 return error;
125
126 error = check_proc_access(l, SCARG(uap, pid));
127 if (error)
128 return error;
129
130 return 0;
131 }
132
133 int
134 freebsd_sys_sched_getparam(struct lwp *l, const struct freebsd_sys_sched_getparam_args *uap, register_t *retval)
135 {
136 /* {
137 syscallarg(pid_t) pid;
138 syscallarg(struct freebsd_sched_param *) sp;
139 } */
140 struct freebsd_sched_param lp;
141 int error;
142
143 /*
144 * We only check for valid parameters and return a dummy
145 * priority afterwards.
146 */
147 if (SCARG(uap, sp) == NULL)
148 return EINVAL;
149
150 error = check_proc_access(l, SCARG(uap, pid));
151 if (error)
152 return error;
153
154 lp.sched_priority = 0;
155 return copyout(&lp, SCARG(uap, sp), sizeof(lp));
156 }
157
158 int
159 freebsd_sys_sched_setscheduler(struct lwp *l, const struct freebsd_sys_sched_setscheduler_args *uap, register_t *retval)
160 {
161 /* {
162 syscallarg(pid_t) pid;
163 syscallarg(int) policy;
164 syscallarg(cont struct freebsd_sched_scheduler *) sp;
165 } */
166 int error;
167 struct freebsd_sched_param lp;
168
169 /*
170 * We only check for valid parameters and return afterwards.
171 */
172 if (SCARG(uap, sp) == NULL)
173 return EINVAL;
174
175 error = copyin(SCARG(uap, sp), &lp, sizeof(lp));
176 if (error)
177 return error;
178
179 error = check_proc_access(l, SCARG(uap, pid));
180 if (error)
181 return error;
182
183 /*
184 * We can't emulate anything put the default scheduling policy.
185 */
186 if (SCARG(uap, policy) != FREEBSD_SCHED_OTHER || lp.sched_priority != 0)
187 return EINVAL;
188
189 return 0;
190 }
191
192 int
193 freebsd_sys_sched_getscheduler(struct lwp *l, const struct freebsd_sys_sched_getscheduler_args *uap, register_t *retval)
194 {
195 /* {
196 syscallarg(pid_t) pid;
197 } */
198 int error;
199
200 *retval = -1;
201
202 /*
203 * We only check for valid parameters and return afterwards.
204 */
205
206 error = check_proc_access(l, SCARG(uap, pid));
207 if (error)
208 return error;
209
210 /*
211 * We can't emulate anything put the default scheduling policy.
212 */
213 *retval = FREEBSD_SCHED_OTHER;
214 return 0;
215 }
216
217 int
218 freebsd_sys_sched_yield(struct lwp *l, const void *v, register_t *retval)
219 {
220
221 yield();
222 return 0;
223 }
224
225 int
226 freebsd_sys_sched_get_priority_max(struct lwp *l, const struct freebsd_sys_sched_get_priority_max_args *uap, register_t *retval)
227 {
228 /* {
229 syscallarg(int) policy;
230 } */
231
232 /*
233 * We can't emulate anything put the default scheduling policy.
234 */
235 if (SCARG(uap, policy) != FREEBSD_SCHED_OTHER) {
236 *retval = -1;
237 return EINVAL;
238 }
239
240 *retval = 0;
241 return 0;
242 }
243
244 int
245 freebsd_sys_sched_get_priority_min(struct lwp *l, const struct freebsd_sys_sched_get_priority_min_args *uap, register_t *retval)
246 {
247 /* {
248 syscallarg(int) policy;
249 } */
250
251 /*
252 * We can't emulate anything put the default scheduling policy.
253 */
254 if (SCARG(uap, policy) != FREEBSD_SCHED_OTHER) {
255 *retval = -1;
256 return EINVAL;
257 }
258
259 *retval = 0;
260 return 0;
261 }
262