xref: /freebsd/sys/kern/p1003_1b.c (revision 2afac34da38d3fd02ff681a0505793003f91aebe)
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  *
32365c5db0SPeter Wemm  * $FreeBSD$
338a6472b7SPeter Dufault  */
348a6472b7SPeter Dufault 
358a6472b7SPeter Dufault /* p1003_1b: Real Time common code.
368a6472b7SPeter Dufault  */
378a6472b7SPeter Dufault 
388a6472b7SPeter Dufault #include <sys/param.h>
398a6472b7SPeter Dufault #include <sys/systm.h>
408a6472b7SPeter Dufault #include <sys/kernel.h>
41fb919e4dSMark Murray #include <sys/lock.h>
428a6472b7SPeter Dufault #include <sys/module.h>
43fb919e4dSMark Murray #include <sys/mutex.h>
44fb919e4dSMark Murray #include <sys/proc.h>
458a6472b7SPeter Dufault #include <sys/sysctl.h>
46fb919e4dSMark Murray #include <sys/sysent.h>
47fb919e4dSMark Murray #include <sys/syslog.h>
48fb919e4dSMark Murray #include <sys/sysproto.h>
498a6472b7SPeter Dufault 
508a6472b7SPeter Dufault #include <posix4/posix4.h>
518a6472b7SPeter Dufault 
528a6472b7SPeter Dufault MALLOC_DEFINE(M_P31B, "p1003.1b", "Posix 1003.1B");
538a6472b7SPeter Dufault 
542a61a110SPeter Dufault /* The system calls return ENOSYS if an entry is called that is
552a61a110SPeter Dufault  * not run-time supported.  I am also logging since some programs
562a61a110SPeter Dufault  * start to use this when they shouldn't.  That will be removed if annoying.
572a61a110SPeter Dufault  */
588a6472b7SPeter Dufault int
598a6472b7SPeter Dufault syscall_not_present(struct proc *p, const char *s, struct nosys_args *uap)
608a6472b7SPeter Dufault {
618a6472b7SPeter Dufault 	log(LOG_ERR, "cmd %s pid %d tried to use non-present %s\n",
628a6472b7SPeter Dufault 			p->p_comm, p->p_pid, s);
632a61a110SPeter Dufault 
642a61a110SPeter Dufault 	/* a " return nosys(p, uap); " here causes a core dump.
652a61a110SPeter Dufault 	 */
662a61a110SPeter Dufault 
672a61a110SPeter Dufault 	return ENOSYS;
688a6472b7SPeter Dufault }
698a6472b7SPeter Dufault 
708a6472b7SPeter Dufault #if !defined(_KPOSIX_PRIORITY_SCHEDULING)
718a6472b7SPeter Dufault 
72e9189611SPeter Wemm /* Not configured but loadable via a module:
738a6472b7SPeter Dufault  */
748a6472b7SPeter Dufault 
758a6472b7SPeter Dufault static int sched_attach(void)
768a6472b7SPeter Dufault {
778a6472b7SPeter Dufault 	return 0;
788a6472b7SPeter Dufault }
798a6472b7SPeter Dufault 
808a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_setparam)
818a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_getparam)
828a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_setscheduler)
838a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_getscheduler)
848a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_yield)
858a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_get_priority_max)
868a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_get_priority_min)
878a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_rr_get_interval)
888a6472b7SPeter Dufault 
898a6472b7SPeter Dufault #else
908a6472b7SPeter Dufault 
918a6472b7SPeter Dufault /* Configured in kernel version:
928a6472b7SPeter Dufault  */
938a6472b7SPeter Dufault static struct ksched *ksched;
948a6472b7SPeter Dufault 
958a6472b7SPeter Dufault static int sched_attach(void)
968a6472b7SPeter Dufault {
978a6472b7SPeter Dufault 	int ret = ksched_attach(&ksched);
988a6472b7SPeter Dufault 
998a6472b7SPeter Dufault 	if (ret == 0)
1008a6472b7SPeter Dufault 		p31b_setcfg(CTL_P1003_1B_PRIORITY_SCHEDULING, 1);
1018a6472b7SPeter Dufault 
1028a6472b7SPeter Dufault 	return ret;
1038a6472b7SPeter Dufault }
1048a6472b7SPeter Dufault 
1052afac34dSMatthew Dillon /*
1062afac34dSMatthew Dillon  * MPSAFE
1072afac34dSMatthew Dillon  */
1088a6472b7SPeter Dufault int sched_setparam(struct proc *p,
1098a6472b7SPeter Dufault 	struct sched_setparam_args *uap)
1108a6472b7SPeter Dufault {
1111af55356SRobert Watson 	struct proc *targetp;
1128a6472b7SPeter Dufault 	int e;
113aebde782SPeter Dufault 	struct sched_param sched_param;
1142afac34dSMatthew Dillon 
115e8f7a952SRobert Watson 	e = copyin(uap->param, &sched_param, sizeof(sched_param));
116e8f7a952SRobert Watson 	if (e)
117e8f7a952SRobert Watson 		return (e);
118aebde782SPeter Dufault 
1192afac34dSMatthew Dillon 	mtx_lock(&Giant);
120e84b7987SRobert Watson 	if (uap->pid == 0) {
121e84b7987SRobert Watson 		targetp = p;
122e84b7987SRobert Watson 		PROC_LOCK(targetp);
123e84b7987SRobert Watson 	} else {
124e84b7987SRobert Watson 		targetp = pfind(uap->pid);
1252afac34dSMatthew Dillon 		if (targetp == NULL) {
1262afac34dSMatthew Dillon 			e = ESRCH;
1272afac34dSMatthew Dillon 			goto done2;
1282afac34dSMatthew Dillon 		}
129e84b7987SRobert Watson 	}
130e84b7987SRobert Watson 
131a0f75161SRobert Watson 	e = p_cansched(p, targetp);
132e84b7987SRobert Watson 	PROC_UNLOCK(targetp);
1332afac34dSMatthew Dillon 	if (e == 0) {
1341af55356SRobert Watson 		e = ksched_setparam(&p->p_retval[0], ksched, targetp,
13564e55bf4SRobert Watson 			(const struct sched_param *)&sched_param);
1362afac34dSMatthew Dillon 	}
1372afac34dSMatthew Dillon done2:
1382afac34dSMatthew Dillon 	mtx_unlock(&Giant);
13964e55bf4SRobert Watson 	return (e);
1408a6472b7SPeter Dufault }
1418a6472b7SPeter Dufault 
1422afac34dSMatthew Dillon /*
1432afac34dSMatthew Dillon  * MPSAFE
1442afac34dSMatthew Dillon  */
1458a6472b7SPeter Dufault int sched_getparam(struct proc *p,
1468a6472b7SPeter Dufault 	struct sched_getparam_args *uap)
1478a6472b7SPeter Dufault {
1488a6472b7SPeter Dufault 	int e;
149aebde782SPeter Dufault 	struct sched_param sched_param;
1501af55356SRobert Watson 	struct proc *targetp;
1518a6472b7SPeter Dufault 
1522afac34dSMatthew Dillon 	mtx_lock(&Giant);
153e84b7987SRobert Watson 	if (uap->pid == 0) {
154e84b7987SRobert Watson 		targetp = p;
155e84b7987SRobert Watson 		PROC_LOCK(targetp);
156e84b7987SRobert Watson 	} else {
157e84b7987SRobert Watson 		targetp = pfind(uap->pid);
1582afac34dSMatthew Dillon 		if (targetp == NULL) {
1592afac34dSMatthew Dillon 			e = ESRCH;
1602afac34dSMatthew Dillon 			goto done2;
1612afac34dSMatthew Dillon 		}
162e84b7987SRobert Watson 	}
163e84b7987SRobert Watson 
164a0f75161SRobert Watson 	e = p_cansee(p, targetp);
165e84b7987SRobert Watson 	PROC_UNLOCK(targetp);
16664e55bf4SRobert Watson 	if (e)
1672afac34dSMatthew Dillon 		goto done2;
168e84b7987SRobert Watson 
1691af55356SRobert Watson 	e = ksched_getparam(&p->p_retval[0], ksched, targetp, &sched_param);
1702afac34dSMatthew Dillon 	if (e == 0)
17164e55bf4SRobert Watson 		e = copyout(&sched_param, uap->param, sizeof(sched_param));
1722afac34dSMatthew Dillon done2:
1732afac34dSMatthew Dillon 	mtx_unlock(&Giant);
17464e55bf4SRobert Watson 	return (e);
1758a6472b7SPeter Dufault }
1762afac34dSMatthew Dillon /*
1772afac34dSMatthew Dillon  * MPSAFE
1782afac34dSMatthew Dillon  */
1798a6472b7SPeter Dufault int sched_setscheduler(struct proc *p,
1808a6472b7SPeter Dufault 	struct sched_setscheduler_args *uap)
1818a6472b7SPeter Dufault {
1828a6472b7SPeter Dufault 	int e;
183aebde782SPeter Dufault 	struct sched_param sched_param;
1841af55356SRobert Watson 	struct proc *targetp;
1851af55356SRobert Watson 
186e8f7a952SRobert Watson 	e = copyin(uap->param, &sched_param, sizeof(sched_param));
187e8f7a952SRobert Watson 	if (e)
188e8f7a952SRobert Watson 		return (e);
189aebde782SPeter Dufault 
1902afac34dSMatthew Dillon 	mtx_lock(&Giant);
191e84b7987SRobert Watson 	if (uap->pid == 0) {
192e84b7987SRobert Watson 		targetp = p;
193e84b7987SRobert Watson 		PROC_LOCK(targetp);
194e84b7987SRobert Watson 	} else {
195e84b7987SRobert Watson 		targetp = pfind(uap->pid);
1962afac34dSMatthew Dillon 		if (targetp == NULL) {
1972afac34dSMatthew Dillon 			e = ESRCH;
1982afac34dSMatthew Dillon 			goto done2;
1992afac34dSMatthew Dillon 		}
200e84b7987SRobert Watson 	}
201e84b7987SRobert Watson 
202a0f75161SRobert Watson 	e = p_cansched(p, targetp);
203e84b7987SRobert Watson 	PROC_UNLOCK(targetp);
2042afac34dSMatthew Dillon 	if (e == 0) {
2052afac34dSMatthew Dillon 		e = ksched_setscheduler(&p->p_retval[0], ksched,
2062afac34dSMatthew Dillon 			targetp, uap->policy,
20764e55bf4SRobert Watson 			(const struct sched_param *)&sched_param);
2082afac34dSMatthew Dillon 	}
2092afac34dSMatthew Dillon done2:
2102afac34dSMatthew Dillon 	mtx_unlock(&Giant);
21164e55bf4SRobert Watson 	return (e);
2128a6472b7SPeter Dufault }
2132afac34dSMatthew Dillon /*
2142afac34dSMatthew Dillon  * MPSAFE
2152afac34dSMatthew Dillon  */
2168a6472b7SPeter Dufault int sched_getscheduler(struct proc *p,
2178a6472b7SPeter Dufault 	struct sched_getscheduler_args *uap)
2188a6472b7SPeter Dufault {
2198a6472b7SPeter Dufault 	int e;
2201af55356SRobert Watson 	struct proc *targetp;
2218a6472b7SPeter Dufault 
2222afac34dSMatthew Dillon 	mtx_lock(&Giant);
223e84b7987SRobert Watson 	if (uap->pid == 0) {
224e84b7987SRobert Watson 		targetp = p;
225e84b7987SRobert Watson 		PROC_LOCK(targetp);
226e84b7987SRobert Watson 	} else {
227e84b7987SRobert Watson 		targetp = pfind(uap->pid);
2282afac34dSMatthew Dillon 		if (targetp == NULL) {
2292afac34dSMatthew Dillon 			e = ESRCH;
2302afac34dSMatthew Dillon 			goto done2;
2312afac34dSMatthew Dillon 		}
232e84b7987SRobert Watson 	}
233e84b7987SRobert Watson 
234a0f75161SRobert Watson 	e = p_cansee(p, targetp);
235e84b7987SRobert Watson 	PROC_UNLOCK(targetp);
2362afac34dSMatthew Dillon 	if (e == 0)
2371af55356SRobert Watson 		e = ksched_getscheduler(&p->p_retval[0], ksched, targetp);
23864e55bf4SRobert Watson 
2392afac34dSMatthew Dillon done2:
2402afac34dSMatthew Dillon 	mtx_unlock(&Giant);
24164e55bf4SRobert Watson 	return (e);
2428a6472b7SPeter Dufault }
2432afac34dSMatthew Dillon /*
2442afac34dSMatthew Dillon  * MPSAFE
2452afac34dSMatthew Dillon  */
2468a6472b7SPeter Dufault int sched_yield(struct proc *p,
2478a6472b7SPeter Dufault 	struct sched_yield_args *uap)
2488a6472b7SPeter Dufault {
2492afac34dSMatthew Dillon 	int error;
2502afac34dSMatthew Dillon 
2512afac34dSMatthew Dillon 	mtx_lock(&Giant);
2522afac34dSMatthew Dillon 	error = ksched_yield(&p->p_retval[0], ksched);
2532afac34dSMatthew Dillon 	mtx_unlock(&Giant);
2542afac34dSMatthew Dillon 	return (error);
2558a6472b7SPeter Dufault }
2562afac34dSMatthew Dillon /*
2572afac34dSMatthew Dillon  * MPSAFE
2582afac34dSMatthew Dillon  */
2598a6472b7SPeter Dufault int sched_get_priority_max(struct proc *p,
2608a6472b7SPeter Dufault 	struct sched_get_priority_max_args *uap)
2618a6472b7SPeter Dufault {
2622afac34dSMatthew Dillon 	int error;
2632afac34dSMatthew Dillon 
2642afac34dSMatthew Dillon 	mtx_lock(&Giant);
2652afac34dSMatthew Dillon 	error = ksched_get_priority_max(&p->p_retval[0], ksched, uap->policy);
2662afac34dSMatthew Dillon 	mtx_unlock(&Giant);
2672afac34dSMatthew Dillon 	return (error);
2688a6472b7SPeter Dufault }
2692afac34dSMatthew Dillon /*
2702afac34dSMatthew Dillon  * MPSAFE
2712afac34dSMatthew Dillon  */
2728a6472b7SPeter Dufault int sched_get_priority_min(struct proc *p,
2738a6472b7SPeter Dufault 	struct sched_get_priority_min_args *uap)
2748a6472b7SPeter Dufault {
2752afac34dSMatthew Dillon 	int error;
2762afac34dSMatthew Dillon 	mtx_lock(&Giant);
2772afac34dSMatthew Dillon 	error = ksched_get_priority_min(&p->p_retval[0], ksched, uap->policy);
2782afac34dSMatthew Dillon 	mtx_unlock(&Giant);
2792afac34dSMatthew Dillon 	return (error);
2808a6472b7SPeter Dufault }
2812afac34dSMatthew Dillon /*
2822afac34dSMatthew Dillon  * MPSAFE
2832afac34dSMatthew Dillon  */
2848a6472b7SPeter Dufault int sched_rr_get_interval(struct proc *p,
2858a6472b7SPeter Dufault 	struct sched_rr_get_interval_args *uap)
2868a6472b7SPeter Dufault {
2878a6472b7SPeter Dufault 	int e;
2881af55356SRobert Watson 	struct proc *targetp;
2898a6472b7SPeter Dufault 
2902afac34dSMatthew Dillon 	mtx_lock(&Giant);
291e84b7987SRobert Watson 	if (uap->pid == 0) {
292e84b7987SRobert Watson 		targetp = p;
293e84b7987SRobert Watson 		PROC_LOCK(targetp);
294e84b7987SRobert Watson 	} else {
295e84b7987SRobert Watson 		targetp = pfind(uap->pid);
2962afac34dSMatthew Dillon 		if (targetp == NULL) {
2972afac34dSMatthew Dillon 			e = ESRCH;
2982afac34dSMatthew Dillon 			goto done2;
2992afac34dSMatthew Dillon 		}
300e84b7987SRobert Watson 	}
301e84b7987SRobert Watson 
302a0f75161SRobert Watson 	e = p_cansee(p, targetp);
303e84b7987SRobert Watson 	PROC_UNLOCK(targetp);
3042afac34dSMatthew Dillon 	if (e == 0) {
3051af55356SRobert Watson 		e = ksched_rr_get_interval(&p->p_retval[0], ksched, targetp,
3061af55356SRobert Watson 			uap->interval);
3072afac34dSMatthew Dillon 	}
3082afac34dSMatthew Dillon done2:
3092afac34dSMatthew Dillon 	mtx_unlock(&Giant);
31064e55bf4SRobert Watson 	return (e);
3118a6472b7SPeter Dufault }
3128a6472b7SPeter Dufault 
3138a6472b7SPeter Dufault #endif
3148a6472b7SPeter Dufault 
3158a6472b7SPeter Dufault static void p31binit(void *notused)
3168a6472b7SPeter Dufault {
3178a6472b7SPeter Dufault 	(void) sched_attach();
318ce47711dSPeter Dufault 	p31b_setcfg(CTL_P1003_1B_PAGESIZE, PAGE_SIZE);
3198a6472b7SPeter Dufault }
3208a6472b7SPeter Dufault 
3218a6472b7SPeter Dufault SYSINIT(p31b, SI_SUB_P1003_1B, SI_ORDER_FIRST, p31binit, NULL);
322