xref: /freebsd/sys/kern/p1003_1b.c (revision f4636c595963ab77fae559bb5eb35e54c9951538)
18a6472b7SPeter Dufault /*
28a6472b7SPeter Dufault  * Copyright (c) 1996, 1997, 1998
38a6472b7SPeter Dufault  *	HD Associates, Inc.  All rights reserved.
48a6472b7SPeter Dufault  *
58a6472b7SPeter Dufault  * Redistribution and use in source and binary forms, with or without
68a6472b7SPeter Dufault  * modification, are permitted provided that the following conditions
78a6472b7SPeter Dufault  * are met:
88a6472b7SPeter Dufault  * 1. Redistributions of source code must retain the above copyright
98a6472b7SPeter Dufault  *    notice, this list of conditions and the following disclaimer.
108a6472b7SPeter Dufault  * 2. Redistributions in binary form must reproduce the above copyright
118a6472b7SPeter Dufault  *    notice, this list of conditions and the following disclaimer in the
128a6472b7SPeter Dufault  *    documentation and/or other materials provided with the distribution.
138a6472b7SPeter Dufault  * 3. All advertising materials mentioning features or use of this software
148a6472b7SPeter Dufault  *    must display the following acknowledgement:
158a6472b7SPeter Dufault  *	This product includes software developed by HD Associates, Inc
168a6472b7SPeter Dufault  * 4. Neither the name of the author nor the names of any co-contributors
178a6472b7SPeter Dufault  *    may be used to endorse or promote products derived from this software
188a6472b7SPeter Dufault  *    without specific prior written permission.
198a6472b7SPeter Dufault  *
208a6472b7SPeter Dufault  * THIS SOFTWARE IS PROVIDED BY HD ASSOCIATES AND CONTRIBUTORS ``AS IS'' AND
218a6472b7SPeter Dufault  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
228a6472b7SPeter Dufault  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
238a6472b7SPeter Dufault  * ARE DISCLAIMED.  IN NO EVENT SHALL HD ASSOCIATES OR CONTRIBUTORS BE LIABLE
248a6472b7SPeter Dufault  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
258a6472b7SPeter Dufault  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
268a6472b7SPeter Dufault  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
278a6472b7SPeter Dufault  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
288a6472b7SPeter Dufault  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
298a6472b7SPeter Dufault  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
308a6472b7SPeter Dufault  * SUCH DAMAGE.
318a6472b7SPeter Dufault  */
328a6472b7SPeter Dufault 
338a6472b7SPeter Dufault /* p1003_1b: Real Time common code.
348a6472b7SPeter Dufault  */
358a6472b7SPeter Dufault 
36f4636c59SDavid E. O'Brien #include <sys/cdefs.h>
37f4636c59SDavid E. O'Brien __FBSDID("$FreeBSD$");
38f4636c59SDavid E. O'Brien 
39b565fb9eSAlfred Perlstein #include "opt_posix.h"
40b565fb9eSAlfred Perlstein 
418a6472b7SPeter Dufault #include <sys/param.h>
428a6472b7SPeter Dufault #include <sys/systm.h>
438a6472b7SPeter Dufault #include <sys/kernel.h>
44fb919e4dSMark Murray #include <sys/lock.h>
458a6472b7SPeter Dufault #include <sys/module.h>
46fb919e4dSMark Murray #include <sys/mutex.h>
47fb919e4dSMark Murray #include <sys/proc.h>
488a6472b7SPeter Dufault #include <sys/sysctl.h>
49fb919e4dSMark Murray #include <sys/sysent.h>
50fb919e4dSMark Murray #include <sys/syslog.h>
51fb919e4dSMark Murray #include <sys/sysproto.h>
528a6472b7SPeter Dufault 
538a6472b7SPeter Dufault #include <posix4/posix4.h>
548a6472b7SPeter Dufault 
558a6472b7SPeter Dufault MALLOC_DEFINE(M_P31B, "p1003.1b", "Posix 1003.1B");
568a6472b7SPeter Dufault 
572a61a110SPeter Dufault /* The system calls return ENOSYS if an entry is called that is
582a61a110SPeter Dufault  * not run-time supported.  I am also logging since some programs
592a61a110SPeter Dufault  * start to use this when they shouldn't.  That will be removed if annoying.
602a61a110SPeter Dufault  */
618a6472b7SPeter Dufault int
62b40ce416SJulian Elischer syscall_not_present(struct thread *td, const char *s, struct nosys_args *uap)
638a6472b7SPeter Dufault {
648a6472b7SPeter Dufault 	log(LOG_ERR, "cmd %s pid %d tried to use non-present %s\n",
65b40ce416SJulian Elischer 			td->td_proc->p_comm, td->td_proc->p_pid, s);
662a61a110SPeter Dufault 
672a61a110SPeter Dufault 	/* a " return nosys(p, uap); " here causes a core dump.
682a61a110SPeter Dufault 	 */
692a61a110SPeter Dufault 
702a61a110SPeter Dufault 	return ENOSYS;
718a6472b7SPeter Dufault }
728a6472b7SPeter Dufault 
738a6472b7SPeter Dufault #if !defined(_KPOSIX_PRIORITY_SCHEDULING)
748a6472b7SPeter Dufault 
75e9189611SPeter Wemm /* Not configured but loadable via a module:
768a6472b7SPeter Dufault  */
778a6472b7SPeter Dufault 
788a6472b7SPeter Dufault static int sched_attach(void)
798a6472b7SPeter Dufault {
808a6472b7SPeter Dufault 	return 0;
818a6472b7SPeter Dufault }
828a6472b7SPeter Dufault 
838a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_setparam)
848a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_getparam)
858a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_setscheduler)
868a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_getscheduler)
878a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_yield)
888a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_get_priority_max)
898a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_get_priority_min)
908a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_rr_get_interval)
918a6472b7SPeter Dufault 
928a6472b7SPeter Dufault #else
938a6472b7SPeter Dufault 
948a6472b7SPeter Dufault /* Configured in kernel version:
958a6472b7SPeter Dufault  */
968a6472b7SPeter Dufault static struct ksched *ksched;
978a6472b7SPeter Dufault 
988a6472b7SPeter Dufault static int sched_attach(void)
998a6472b7SPeter Dufault {
1008a6472b7SPeter Dufault 	int ret = ksched_attach(&ksched);
1018a6472b7SPeter Dufault 
1028a6472b7SPeter Dufault 	if (ret == 0)
1038a6472b7SPeter Dufault 		p31b_setcfg(CTL_P1003_1B_PRIORITY_SCHEDULING, 1);
1048a6472b7SPeter Dufault 
1058a6472b7SPeter Dufault 	return ret;
1068a6472b7SPeter Dufault }
1078a6472b7SPeter Dufault 
1082afac34dSMatthew Dillon /*
1092afac34dSMatthew Dillon  * MPSAFE
1102afac34dSMatthew Dillon  */
111b40ce416SJulian Elischer int sched_setparam(struct thread *td,
1128a6472b7SPeter Dufault 	struct sched_setparam_args *uap)
1138a6472b7SPeter Dufault {
114b40ce416SJulian Elischer 	struct thread *targettd;
1151af55356SRobert Watson 	struct proc *targetp;
1168a6472b7SPeter Dufault 	int e;
117aebde782SPeter Dufault 	struct sched_param sched_param;
1182afac34dSMatthew Dillon 
119e8f7a952SRobert Watson 	e = copyin(uap->param, &sched_param, sizeof(sched_param));
120e8f7a952SRobert Watson 	if (e)
121e8f7a952SRobert Watson 		return (e);
122aebde782SPeter Dufault 
1232afac34dSMatthew Dillon 	mtx_lock(&Giant);
124e84b7987SRobert Watson 	if (uap->pid == 0) {
125b40ce416SJulian Elischer 		targetp = td->td_proc;
126b40ce416SJulian Elischer 		targettd = td;
127e84b7987SRobert Watson 		PROC_LOCK(targetp);
128e84b7987SRobert Watson 	} else {
129e84b7987SRobert Watson 		targetp = pfind(uap->pid);
1302afac34dSMatthew Dillon 		if (targetp == NULL) {
1312afac34dSMatthew Dillon 			e = ESRCH;
1322afac34dSMatthew Dillon 			goto done2;
1332afac34dSMatthew Dillon 		}
134079b7badSJulian Elischer 		targettd = FIRST_THREAD_IN_PROC(targetp); /* XXXKSE */
135e84b7987SRobert Watson 	}
136e84b7987SRobert Watson 
137f44d9e24SJohn Baldwin 	e = p_cansched(td, targetp);
138e84b7987SRobert Watson 	PROC_UNLOCK(targetp);
1392afac34dSMatthew Dillon 	if (e == 0) {
140b40ce416SJulian Elischer 		e = ksched_setparam(&td->td_retval[0], ksched, targettd,
14164e55bf4SRobert Watson 			(const struct sched_param *)&sched_param);
1422afac34dSMatthew Dillon 	}
1432afac34dSMatthew Dillon done2:
1442afac34dSMatthew Dillon 	mtx_unlock(&Giant);
14564e55bf4SRobert Watson 	return (e);
1468a6472b7SPeter Dufault }
1478a6472b7SPeter Dufault 
1482afac34dSMatthew Dillon /*
1492afac34dSMatthew Dillon  * MPSAFE
1502afac34dSMatthew Dillon  */
151b40ce416SJulian Elischer int sched_getparam(struct thread *td,
1528a6472b7SPeter Dufault 	struct sched_getparam_args *uap)
1538a6472b7SPeter Dufault {
1548a6472b7SPeter Dufault 	int e;
155aebde782SPeter Dufault 	struct sched_param sched_param;
156b40ce416SJulian Elischer 	struct thread *targettd;
1571af55356SRobert Watson 	struct proc *targetp;
1588a6472b7SPeter Dufault 
1592afac34dSMatthew Dillon 	mtx_lock(&Giant);
160e84b7987SRobert Watson 	if (uap->pid == 0) {
161b40ce416SJulian Elischer 		targetp = td->td_proc;
162b40ce416SJulian Elischer 		targettd = td;
163e84b7987SRobert Watson 		PROC_LOCK(targetp);
164e84b7987SRobert Watson 	} else {
165e84b7987SRobert Watson 		targetp = pfind(uap->pid);
1662afac34dSMatthew Dillon 		if (targetp == NULL) {
1672afac34dSMatthew Dillon 			e = ESRCH;
1682afac34dSMatthew Dillon 			goto done2;
1692afac34dSMatthew Dillon 		}
170079b7badSJulian Elischer 		targettd = FIRST_THREAD_IN_PROC(targetp); /* XXXKSE */
171e84b7987SRobert Watson 	}
172e84b7987SRobert Watson 
173f44d9e24SJohn Baldwin 	e = p_cansee(td, targetp);
174e84b7987SRobert Watson 	PROC_UNLOCK(targetp);
17564e55bf4SRobert Watson 	if (e)
1762afac34dSMatthew Dillon 		goto done2;
177e84b7987SRobert Watson 
178b40ce416SJulian Elischer 	e = ksched_getparam(&td->td_retval[0], ksched, targettd, &sched_param);
1792afac34dSMatthew Dillon 	if (e == 0)
18064e55bf4SRobert Watson 		e = copyout(&sched_param, uap->param, sizeof(sched_param));
1812afac34dSMatthew Dillon done2:
1822afac34dSMatthew Dillon 	mtx_unlock(&Giant);
18364e55bf4SRobert Watson 	return (e);
1848a6472b7SPeter Dufault }
185b40ce416SJulian Elischer 
1862afac34dSMatthew Dillon /*
1872afac34dSMatthew Dillon  * MPSAFE
1882afac34dSMatthew Dillon  */
189b40ce416SJulian Elischer int sched_setscheduler(struct thread *td,
1908a6472b7SPeter Dufault 	struct sched_setscheduler_args *uap)
1918a6472b7SPeter Dufault {
1928a6472b7SPeter Dufault 	int e;
193aebde782SPeter Dufault 	struct sched_param sched_param;
194b40ce416SJulian Elischer 	struct thread *targettd;
1951af55356SRobert Watson 	struct proc *targetp;
1961af55356SRobert Watson 
197e8f7a952SRobert Watson 	e = copyin(uap->param, &sched_param, sizeof(sched_param));
198e8f7a952SRobert Watson 	if (e)
199e8f7a952SRobert Watson 		return (e);
200aebde782SPeter Dufault 
2012afac34dSMatthew Dillon 	mtx_lock(&Giant);
202e84b7987SRobert Watson 	if (uap->pid == 0) {
203b40ce416SJulian Elischer 		targetp = td->td_proc;
204b40ce416SJulian Elischer 		targettd = td;
205e84b7987SRobert Watson 		PROC_LOCK(targetp);
206e84b7987SRobert Watson 	} else {
207e84b7987SRobert Watson 		targetp = pfind(uap->pid);
2082afac34dSMatthew Dillon 		if (targetp == NULL) {
2092afac34dSMatthew Dillon 			e = ESRCH;
2102afac34dSMatthew Dillon 			goto done2;
2112afac34dSMatthew Dillon 		}
212079b7badSJulian Elischer 		targettd = FIRST_THREAD_IN_PROC(targetp); /* XXXKSE */
213e84b7987SRobert Watson 	}
214e84b7987SRobert Watson 
215f44d9e24SJohn Baldwin 	e = p_cansched(td, targetp);
216e84b7987SRobert Watson 	PROC_UNLOCK(targetp);
2172afac34dSMatthew Dillon 	if (e == 0) {
218b40ce416SJulian Elischer 		e = ksched_setscheduler(&td->td_retval[0], ksched, targettd,
219b40ce416SJulian Elischer 			uap->policy, (const struct sched_param *)&sched_param);
2202afac34dSMatthew Dillon 	}
2212afac34dSMatthew Dillon done2:
2222afac34dSMatthew Dillon 	mtx_unlock(&Giant);
22364e55bf4SRobert Watson 	return (e);
2248a6472b7SPeter Dufault }
225b40ce416SJulian Elischer 
2262afac34dSMatthew Dillon /*
2272afac34dSMatthew Dillon  * MPSAFE
2282afac34dSMatthew Dillon  */
229b40ce416SJulian Elischer int sched_getscheduler(struct thread *td,
2308a6472b7SPeter Dufault 	struct sched_getscheduler_args *uap)
2318a6472b7SPeter Dufault {
2328a6472b7SPeter Dufault 	int e;
233b40ce416SJulian Elischer 	struct thread *targettd;
2341af55356SRobert Watson 	struct proc *targetp;
2358a6472b7SPeter Dufault 
2362afac34dSMatthew Dillon 	mtx_lock(&Giant);
237e84b7987SRobert Watson 	if (uap->pid == 0) {
238b40ce416SJulian Elischer 		targetp = td->td_proc;
239b40ce416SJulian Elischer 		targettd = td;
240e84b7987SRobert Watson 		PROC_LOCK(targetp);
241e84b7987SRobert Watson 	} else {
242e84b7987SRobert Watson 		targetp = pfind(uap->pid);
2432afac34dSMatthew Dillon 		if (targetp == NULL) {
2442afac34dSMatthew Dillon 			e = ESRCH;
2452afac34dSMatthew Dillon 			goto done2;
2462afac34dSMatthew Dillon 		}
247079b7badSJulian Elischer 		targettd = FIRST_THREAD_IN_PROC(targetp); /* XXXKSE */
248e84b7987SRobert Watson 	}
249e84b7987SRobert Watson 
250f44d9e24SJohn Baldwin 	e = p_cansee(td, targetp);
251e84b7987SRobert Watson 	PROC_UNLOCK(targetp);
2522afac34dSMatthew Dillon 	if (e == 0)
253b40ce416SJulian Elischer 		e = ksched_getscheduler(&td->td_retval[0], ksched, targettd);
25464e55bf4SRobert Watson 
2552afac34dSMatthew Dillon done2:
2562afac34dSMatthew Dillon 	mtx_unlock(&Giant);
25764e55bf4SRobert Watson 	return (e);
2588a6472b7SPeter Dufault }
259b40ce416SJulian Elischer 
2602afac34dSMatthew Dillon /*
2612afac34dSMatthew Dillon  * MPSAFE
2622afac34dSMatthew Dillon  */
263b40ce416SJulian Elischer int sched_yield(struct thread *td,
2648a6472b7SPeter Dufault 	struct sched_yield_args *uap)
2658a6472b7SPeter Dufault {
2662afac34dSMatthew Dillon 	int error;
2672afac34dSMatthew Dillon 
2682afac34dSMatthew Dillon 	mtx_lock(&Giant);
269b40ce416SJulian Elischer 	error = ksched_yield(&td->td_retval[0], ksched);
2702afac34dSMatthew Dillon 	mtx_unlock(&Giant);
2712afac34dSMatthew Dillon 	return (error);
2728a6472b7SPeter Dufault }
273b40ce416SJulian Elischer 
2742afac34dSMatthew Dillon /*
2752afac34dSMatthew Dillon  * MPSAFE
2762afac34dSMatthew Dillon  */
277b40ce416SJulian Elischer int sched_get_priority_max(struct thread *td,
2788a6472b7SPeter Dufault 	struct sched_get_priority_max_args *uap)
2798a6472b7SPeter Dufault {
2802afac34dSMatthew Dillon 	int error;
2812afac34dSMatthew Dillon 
2822afac34dSMatthew Dillon 	mtx_lock(&Giant);
283b40ce416SJulian Elischer 	error = ksched_get_priority_max(&td->td_retval[0], ksched, uap->policy);
2842afac34dSMatthew Dillon 	mtx_unlock(&Giant);
2852afac34dSMatthew Dillon 	return (error);
2868a6472b7SPeter Dufault }
287b40ce416SJulian Elischer 
2882afac34dSMatthew Dillon /*
2892afac34dSMatthew Dillon  * MPSAFE
2902afac34dSMatthew Dillon  */
291b40ce416SJulian Elischer int sched_get_priority_min(struct thread *td,
2928a6472b7SPeter Dufault 	struct sched_get_priority_min_args *uap)
2938a6472b7SPeter Dufault {
2942afac34dSMatthew Dillon 	int error;
295b40ce416SJulian Elischer 
2962afac34dSMatthew Dillon 	mtx_lock(&Giant);
297b40ce416SJulian Elischer 	error = ksched_get_priority_min(&td->td_retval[0], ksched, uap->policy);
2982afac34dSMatthew Dillon 	mtx_unlock(&Giant);
2992afac34dSMatthew Dillon 	return (error);
3008a6472b7SPeter Dufault }
301b40ce416SJulian Elischer 
3022afac34dSMatthew Dillon /*
3032afac34dSMatthew Dillon  * MPSAFE
3042afac34dSMatthew Dillon  */
305b40ce416SJulian Elischer int sched_rr_get_interval(struct thread *td,
3068a6472b7SPeter Dufault 	struct sched_rr_get_interval_args *uap)
3078a6472b7SPeter Dufault {
3088a6472b7SPeter Dufault 	int e;
309b40ce416SJulian Elischer 	struct thread *targettd;
310a11acc6fSAlfred Perlstein 	struct timespec timespec;
3111af55356SRobert Watson 	struct proc *targetp;
3128a6472b7SPeter Dufault 
3132afac34dSMatthew Dillon 	mtx_lock(&Giant);
314e84b7987SRobert Watson 	if (uap->pid == 0) {
315b40ce416SJulian Elischer 		targettd = td;
316b40ce416SJulian Elischer 		targetp = td->td_proc;
317e84b7987SRobert Watson 		PROC_LOCK(targetp);
318e84b7987SRobert Watson 	} else {
319e84b7987SRobert Watson 		targetp = pfind(uap->pid);
3202afac34dSMatthew Dillon 		if (targetp == NULL) {
3212afac34dSMatthew Dillon 			e = ESRCH;
3222afac34dSMatthew Dillon 			goto done2;
3232afac34dSMatthew Dillon 		}
324079b7badSJulian Elischer 		targettd = FIRST_THREAD_IN_PROC(targetp); /* XXXKSE */
325e84b7987SRobert Watson 	}
326e84b7987SRobert Watson 
327f44d9e24SJohn Baldwin 	e = p_cansee(td, targetp);
328e84b7987SRobert Watson 	PROC_UNLOCK(targetp);
3292afac34dSMatthew Dillon 	if (e == 0) {
330b40ce416SJulian Elischer 		e = ksched_rr_get_interval(&td->td_retval[0], ksched, targettd,
331a11acc6fSAlfred Perlstein 			&timespec);
332a11acc6fSAlfred Perlstein 		if (e == 0)
333a11acc6fSAlfred Perlstein 			e = copyout(&timespec, uap->interval,
334a11acc6fSAlfred Perlstein 			    sizeof(timespec));
3352afac34dSMatthew Dillon 	}
3362afac34dSMatthew Dillon done2:
3372afac34dSMatthew Dillon 	mtx_unlock(&Giant);
33864e55bf4SRobert Watson 	return (e);
3398a6472b7SPeter Dufault }
3408a6472b7SPeter Dufault 
3418a6472b7SPeter Dufault #endif
3428a6472b7SPeter Dufault 
3438a6472b7SPeter Dufault static void p31binit(void *notused)
3448a6472b7SPeter Dufault {
3458a6472b7SPeter Dufault 	(void) sched_attach();
346ce47711dSPeter Dufault 	p31b_setcfg(CTL_P1003_1B_PAGESIZE, PAGE_SIZE);
3478a6472b7SPeter Dufault }
3488a6472b7SPeter Dufault 
3498a6472b7SPeter Dufault SYSINIT(p31b, SI_SUB_P1003_1B, SI_ORDER_FIRST, p31binit, NULL);
350