p1003_1b.c revision 76316
121308Sache/* 221308Sache * Copyright (c) 1996, 1997, 1998 321308Sache * HD Associates, Inc. All rights reserved. 421308Sache * 521308Sache * Redistribution and use in source and binary forms, with or without 621308Sache * modification, are permitted provided that the following conditions 7157184Sache * are met: 821308Sache * 1. Redistributions of source code must retain the above copyright 921308Sache * notice, this list of conditions and the following disclaimer. 1021308Sache * 2. Redistributions in binary form must reproduce the above copyright 1121308Sache * notice, this list of conditions and the following disclaimer in the 1221308Sache * documentation and/or other materials provided with the distribution. 1321308Sache * 3. All advertising materials mentioning features or use of this software 1421308Sache * must display the following acknowledgement: 1558310Sache * This product includes software developed by HD Associates, Inc 1621308Sache * 4. Neither the name of the author nor the names of any co-contributors 1721308Sache * may be used to endorse or promote products derived from this software 1821308Sache * without specific prior written permission. 1921308Sache * 2021308Sache * THIS SOFTWARE IS PROVIDED BY HD ASSOCIATES AND CONTRIBUTORS ``AS IS'' AND 2121308Sache * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2221308Sache * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2321308Sache * ARE DISCLAIMED. IN NO EVENT SHALL HD ASSOCIATES OR CONTRIBUTORS BE LIABLE 2421308Sache * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2521308Sache * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2658310Sache * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2721308Sache * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2821308Sache * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2921308Sache * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3021308Sache * SUCH DAMAGE. 3121308Sache * 3221308Sache * $FreeBSD: head/sys/kern/p1003_1b.c 76316 2001-05-06 16:15:42Z rwatson $ 3326497Sache */ 3426497Sache 3521308Sache/* p1003_1b: Real Time common code. 3621308Sache */ 3721308Sache 3821308Sache#include <sys/param.h> 3921308Sache#include <sys/systm.h> 4021308Sache#include <sys/kernel.h> 4126497Sache#include <sys/lock.h> 4226497Sache#include <sys/module.h> 4326497Sache#include <sys/mutex.h> 4426497Sache#include <sys/proc.h> 4526497Sache#include <sys/sysctl.h> 4621308Sache#include <sys/sysent.h> 4721308Sache#include <sys/syslog.h> 48119610Sache#include <sys/sysproto.h> 49119610Sache 5021308Sache#include <posix4/posix4.h> 5121308Sache 5221308SacheMALLOC_DEFINE(M_P31B, "p1003.1b", "Posix 1003.1B"); 5358310Sache 5458310Sache/* p31b_proc: Return a proc struct corresponding to a pid to operate on. 5558310Sache * 5647558Sache * Enforce permission policy. 57119610Sache * 5847558Sache * The policy is the same as for sending signals except there 59157184Sache * is no notion of process groups. 60157184Sache * 6121308Sache * pid == 0 means my process. 6275406Sache * 6321308Sache * This is disabled until I've got a permission gate in again: 64119610Sache * only root can do this. 6521308Sache */ 66157184Sache 67157184Sache#if 0 68157184Sache/* 69157184Sache * This is stolen from CANSIGNAL in kern_sig: 7021308Sache * 71165670Sache * Can process p, with pcred pc, do "write flavor" operations to process q? 72165670Sache */ 7321308Sache#define CAN_AFFECT(p, q) \ 74119610Sache (!suser_xxx(NULL, p, PRISON_ROOT) || \ 75119610Sache (p)->p_cred->pc_ruid == (q)->p_cred->p_ruid || \ 76119610Sache (p)->p_ucred->cr_uid == (q)->p_cred->p_ruid || \ 7775406Sache (p)->p_cred->pc_ruid == (q)->p_ucred->cr_uid || \ 78119610Sache (p)->p_ucred->cr_uid == (q)->p_ucred->cr_uid) 79119610Sache#else 80157184Sache#define CAN_AFFECT(p, q) (!suser_xxx(NULL, p, PRISON_ROOT)) 81157184Sache#endif 82157184Sache 83157184Sache/* 84157184Sache * p31b_proc: Look up a proc from a PID. If proc is 0 it is 85157184Sache * my own proc. 86157184Sache */ 87157184Sacheint p31b_proc(struct proc *p, pid_t pid, struct proc **pp) 88157184Sache{ 89157184Sache int ret = 0; 90157184Sache struct proc *other_proc = 0; 91157184Sache 92157184Sache if (pid == 0) { 93157184Sache other_proc = p; 94157184Sache PROC_LOCK(p); 95157184Sache } else 96157184Sache other_proc = pfind(pid); 97157184Sache 98157184Sache if (other_proc) 99157184Sache { 100157184Sache /* Enforce permission policy. 101157184Sache */ 102157184Sache if (CAN_AFFECT(p, other_proc)) 103157184Sache *pp = other_proc; 104157184Sache else 105157184Sache ret = EPERM; 106157184Sache PROC_UNLOCK(other_proc); 107157184Sache } 108157184Sache else 109157184Sache ret = ESRCH; 110157184Sache 111157184Sache return ret; 112157184Sache} 113157184Sache 114157184Sache/* The system calls return ENOSYS if an entry is called that is 115157184Sache * not run-time supported. I am also logging since some programs 116157184Sache * start to use this when they shouldn't. That will be removed if annoying. 117157184Sache */ 118157184Sacheint 119157184Sachesyscall_not_present(struct proc *p, const char *s, struct nosys_args *uap) 120157184Sache{ 121157184Sache log(LOG_ERR, "cmd %s pid %d tried to use non-present %s\n", 122157184Sache p->p_comm, p->p_pid, s); 123157184Sache 124157184Sache /* a " return nosys(p, uap); " here causes a core dump. 125157184Sache */ 126157184Sache 127157184Sache return ENOSYS; 128157184Sache} 129157184Sache 130157184Sache#if !defined(_KPOSIX_PRIORITY_SCHEDULING) 13121308Sache 13221308Sache/* Not configured but loadable via a module: 13321308Sache */ 13421308Sache 13521308Sachestatic int sched_attach(void) 13621308Sache{ 13721308Sache return 0; 13821308Sache} 13921308Sache 14021308SacheSYSCALL_NOT_PRESENT_GEN(sched_setparam) 14121308SacheSYSCALL_NOT_PRESENT_GEN(sched_getparam) 14221308SacheSYSCALL_NOT_PRESENT_GEN(sched_setscheduler) 14321308SacheSYSCALL_NOT_PRESENT_GEN(sched_getscheduler) 14421308SacheSYSCALL_NOT_PRESENT_GEN(sched_yield) 14521308SacheSYSCALL_NOT_PRESENT_GEN(sched_get_priority_max) 14621308SacheSYSCALL_NOT_PRESENT_GEN(sched_get_priority_min) 14721308SacheSYSCALL_NOT_PRESENT_GEN(sched_rr_get_interval) 14821308Sache 14921308Sache#else 15021308Sache 151157184Sache/* Configured in kernel version: 15221308Sache */ 15321308Sachestatic struct ksched *ksched; 15421308Sache 15521308Sachestatic int sched_attach(void) 15621308Sache{ 15721308Sache int ret = ksched_attach(&ksched); 15821308Sache 15921308Sache if (ret == 0) 16021308Sache p31b_setcfg(CTL_P1003_1B_PRIORITY_SCHEDULING, 1); 16121308Sache 16221308Sache return ret; 16321308Sache} 164119610Sache 16521308Sacheint sched_setparam(struct proc *p, 16621308Sache struct sched_setparam_args *uap) 16721308Sache{ 16821308Sache int e; 16921308Sache 17021308Sache struct sched_param sched_param; 17121308Sache copyin(uap->param, &sched_param, sizeof(sched_param)); 17221308Sache 17321308Sache (void) (0 17421308Sache || (e = p31b_proc(p, uap->pid, &p)) 17521308Sache || (e = ksched_setparam(&p->p_retval[0], ksched, p, 17621308Sache (const struct sched_param *)&sched_param)) 17721308Sache ); 17821308Sache 17921308Sache return e; 18021308Sache} 18121308Sache 18221308Sacheint sched_getparam(struct proc *p, 18321308Sache struct sched_getparam_args *uap) 18421308Sache{ 18521308Sache int e; 18621308Sache struct sched_param sched_param; 18721308Sache 18821308Sache (void) (0 18921308Sache || (e = p31b_proc(p, uap->pid, &p)) 19021308Sache || (e = ksched_getparam(&p->p_retval[0], ksched, p, &sched_param)) 19121308Sache ); 19221308Sache 19321308Sache if (!e) 194119610Sache copyout(&sched_param, uap->param, sizeof(sched_param)); 19521308Sache 19621308Sache return e; 19721308Sache} 19821308Sacheint sched_setscheduler(struct proc *p, 199157184Sache struct sched_setscheduler_args *uap) 200157184Sache{ 201157184Sache int e; 20221308Sache 203157184Sache struct sched_param sched_param; 204157184Sache copyin(uap->param, &sched_param, sizeof(sched_param)); 20521308Sache 20621308Sache (void) (0 207157184Sache || (e = p31b_proc(p, uap->pid, &p)) 208157184Sache || (e = ksched_setscheduler(&p->p_retval[0], 209157184Sache ksched, p, uap->policy, 21021308Sache (const struct sched_param *)&sched_param)) 211157184Sache ); 21275406Sache 21347558Sache return e; 21421308Sache} 215157184Sacheint sched_getscheduler(struct proc *p, 21675406Sache struct sched_getscheduler_args *uap) 21721308Sache{ 21821308Sache int e; 21921308Sache (void) (0 22021308Sache || (e = p31b_proc(p, uap->pid, &p)) 22121308Sache || (e = ksched_getscheduler(&p->p_retval[0], ksched, p)) 22221308Sache ); 223157184Sache 224157184Sache return e; 225157184Sache} 22621308Sacheint sched_yield(struct proc *p, 22775406Sache struct sched_yield_args *uap) 228157184Sache{ 22921308Sache return ksched_yield(&p->p_retval[0], ksched); 23021308Sache} 23121308Sacheint sched_get_priority_max(struct proc *p, 232157184Sache struct sched_get_priority_max_args *uap) 233157184Sache{ 234157184Sache return ksched_get_priority_max(&p->p_retval[0], 23521308Sache ksched, uap->policy); 23621308Sache} 237157184Sacheint sched_get_priority_min(struct proc *p, 23821308Sache struct sched_get_priority_min_args *uap) 23921308Sache{ 240157184Sache return ksched_get_priority_min(&p->p_retval[0], 24121308Sache ksched, uap->policy); 24247558Sache} 24321308Sacheint sched_rr_get_interval(struct proc *p, 24421308Sache struct sched_rr_get_interval_args *uap) 245157184Sache{ 246157184Sache int e; 24721308Sache 24821308Sache (void) (0 249157184Sache || (e = p31b_proc(p, uap->pid, &p)) 25021308Sache || (e = ksched_rr_get_interval(&p->p_retval[0], ksched, 251157184Sache p, uap->interval)) 252157184Sache ); 253157184Sache 25421308Sache return e; 255157184Sache} 25621308Sache 257157184Sache#endif 258157184Sache 259157184Sachestatic void p31binit(void *notused) 260157184Sache{ 261157184Sache (void) sched_attach(); 262157184Sache p31b_setcfg(CTL_P1003_1B_PAGESIZE, PAGE_SIZE); 263157184Sache} 264157184Sache 265157184SacheSYSINIT(p31b, SI_SUB_P1003_1B, SI_ORDER_FIRST, p31binit, NULL); 266157184Sache