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/ipc_host.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  * Mach Operating System
    3  * Copyright (c) 1992,1991,1990,1989,1988 Carnegie Mellon University
    4  * All Rights Reserved.
    5  * 
    6  * Permission to use, copy, modify and distribute this software and its
    7  * documentation is hereby granted, provided that both the copyright
    8  * notice and this permission notice appear in all copies of the
    9  * software, derivative works or modified versions, and any portions
   10  * thereof, and that both notices appear in supporting documentation.
   11  * 
   12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   15  * 
   16  * Carnegie Mellon requests users of this software to return to
   17  * 
   18  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   19  *  School of Computer Science
   20  *  Carnegie Mellon University
   21  *  Pittsburgh PA 15213-3890
   22  * 
   23  * any improvements or extensions that they make and grant Carnegie Mellon
   24  * the rights to redistribute these changes.
   25  */
   26 /*
   27  * HISTORY
   28  * $Log:        ipc_host.c,v $
   29  * Revision 2.14  93/05/15  18:55:15  mrt
   30  *      machparam.h -> machspl.h
   31  * 
   32  * Revision 2.13  93/01/14  17:34:21  danner
   33  *      Added function prototypes.  Combined ipc_processor_init and
   34  *      ipc_processor_enable.  Removed ipc_processor_disable and
   35  *      ipc_processor_terminate; processor ports are never removed.
   36  *      Fixed lock ordering bugs in processor and processor_set code.
   37  *      [92/11/17            dbg]
   38  *      Added function prototypes.  Combined ipc_processor_init and
   39  *      ipc_processor_enable.  Removed ipc_processor_disable and
   40  *      ipc_processor_terminate; processor ports are never removed.
   41  *      Fixed lock ordering bugs in processor and processor_set code.
   42  *      [92/11/17            dbg]
   43  * 
   44  * Revision 2.12  92/08/03  17:37:13  jfriedl
   45  *      removed silly prototypes
   46  *      [92/08/02            jfriedl]
   47  * 
   48  * Revision 2.11  92/05/21  17:13:39  jfriedl
   49  *      tried prototypes.
   50  *      [92/05/20            jfriedl]
   51  * 
   52  * Revision 2.10  91/08/03  18:18:50  jsb
   53  *      Removed NORMA hooks.
   54  *      [91/07/17  23:05:10  jsb]
   55  * 
   56  * Revision 2.9  91/06/25  10:28:20  rpd
   57  *      Changed the convert_foo_to_bar functions
   58  *      to use ipc_port_t instead of mach_port_t.
   59  *      [91/05/27            rpd]
   60  * 
   61  * Revision 2.8  91/06/17  15:46:59  jsb
   62  *      Renamed NORMA conditionals.
   63  *      [91/06/17  10:49:34  jsb]
   64  * 
   65  * Revision 2.7  91/06/06  17:06:59  jsb
   66  *      Redid host port initialization under NORMA_IPC.
   67  *      [91/05/13  17:37:21  jsb]
   68  * 
   69  * Revision 2.6  91/05/14  16:41:36  mrt
   70  *      Correcting copyright
   71  * 
   72  * Revision 2.5  91/02/05  17:26:24  mrt
   73  *      Changed to new Mach copyright
   74  *      [91/02/01  16:12:32  mrt]
   75  * 
   76  * Revision 2.4  90/09/09  14:32:08  rpd
   77  *      Don't take out extra references in ipc_pset_init.
   78  *      [90/08/30            rpd]
   79  * 
   80  * Revision 2.3  90/06/19  22:58:46  rpd
   81  *      Changed convert_port_to_pset_name to allow
   82  *      both IKOT_PSET and IKOT_PSET_NAME ports.
   83  *      Changed convert_port_to_host to allow
   84  *      both IKOT_HOST and IKOT_HOST_PRIV ports.
   85  *      [90/06/18            rpd]
   86  * 
   87  *      Fixed bug in convert_processor_to_port.
   88  *      [90/06/16            rpd]
   89  * 
   90  * Revision 2.2  90/06/02  14:53:59  rpd
   91  *      Created for new IPC.
   92  *      [90/03/26  23:46:28  rpd]
   93  * 
   94  *      Move includes.
   95  *      [89/08/02            dlb]
   96  *      Remove interrupt protection from pset locks.
   97  *      [89/06/14            dlb]
   98  *      Use port_alloc instead of xxx_port_allocate.
   99  *      [89/02/21            dlb]
  100  *      Reformat includes.
  101  *      [89/01/26            dlb]
  102  * 
  103  *      Break processor_set_default into two pieces.
  104  *      [88/12/21            dlb]
  105  * 
  106  *      Move host_self, host_priv_self to ipc_ptraps.c
  107  *      Rewrite processor_set_default to return both ports
  108  *      [88/11/30            dlb]
  109  * 
  110  *      Created.
  111  *      [88/10/29            dlb]
  112  * 
  113  * Revision 2.4  89/12/22  15:52:20  rpd
  114  *      Take out extra reference on new processor set ports in
  115  *      ipc_pset_init for reply message; these ports are now
  116  *      returned untranslated.  Assume caller of ipc_pset_disable
  117  *      has pset locked as well as referenced.
  118  *      [89/12/15            dlb]
  119  * 
  120  * Revision 2.3  89/10/15  02:04:29  rpd
  121  *      Minor cleanups.
  122  * 
  123  * Revision 2.2  89/10/11  14:07:11  dlb
  124  *      Fix includes.
  125  *      Remove interrupt protection from pset locks.
  126  * 
  127  */
  128 
  129 /*
  130  *      kern/ipc_host.c
  131  *
  132  *      Routines to implement host ports.
  133  */
  134 
  135 #include <mach/message.h>
  136 #include <kern/host.h>
  137 #include <kern/processor.h>
  138 #include <kern/task.h>
  139 #include <kern/thread.h>
  140 #include <kern/ipc_host.h>
  141 #include <kern/ipc_kobject.h>
  142 #include <ipc/ipc_port.h>
  143 #include <ipc/ipc_space.h>
  144 
  145 #include <machine/machspl.h>    /* for spl */
  146 
  147 
  148 
  149 /*
  150  *      ipc_host_init: set up various things.
  151  */
  152 
  153 void ipc_host_init(void)
  154 {
  155         ipc_port_t      port;
  156         /*
  157          *      Allocate and set up the two host ports.
  158          */
  159         port = ipc_port_alloc_kernel();
  160         if (port == IP_NULL)
  161                 panic("ipc_host_init");
  162 
  163         ipc_kobject_set(port, (ipc_kobject_t) &realhost, IKOT_HOST);
  164         realhost.host_self = port;
  165 
  166         port = ipc_port_alloc_kernel();
  167         if (port == IP_NULL)
  168                 panic("ipc_host_init");
  169 
  170         ipc_kobject_set(port, (ipc_kobject_t) &realhost, IKOT_HOST_PRIV);
  171         realhost.host_priv_self = port;
  172 
  173         /*
  174          *      Set up ipc for default processor set.
  175          */
  176         ipc_pset_init(&default_pset);
  177         ipc_pset_enable(&default_pset);
  178 
  179         /*
  180          *      And for master processor
  181          */
  182         ipc_processor_init(master_processor);
  183 }
  184 
  185 /*
  186  *      Routine:        mach_host_self [mach trap]
  187  *      Purpose:
  188  *              Give the caller send rights for his own host port.
  189  *      Conditions:
  190  *              Nothing locked.
  191  *      Returns:
  192  *              MACH_PORT_NULL if there are any resource failures
  193  *              or other errors.
  194  */
  195 
  196 mach_port_t
  197 mach_host_self(void)
  198 {
  199         ipc_port_t sright;
  200 
  201         sright = ipc_port_make_send(realhost.host_self);
  202         return ipc_port_copyout_send(sright, current_space());
  203 }
  204 
  205 #if     MACH_IPC_COMPAT
  206 
  207 /*
  208  *      Routine:        host_self [mach trap]
  209  *      Purpose:
  210  *              Give the caller send rights for his own host port.
  211  *              If new, the send right is marked with IE_BITS_COMPAT.
  212  *      Conditions:
  213  *              Nothing locked.
  214  *      Returns:
  215  *              MACH_PORT_NULL if there are any resource failures
  216  *              or other errors.
  217  */
  218 
  219 port_name_t
  220 host_self(void)
  221 {
  222         ipc_port_t sright;
  223 
  224         sright = ipc_port_make_send(realhost.host_self);
  225         return (port_name_t)
  226                 ipc_port_copyout_send_compat(sright, current_space());
  227 }
  228 
  229 #endif  MACH_IPC_COMPAT
  230 
  231 /*
  232  *      ipc_processor_init:
  233  *
  234  *      Initialize ipc access to processor by allocating port.
  235  *      Enable ipc control of processor by setting port object.
  236  */
  237 
  238 void
  239 ipc_processor_init(
  240         processor_t     processor)
  241 {
  242         ipc_port_t      port;
  243 
  244         port = ipc_port_alloc_kernel();
  245         if (port == IP_NULL)
  246                 panic("ipc_processor_init");
  247         processor->processor_self = port;
  248         ipc_kobject_set(port, (ipc_kobject_t) processor, IKOT_PROCESSOR);
  249 }
  250 
  251 
  252 /*
  253  *      ipc_pset_init:
  254  *
  255  *      Initialize ipc control of a processor set by allocating its ports.
  256  */
  257 
  258 void
  259 ipc_pset_init(
  260         processor_set_t pset)
  261 {
  262         ipc_port_t      port;
  263 
  264         port = ipc_port_alloc_kernel();
  265         if (port == IP_NULL)
  266                 panic("ipc_pset_init");
  267         pset->pset_self = port;
  268 
  269         port = ipc_port_alloc_kernel();
  270         if (port == IP_NULL)
  271                 panic("ipc_pset_init");
  272         pset->pset_name_self = port;
  273 }
  274 
  275 /*
  276  *      ipc_pset_enable:
  277  *
  278  *      Enable ipc access to a processor set.
  279  */
  280 void
  281 ipc_pset_enable(
  282         processor_set_t pset)
  283 {
  284         pset_lock(pset);
  285         if (pset->active) {
  286                 ipc_kobject_set(pset->pset_self,
  287                                 (ipc_kobject_t) pset, IKOT_PSET);
  288                 ipc_kobject_set(pset->pset_name_self,
  289                                 (ipc_kobject_t) pset, IKOT_PSET_NAME);
  290                 pset_ref_lock(pset);
  291                 pset->ref_count += 2;
  292                 pset_ref_unlock(pset);
  293         }
  294         pset_unlock(pset);
  295 }
  296 
  297 /*
  298  *      ipc_pset_disable:
  299  *
  300  *      Disable ipc access to a processor set by clearing the port objects.
  301  *      Caller must hold pset lock and a reference to the pset.  Ok to
  302  *      just decrement pset reference count as a result.
  303  */
  304 void
  305 ipc_pset_disable(
  306         processor_set_t pset)
  307 {
  308         ipc_kobject_set(pset->pset_self, IKO_NULL, IKOT_NONE);
  309         ipc_kobject_set(pset->pset_name_self, IKO_NULL, IKOT_NONE);
  310 
  311         pset_ref_lock(pset);
  312         pset->ref_count -= 2;
  313         pset_ref_unlock(pset);
  314 }
  315 
  316 /*
  317  *      ipc_pset_terminate:
  318  *
  319  *      Processor set is dead.  Deallocate the ipc control structures.
  320  */
  321 void
  322 ipc_pset_terminate(
  323         processor_set_t pset)
  324 {
  325         ipc_port_dealloc_kernel(pset->pset_self);
  326         ipc_port_dealloc_kernel(pset->pset_name_self);
  327 }
  328 
  329 /*
  330  *      processor_set_default, processor_set_default_priv:
  331  *
  332  *      Return ports for manipulating default_processor set.  MiG code
  333  *      differentiates between these two routines.
  334  */
  335 kern_return_t
  336 processor_set_default(
  337         host_t          host,
  338         processor_set_t *pset)
  339 {
  340         if (host == HOST_NULL)
  341                 return KERN_INVALID_ARGUMENT;
  342 
  343         *pset = &default_pset;
  344         pset_reference(*pset);
  345         return KERN_SUCCESS;
  346 }
  347 
  348 kern_return_t
  349 xxx_processor_set_default_priv(
  350         host_t          host,
  351         processor_set_t *pset)
  352 {
  353         if (host == HOST_NULL)
  354                 return KERN_INVALID_ARGUMENT;
  355 
  356         *pset = &default_pset;
  357         pset_reference(*pset);
  358         return KERN_SUCCESS;
  359 }
  360 
  361 /*
  362  *      Routine:        convert_port_to_host
  363  *      Purpose:
  364  *              Convert from a port to a host.
  365  *              Doesn't consume the port ref; the host produced may be null.
  366  *      Conditions:
  367  *              Nothing locked.
  368  */
  369 
  370 host_t
  371 convert_port_to_host(ipc_port_t port)
  372 {
  373         host_t host = HOST_NULL;
  374 
  375         if (IP_VALID(port)) {
  376                 ip_lock(port);
  377                 if (ip_active(port) &&
  378                     ((ip_kotype(port) == IKOT_HOST) ||
  379                      (ip_kotype(port) == IKOT_HOST_PRIV)))
  380                         host = (host_t) port->ip_kobject;
  381                 ip_unlock(port);
  382         }
  383 
  384         return host;
  385 }
  386 
  387 /*
  388  *      Routine:        convert_port_to_host_priv
  389  *      Purpose:
  390  *              Convert from a port to a host.
  391  *              Doesn't consume the port ref; the host produced may be null.
  392  *      Conditions:
  393  *              Nothing locked.
  394  */
  395 
  396 host_t
  397 convert_port_to_host_priv(ipc_port_t port)
  398 {
  399         host_t host = HOST_NULL;
  400 
  401         if (IP_VALID(port)) {
  402                 ip_lock(port);
  403                 if (ip_active(port) &&
  404                     (ip_kotype(port) == IKOT_HOST_PRIV))
  405                         host = (host_t) port->ip_kobject;
  406                 ip_unlock(port);
  407         }
  408 
  409         return host;
  410 }
  411 
  412 /*
  413  *      Routine:        convert_port_to_processor
  414  *      Purpose:
  415  *              Convert from a port to a processor.
  416  *              Doesn't consume the port ref;
  417  *              the processor produced may be null.
  418  *      Conditions:
  419  *              Nothing locked.
  420  */
  421 
  422 processor_t
  423 convert_port_to_processor(ipc_port_t port)
  424 {
  425         processor_t processor = PROCESSOR_NULL;
  426 
  427         if (IP_VALID(port)) {
  428                 ip_lock(port);
  429                 if (ip_active(port) &&
  430                     (ip_kotype(port) == IKOT_PROCESSOR))
  431                         processor = (processor_t) port->ip_kobject;
  432                 ip_unlock(port);
  433         }
  434 
  435         return processor;
  436 }
  437 
  438 /*
  439  *      Routine:        convert_port_to_pset
  440  *      Purpose:
  441  *              Convert from a port to a pset.
  442  *              Doesn't consume the port ref; produces a pset ref,
  443  *              which may be null.
  444  *      Conditions:
  445  *              Nothing locked.
  446  */
  447 
  448 processor_set_t
  449 convert_port_to_pset(ipc_port_t port)
  450 {
  451         processor_set_t pset = PROCESSOR_SET_NULL;
  452 
  453         if (IP_VALID(port)) {
  454                 ip_lock(port);
  455                 if (ip_active(port) &&
  456                     (ip_kotype(port) == IKOT_PSET)) {
  457                         pset = (processor_set_t) port->ip_kobject;
  458                         pset_reference(pset);
  459                 }
  460                 ip_unlock(port);
  461         }
  462 
  463         return pset;
  464 }
  465 
  466 /*
  467  *      Routine:        convert_port_to_pset_name
  468  *      Purpose:
  469  *              Convert from a port to a pset.
  470  *              Doesn't consume the port ref; produces a pset ref,
  471  *              which may be null.
  472  *      Conditions:
  473  *              Nothing locked.
  474  */
  475 
  476 processor_set_t
  477 convert_port_to_pset_name(ipc_port_t port)
  478 {
  479         processor_set_t pset = PROCESSOR_SET_NULL;
  480 
  481         if (IP_VALID(port)) {
  482                 ip_lock(port);
  483                 if (ip_active(port) &&
  484                     ((ip_kotype(port) == IKOT_PSET) ||
  485                      (ip_kotype(port) == IKOT_PSET_NAME))) {
  486                         pset = (processor_set_t) port->ip_kobject;
  487                         pset_reference(pset);
  488                 }
  489                 ip_unlock(port);
  490         }
  491 
  492         return pset;
  493 }
  494 
  495 /*
  496  *      Routine:        convert_host_to_port
  497  *      Purpose:
  498  *              Convert from a host to a port.
  499  *              Produces a naked send right which is always valid.
  500  *      Conditions:
  501  *              Nothing locked.
  502  */
  503 
  504 ipc_port_t
  505 convert_host_to_port(host_t host)
  506 {
  507         ipc_port_t port;
  508 
  509         port = ipc_port_make_send(host->host_self);
  510 
  511         return port;
  512 }
  513 
  514 /*
  515  *      Routine:        convert_processor_to_port
  516  *      Purpose:
  517  *              Convert from a processor to a port.
  518  *              Produces a naked send right which is always valid.
  519  *      Conditions:
  520  *              Nothing locked.
  521  */
  522 
  523 ipc_port_t
  524 convert_processor_to_port(processor_t processor)
  525 {
  526         ipc_port_t port;
  527 
  528         port = ipc_port_make_send(processor->processor_self);
  529 
  530         return port;
  531 }
  532 
  533 /*
  534  *      Routine:        convert_pset_to_port
  535  *      Purpose:
  536  *              Convert from a pset to a port.
  537  *              Consumes a pset ref; produces a naked send right
  538  *              which may be invalid.
  539  *      Conditions:
  540  *              Nothing locked.
  541  */
  542 
  543 ipc_port_t
  544 convert_pset_to_port(processor_set_t pset)
  545 {
  546         ipc_port_t port;
  547 
  548         pset_lock(pset);
  549         if (pset->active)
  550                 port = ipc_port_make_send(pset->pset_self);
  551         else
  552                 port = IP_NULL;
  553         pset_unlock(pset);
  554 
  555         pset_deallocate(pset);
  556         return port;
  557 }
  558 
  559 /*
  560  *      Routine:        convert_pset_name_to_port
  561  *      Purpose:
  562  *              Convert from a pset to a port.
  563  *              Consumes a pset ref; produces a naked send right
  564  *              which may be invalid.
  565  *      Conditions:
  566  *              Nothing locked.
  567  */
  568 
  569 ipc_port_t
  570 convert_pset_name_to_port(processor_set_t pset)
  571 {
  572         ipc_port_t port;
  573 
  574         pset_lock(pset);
  575         if (pset->active)
  576                 port = ipc_port_make_send(pset->pset_name_self);
  577         else
  578                 port = IP_NULL;
  579         pset_unlock(pset);
  580 
  581         pset_deallocate(pset);
  582         return port;
  583 }

Cache object: 97ff902848f19f8d49c4f3476211f5c7


[ 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.