xref: /freebsd/sys/kern/p1003_1b.c (revision e91896117bba50d067048e99659fd015b35322e9)
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 
348a6472b7SPeter Dufault /* p1003_1b: Real Time common code.
358a6472b7SPeter Dufault  */
368a6472b7SPeter Dufault 
378a6472b7SPeter Dufault #include <sys/param.h>
388a6472b7SPeter Dufault #include <sys/systm.h>
398a6472b7SPeter Dufault #include <sys/kernel.h>
408a6472b7SPeter Dufault #include <sys/sysent.h>
418a6472b7SPeter Dufault #include <sys/proc.h>
428a6472b7SPeter Dufault #include <sys/syslog.h>
438a6472b7SPeter Dufault #include <sys/module.h>
448a6472b7SPeter Dufault #include <sys/sysproto.h>
458a6472b7SPeter Dufault #include <sys/sysctl.h>
468a6472b7SPeter Dufault 
478a6472b7SPeter Dufault #include <posix4/posix4.h>
488a6472b7SPeter Dufault 
498a6472b7SPeter Dufault MALLOC_DEFINE(M_P31B, "p1003.1b", "Posix 1003.1B");
508a6472b7SPeter Dufault 
518a6472b7SPeter Dufault /* p31b_proc: Return a proc struct corresponding to a pid to operate on.
528a6472b7SPeter Dufault  *
538a6472b7SPeter Dufault  * Enforce permission policy.
548a6472b7SPeter Dufault  *
558a6472b7SPeter Dufault  * The policy is the same as for sending signals except there
568a6472b7SPeter Dufault  * is no notion of process groups.
578a6472b7SPeter Dufault  *
588a6472b7SPeter Dufault  * pid == 0 means my process.
598a6472b7SPeter Dufault  *
608a6472b7SPeter Dufault  * This is disabled until I've got a permission gate in again:
618a6472b7SPeter Dufault  * only root can do this.
628a6472b7SPeter Dufault  */
638a6472b7SPeter Dufault 
648a6472b7SPeter Dufault #if 0
658a6472b7SPeter Dufault /*
668a6472b7SPeter Dufault  * This is stolen from CANSIGNAL in kern_sig:
678a6472b7SPeter Dufault  *
688a6472b7SPeter Dufault  * Can process p, with pcred pc, do "write flavor" operations to process q?
698a6472b7SPeter Dufault  */
708a6472b7SPeter Dufault #define CAN_AFFECT(p, pc, q) \
718a6472b7SPeter Dufault 	((pc)->pc_ucred->cr_uid == 0 || \
728a6472b7SPeter Dufault 	    (pc)->p_ruid == (q)->p_cred->p_ruid || \
738a6472b7SPeter Dufault 	    (pc)->pc_ucred->cr_uid == (q)->p_cred->p_ruid || \
748a6472b7SPeter Dufault 	    (pc)->p_ruid == (q)->p_ucred->cr_uid || \
758a6472b7SPeter Dufault 	    (pc)->pc_ucred->cr_uid == (q)->p_ucred->cr_uid)
768a6472b7SPeter Dufault #else
778a6472b7SPeter Dufault #define CAN_AFFECT(p, pc, q) ((pc)->pc_ucred->cr_uid == 0)
788a6472b7SPeter Dufault #endif
798a6472b7SPeter Dufault 
808a6472b7SPeter Dufault /*
818a6472b7SPeter Dufault  * p31b_proc: Look up a proc from a PID.  If proc is 0 it is
828a6472b7SPeter Dufault  * my own proc.
838a6472b7SPeter Dufault  */
848a6472b7SPeter Dufault int p31b_proc(struct proc *p, pid_t pid, struct proc **pp)
858a6472b7SPeter Dufault {
868a6472b7SPeter Dufault 	int ret = 0;
878a6472b7SPeter Dufault 	struct proc *other_proc = 0;
888a6472b7SPeter Dufault 
898a6472b7SPeter Dufault 	if (pid == 0)
908a6472b7SPeter Dufault 		other_proc = p;
918a6472b7SPeter Dufault 	else
928a6472b7SPeter Dufault 		other_proc = pfind(pid);
938a6472b7SPeter Dufault 
948a6472b7SPeter Dufault 	if (other_proc)
958a6472b7SPeter Dufault 	{
968a6472b7SPeter Dufault 		/* Enforce permission policy.
978a6472b7SPeter Dufault 		 */
988a6472b7SPeter Dufault 		if (CAN_AFFECT(p, p->p_cred, other_proc))
998a6472b7SPeter Dufault 			*pp = other_proc;
1008a6472b7SPeter Dufault 		else
1018a6472b7SPeter Dufault 			ret = EPERM;
1028a6472b7SPeter Dufault 	}
1038a6472b7SPeter Dufault 	else
1048a6472b7SPeter Dufault 		ret = ESRCH;
1058a6472b7SPeter Dufault 
1068a6472b7SPeter Dufault 	return ret;
1078a6472b7SPeter Dufault }
1088a6472b7SPeter Dufault 
1092a61a110SPeter Dufault /* The system calls return ENOSYS if an entry is called that is
1102a61a110SPeter Dufault  * not run-time supported.  I am also logging since some programs
1112a61a110SPeter Dufault  * start to use this when they shouldn't.  That will be removed if annoying.
1122a61a110SPeter Dufault  */
1138a6472b7SPeter Dufault int
1148a6472b7SPeter Dufault syscall_not_present(struct proc *p, const char *s, struct nosys_args *uap)
1158a6472b7SPeter Dufault {
1168a6472b7SPeter Dufault 	log(LOG_ERR, "cmd %s pid %d tried to use non-present %s\n",
1178a6472b7SPeter Dufault 			p->p_comm, p->p_pid, s);
1182a61a110SPeter Dufault 
1192a61a110SPeter Dufault 	/* a " return nosys(p, uap); " here causes a core dump.
1202a61a110SPeter Dufault 	 */
1212a61a110SPeter Dufault 
1222a61a110SPeter Dufault 	return ENOSYS;
1238a6472b7SPeter Dufault }
1248a6472b7SPeter Dufault 
1258a6472b7SPeter Dufault #if !defined(_KPOSIX_PRIORITY_SCHEDULING)
1268a6472b7SPeter Dufault 
127e9189611SPeter Wemm /* Not configured but loadable via a module:
1288a6472b7SPeter Dufault  */
1298a6472b7SPeter Dufault 
1308a6472b7SPeter Dufault static int sched_attach(void)
1318a6472b7SPeter Dufault {
1328a6472b7SPeter Dufault 	return 0;
1338a6472b7SPeter Dufault }
1348a6472b7SPeter Dufault 
1358a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_setparam)
1368a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_getparam)
1378a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_setscheduler)
1388a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_getscheduler)
1398a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_yield)
1408a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_get_priority_max)
1418a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_get_priority_min)
1428a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_rr_get_interval)
1438a6472b7SPeter Dufault 
1448a6472b7SPeter Dufault #else
1458a6472b7SPeter Dufault 
1468a6472b7SPeter Dufault /* Configured in kernel version:
1478a6472b7SPeter Dufault  */
1488a6472b7SPeter Dufault static struct ksched *ksched;
1498a6472b7SPeter Dufault 
1508a6472b7SPeter Dufault static int sched_attach(void)
1518a6472b7SPeter Dufault {
1528a6472b7SPeter Dufault 	int ret = ksched_attach(&ksched);
1538a6472b7SPeter Dufault 
1548a6472b7SPeter Dufault 	if (ret == 0)
1558a6472b7SPeter Dufault 		p31b_setcfg(CTL_P1003_1B_PRIORITY_SCHEDULING, 1);
1568a6472b7SPeter Dufault 
1578a6472b7SPeter Dufault 	return ret;
1588a6472b7SPeter Dufault }
1598a6472b7SPeter Dufault 
1608a6472b7SPeter Dufault int sched_setparam(struct proc *p,
1618a6472b7SPeter Dufault 	struct sched_setparam_args *uap)
1628a6472b7SPeter Dufault {
1638a6472b7SPeter Dufault 	int e;
1648a6472b7SPeter Dufault 
165aebde782SPeter Dufault 	struct sched_param sched_param;
166aebde782SPeter Dufault 	copyin(uap->param, &sched_param, sizeof(sched_param));
167aebde782SPeter Dufault 
1688a6472b7SPeter Dufault 	(void) (0
1698a6472b7SPeter Dufault 	|| (e = p31b_proc(p, uap->pid, &p))
1708a6472b7SPeter Dufault 	|| (e = ksched_setparam(&p->p_retval[0], ksched, p,
171aebde782SPeter Dufault 		(const struct sched_param *)&sched_param))
1728a6472b7SPeter Dufault 	);
1738a6472b7SPeter Dufault 
1748a6472b7SPeter Dufault 	return e;
1758a6472b7SPeter Dufault }
1768a6472b7SPeter Dufault 
1778a6472b7SPeter Dufault int sched_getparam(struct proc *p,
1788a6472b7SPeter Dufault 	struct sched_getparam_args *uap)
1798a6472b7SPeter Dufault {
1808a6472b7SPeter Dufault 	int e;
181aebde782SPeter Dufault 	struct sched_param sched_param;
1828a6472b7SPeter Dufault 
1838a6472b7SPeter Dufault 	(void) (0
1848a6472b7SPeter Dufault 	|| (e = p31b_proc(p, uap->pid, &p))
185aebde782SPeter Dufault 	|| (e = ksched_getparam(&p->p_retval[0], ksched, p, &sched_param))
1868a6472b7SPeter Dufault 	);
1878a6472b7SPeter Dufault 
188aebde782SPeter Dufault 	if (!e)
189aebde782SPeter Dufault 		copyout(&sched_param, uap->param, sizeof(sched_param));
190aebde782SPeter Dufault 
1918a6472b7SPeter Dufault 	return e;
1928a6472b7SPeter Dufault }
1938a6472b7SPeter Dufault int sched_setscheduler(struct proc *p,
1948a6472b7SPeter Dufault 	struct sched_setscheduler_args *uap)
1958a6472b7SPeter Dufault {
1968a6472b7SPeter Dufault 	int e;
197aebde782SPeter Dufault 
198aebde782SPeter Dufault 	struct sched_param sched_param;
199aebde782SPeter Dufault 	copyin(uap->param, &sched_param, sizeof(sched_param));
200aebde782SPeter Dufault 
2018a6472b7SPeter Dufault 	(void) (0
2028a6472b7SPeter Dufault 	|| (e = p31b_proc(p, uap->pid, &p))
2038a6472b7SPeter Dufault 	|| (e = ksched_setscheduler(&p->p_retval[0],
204aebde782SPeter Dufault 	ksched, p, uap->policy,
205aebde782SPeter Dufault 		(const struct sched_param *)&sched_param))
2068a6472b7SPeter Dufault 	);
2078a6472b7SPeter Dufault 
2088a6472b7SPeter Dufault 	return e;
2098a6472b7SPeter Dufault }
2108a6472b7SPeter Dufault int sched_getscheduler(struct proc *p,
2118a6472b7SPeter Dufault 	struct sched_getscheduler_args *uap)
2128a6472b7SPeter Dufault {
2138a6472b7SPeter Dufault 	int e;
2148a6472b7SPeter Dufault 	(void) (0
2158a6472b7SPeter Dufault 	|| (e = p31b_proc(p, uap->pid, &p))
2168a6472b7SPeter Dufault 	|| (e = ksched_getscheduler(&p->p_retval[0], ksched, p))
2178a6472b7SPeter Dufault 	);
2188a6472b7SPeter Dufault 
2198a6472b7SPeter Dufault 	return e;
2208a6472b7SPeter Dufault }
2218a6472b7SPeter Dufault int sched_yield(struct proc *p,
2228a6472b7SPeter Dufault 	struct sched_yield_args *uap)
2238a6472b7SPeter Dufault {
2248a6472b7SPeter Dufault 	return ksched_yield(&p->p_retval[0], ksched);
2258a6472b7SPeter Dufault }
2268a6472b7SPeter Dufault int sched_get_priority_max(struct proc *p,
2278a6472b7SPeter Dufault 	struct sched_get_priority_max_args *uap)
2288a6472b7SPeter Dufault {
2298a6472b7SPeter Dufault 	return ksched_get_priority_max(&p->p_retval[0],
2308a6472b7SPeter Dufault 	ksched, uap->policy);
2318a6472b7SPeter Dufault }
2328a6472b7SPeter Dufault int sched_get_priority_min(struct proc *p,
2338a6472b7SPeter Dufault 	struct sched_get_priority_min_args *uap)
2348a6472b7SPeter Dufault {
2358a6472b7SPeter Dufault 	return ksched_get_priority_min(&p->p_retval[0],
2368a6472b7SPeter Dufault 	ksched, uap->policy);
2378a6472b7SPeter Dufault }
2388a6472b7SPeter Dufault int sched_rr_get_interval(struct proc *p,
2398a6472b7SPeter Dufault 	struct sched_rr_get_interval_args *uap)
2408a6472b7SPeter Dufault {
2418a6472b7SPeter Dufault 	int e;
2428a6472b7SPeter Dufault 
2438a6472b7SPeter Dufault 	(void) (0
2448a6472b7SPeter Dufault 	|| (e = p31b_proc(p, uap->pid, &p))
2458a6472b7SPeter Dufault 	|| (e = ksched_rr_get_interval(&p->p_retval[0], ksched,
2468a6472b7SPeter Dufault 	p, uap->interval))
2478a6472b7SPeter Dufault 	);
2488a6472b7SPeter Dufault 
2498a6472b7SPeter Dufault 	return e;
2508a6472b7SPeter Dufault }
2518a6472b7SPeter Dufault 
2528a6472b7SPeter Dufault #endif
2538a6472b7SPeter Dufault 
2548a6472b7SPeter Dufault static void p31binit(void *notused)
2558a6472b7SPeter Dufault {
2568a6472b7SPeter Dufault 	(void) sched_attach();
257ce47711dSPeter Dufault 	p31b_setcfg(CTL_P1003_1B_PAGESIZE, PAGE_SIZE);
2588a6472b7SPeter Dufault }
2598a6472b7SPeter Dufault 
2608a6472b7SPeter Dufault SYSINIT(p31b, SI_SUB_P1003_1B, SI_ORDER_FIRST, p31binit, NULL);
261