The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/kern_p1003_1b.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 1996, 1997, 1998
    3  *      HD Associates, Inc.  All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  * 3. All advertising materials mentioning features or use of this software
   14  *    must display the following acknowledgement:
   15  *      This product includes software developed by HD Associates, Inc
   16  * 4. Neither the name of the author nor the names of any co-contributors
   17  *    may be used to endorse or promote products derived from this software
   18  *    without specific prior written permission.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY HD ASSOCIATES AND CONTRIBUTORS ``AS IS'' AND
   21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23  * ARE DISCLAIMED.  IN NO EVENT SHALL HD ASSOCIATES OR CONTRIBUTORS BE LIABLE
   24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   30  * SUCH DAMAGE.
   31  *
   32  * $FreeBSD: src/sys/posix4/p1003_1b.c,v 1.5.2.2 2003/03/25 06:13:35 rwatson Exp $
   33  */
   34 
   35 /* p1003_1b: Real Time common code.
   36  */
   37 
   38 #include <sys/param.h>
   39 #include <sys/systm.h>
   40 #include <sys/kernel.h>
   41 #include <sys/sysent.h>
   42 #include <sys/posix4.h>
   43 #include <sys/proc.h>
   44 #include <sys/syslog.h>
   45 #include <sys/module.h>
   46 #include <sys/sysproto.h>
   47 #include <sys/sysctl.h>
   48 #include <sys/unistd.h>
   49 
   50 MALLOC_DEFINE(M_P31B, "p1003.1b", "Posix 1003.1B");
   51 
   52 /*
   53  * p31b_proc: Return a proc struct corresponding to a pid to operate on.
   54  *
   55  * Enforce permission policy.
   56  *
   57  * The policy is the same as for sending signals except there
   58  * is no notion of process groups.
   59  *
   60  * pid == 0 means my process.
   61  *
   62  * This is disabled until I've got a permission gate in again:
   63  * only root can do this.
   64  */
   65 
   66 #if 0
   67 /*
   68  * This is stolen from CANSIGNAL in kern_sig:
   69  *
   70  * Can process p, with pcred pc, do "write flavor" operations to process q?
   71  */
   72 #define CAN_AFFECT(p, cr, q) \
   73         ((cr)->cr_uid == 0 || \
   74             (cr)->cr_ruid == (q)->p_ucred->cr_ruid || \
   75             (cr)->cr_uid == (q)->p_ucred->cr_ruid || \
   76             (cr)->cr_ruid == (q)->p_ucred->cr_uid || \
   77             (cr)->cr_uid == (q)->p_ucred->cr_uid)
   78 #else
   79 #define CAN_AFFECT(p, cr, q) ((cr)->cr_uid == 0)
   80 #endif
   81 
   82 /*
   83  * p31b_proc: Look up a proc from a PID.  If proc is 0 it is
   84  * my own proc.
   85  *
   86  * Returns a held process in *pp.
   87  */
   88 static
   89 int
   90 p31b_proc(pid_t pid, struct proc **pp)
   91 {
   92         int ret = 0;
   93         struct proc *p = curproc;
   94         struct proc *other_proc;
   95 
   96         if (pid == 0) {
   97                 other_proc = p;
   98                 if (other_proc)
   99                         PHOLD(other_proc);
  100         } else {
  101                 other_proc = pfind(pid);
  102                 /* ref from pfind() */
  103         }
  104 
  105         if (other_proc) {
  106                 /* Enforce permission policy.
  107                  */
  108                 if (CAN_AFFECT(p, p->p_ucred, other_proc)) {
  109                         *pp = other_proc;
  110                         lwkt_gettoken(&other_proc->p_token);
  111                 } else {
  112                         *pp = NULL;
  113                         ret = EPERM;
  114                         PRELE(other_proc);
  115                 }
  116         } else {
  117                 *pp = NULL;
  118                 ret = ESRCH;
  119         }
  120         return ret;
  121 }
  122 
  123 static
  124 void
  125 p31b_proc_done(struct proc *other_proc)
  126 {
  127         if (other_proc) {
  128                 lwkt_reltoken(&other_proc->p_token);
  129                 PRELE(other_proc);
  130         }
  131 }
  132 
  133 
  134 #if !defined(_KPOSIX_PRIORITY_SCHEDULING)
  135 
  136 int syscall_not_present(const char *s);
  137 
  138 /* The system calls return ENOSYS if an entry is called that is
  139  * not run-time supported.  I am also logging since some programs
  140  * start to use this when they shouldn't.  That will be removed if annoying.
  141  */
  142 int syscall_not_present(const char *s)
  143 {
  144         struct proc *p = curproc;
  145         log(LOG_ERR, "cmd %s pid %d tried to use non-present %s\n",
  146                         p->p_comm, p->p_pid, s);
  147 
  148         /* a " return nosys(p, uap); " here causes a core dump.
  149          */
  150 
  151         return ENOSYS;
  152 }
  153 
  154 /* Not configured but loadable via a module:
  155  */
  156 
  157 static int sched_attach(void)
  158 {
  159         return 0;
  160 }
  161 
  162 #define SYSCALL_NOT_PRESENT_GEN(SC) \
  163 int sys_##SC (struct SC##_args *uap) \
  164 { \
  165         return syscall_not_present(#SC); \
  166 }
  167 
  168 SYSCALL_NOT_PRESENT_GEN(sched_setparam)
  169 SYSCALL_NOT_PRESENT_GEN(sched_getparam)
  170 SYSCALL_NOT_PRESENT_GEN(sched_setscheduler)
  171 SYSCALL_NOT_PRESENT_GEN(sched_getscheduler)
  172 SYSCALL_NOT_PRESENT_GEN(sched_yield)
  173 SYSCALL_NOT_PRESENT_GEN(sched_get_priority_max)
  174 SYSCALL_NOT_PRESENT_GEN(sched_get_priority_min)
  175 SYSCALL_NOT_PRESENT_GEN(sched_rr_get_interval)
  176 
  177 #else
  178 
  179 /* Configured in kernel version:
  180  */
  181 static struct ksched *ksched;
  182 
  183 static int sched_attach(void)
  184 {
  185         int ret = ksched_attach(&ksched);
  186 
  187         if (ret == 0)
  188                 p31b_setcfg(CTL_P1003_1B_PRIORITY_SCHEDULING, 1);
  189 
  190         return ret;
  191 }
  192 
  193 int
  194 sys_sched_setparam(struct sched_setparam_args *uap)
  195 {
  196         struct proc *p;
  197         struct lwp *lp;
  198         struct sched_param sched_param;
  199         int e;
  200 
  201         copyin(uap->param, &sched_param, sizeof(sched_param));
  202 
  203         if ((e = p31b_proc(uap->pid, &p)) == 0) {
  204                 lp = FIRST_LWP_IN_PROC(p); /* XXX lwp */
  205                 if (lp) {
  206                         LWPHOLD(lp);
  207                         lwkt_gettoken(&lp->lwp_token);
  208                         e = ksched_setparam(&uap->sysmsg_reg, ksched, lp,
  209                                     (const struct sched_param *)&sched_param);
  210                         lwkt_reltoken(&lp->lwp_token);
  211                         LWPRELE(lp);
  212                 } else {
  213                         e = ESRCH;
  214                 }
  215                 p31b_proc_done(p);
  216         }
  217         return e;
  218 }
  219 
  220 int
  221 sys_sched_getparam(struct sched_getparam_args *uap)
  222 {
  223         struct proc *targetp;
  224         struct lwp *lp;
  225         struct sched_param sched_param;
  226         int e;
  227  
  228         if ((e = p31b_proc(uap->pid, &targetp)) == 0) {
  229                 lp = FIRST_LWP_IN_PROC(targetp); /* XXX lwp */
  230                 if (lp) {
  231                         LWPHOLD(lp);
  232                         lwkt_gettoken(&lp->lwp_token);
  233                         e = ksched_getparam(&uap->sysmsg_reg, ksched,
  234                                             lp, &sched_param);
  235                         lwkt_reltoken(&lp->lwp_token);
  236                         LWPRELE(lp);
  237                 } else {
  238                         e = ESRCH;
  239                 }
  240                 p31b_proc_done(targetp);
  241         }
  242         if (e == 0)
  243                 copyout(&sched_param, uap->param, sizeof(sched_param));
  244         return e;
  245 }
  246 
  247 int
  248 sys_sched_setscheduler(struct sched_setscheduler_args *uap)
  249 {
  250         struct proc *p;
  251         struct lwp *lp;
  252         int e;
  253         struct sched_param sched_param;
  254 
  255         copyin(uap->param, &sched_param, sizeof(sched_param));
  256 
  257         if ((e = p31b_proc(uap->pid, &p)) == 0) {
  258                 lp = FIRST_LWP_IN_PROC(p); /* XXX lwp */
  259                 if (lp) {
  260                         LWPHOLD(lp);
  261                         lwkt_gettoken(&lp->lwp_token);
  262                         e = ksched_setscheduler(&uap->sysmsg_reg, ksched,
  263                                                 lp, uap->policy,
  264                                     (const struct sched_param *)&sched_param);
  265                         lwkt_reltoken(&lp->lwp_token);
  266                         LWPRELE(lp);
  267                 } else {
  268                         e = ESRCH;
  269                 }
  270                 p31b_proc_done(p);
  271         }
  272         return e;
  273 }
  274 
  275 int
  276 sys_sched_getscheduler(struct sched_getscheduler_args *uap)
  277 {
  278         struct proc *targetp;
  279         struct lwp *lp;
  280         int e;
  281  
  282         if ((e = p31b_proc(uap->pid, &targetp)) == 0) {
  283                 lp = FIRST_LWP_IN_PROC(targetp); /* XXX lwp */
  284                 if (lp) {
  285                         LWPHOLD(lp);
  286                         lwkt_gettoken(&lp->lwp_token);
  287                         e = ksched_getscheduler(&uap->sysmsg_reg, ksched, lp);
  288                         lwkt_reltoken(&lp->lwp_token);
  289                         LWPRELE(lp);
  290                 } else {
  291                         e = ESRCH;
  292                 }
  293                 p31b_proc_done(targetp);
  294         }
  295         return e;
  296 }
  297 
  298 /*
  299  * MPSAFE
  300  */
  301 int
  302 sys_sched_yield(struct sched_yield_args *uap)
  303 {
  304         return ksched_yield(&uap->sysmsg_reg, ksched);
  305 }
  306 
  307 /*
  308  * MPSAFE
  309  */
  310 int
  311 sys_sched_get_priority_max(struct sched_get_priority_max_args *uap)
  312 {
  313         return ksched_get_priority_max(&uap->sysmsg_reg, ksched, uap->policy);
  314 }
  315 
  316 /*
  317  * MPSAFE
  318  */
  319 int
  320 sys_sched_get_priority_min(struct sched_get_priority_min_args *uap)
  321 {
  322         return ksched_get_priority_min(&uap->sysmsg_reg, ksched, uap->policy);
  323 }
  324 
  325 int
  326 sys_sched_rr_get_interval(struct sched_rr_get_interval_args *uap)
  327 {
  328         int e;
  329         struct proc *p;
  330         struct lwp *lp;
  331         struct timespec ts;
  332 
  333         if ((e = p31b_proc(uap->pid, &p)) == 0) {
  334                 lp = FIRST_LWP_IN_PROC(p); /* XXX lwp */
  335                 if (lp) {
  336                         LWPHOLD(lp);
  337                         lwkt_gettoken(&lp->lwp_token);
  338                         e = ksched_rr_get_interval(&uap->sysmsg_reg, ksched,
  339                                                    lp, &ts);
  340                         if (e == 0)
  341                                 e = copyout(&ts, uap->interval, sizeof(ts));
  342                         lwkt_reltoken(&lp->lwp_token);
  343                         LWPRELE(lp);
  344                 } else {
  345                         e = ESRCH;
  346                 }
  347                 p31b_proc_done(p);
  348         }
  349         return e;
  350 }
  351 
  352 #endif
  353 
  354 static void
  355 p31binit(void *notused)
  356 {
  357         (void) sched_attach();
  358         p31b_setcfg(CTL_P1003_1B_PAGESIZE, PAGE_SIZE);
  359         p31b_setcfg(CTL_P1003_1B_ASYNCHRONOUS_IO, -1);
  360         p31b_setcfg(CTL_P1003_1B_MESSAGE_PASSING, _POSIX_MESSAGE_PASSING);
  361 }
  362 
  363 SYSINIT(p31b, SI_SUB_P1003_1B, SI_ORDER_FIRST, p31binit, NULL);

Cache object: 98acc4ba10e28abc088406443949a370


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.