xref: /netbsd-src/sys/compat/freebsd/freebsd_sched.c (revision 8b0f9554ff8762542c4defc4f70e1eb76fb508fa)
1 /*	$NetBSD: freebsd_sched.c,v 1.11 2007/12/08 18:35:58 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.11 2007/12/08 18:35:58 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, 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(struct lwp *l, void *v, register_t *retval)
196 {
197 	struct freebsd_sys_sched_getscheduler_args /* {
198 		syscallarg(pid_t) pid;
199 	} */ *uap = v;
200 	int error;
201 
202 	*retval = -1;
203 
204 	/*
205 	 * We only check for valid parameters and return afterwards.
206 	 */
207 
208 	error = check_proc_access(l, SCARG(uap, pid));
209 	if (error)
210 		return error;
211 
212 	/*
213 	 * We can't emulate anything put the default scheduling policy.
214 	 */
215 	*retval = FREEBSD_SCHED_OTHER;
216 	return 0;
217 }
218 
219 int
220 freebsd_sys_sched_yield(struct lwp *l, void *v,
221     register_t *retval)
222 {
223 
224 	yield();
225 	return 0;
226 }
227 
228 int
229 freebsd_sys_sched_get_priority_max(struct lwp *l, void *v,
230     register_t *retval)
231 {
232 	struct freebsd_sys_sched_get_priority_max_args /* {
233 		syscallarg(int) policy;
234 	} */ *uap = v;
235 
236 	/*
237 	 * We can't emulate anything put the default scheduling policy.
238 	 */
239 	if (SCARG(uap, policy) != FREEBSD_SCHED_OTHER) {
240 		*retval = -1;
241 		return EINVAL;
242 	}
243 
244 	*retval = 0;
245 	return 0;
246 }
247 
248 int
249 freebsd_sys_sched_get_priority_min(struct lwp *l, void *v,
250     register_t *retval)
251 {
252 	struct freebsd_sys_sched_get_priority_min_args /* {
253 		syscallarg(int) policy;
254 	} */ *uap = v;
255 
256 	/*
257 	 * We can't emulate anything put the default scheduling policy.
258 	 */
259 	if (SCARG(uap, policy) != FREEBSD_SCHED_OTHER) {
260 		*retval = -1;
261 		return EINVAL;
262 	}
263 
264 	*retval = 0;
265 	return 0;
266 }
267