Annotation of XNU/osfmk/kern/ipc_host.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /*
                     23:  * @OSF_COPYRIGHT@
                     24:  */
                     25: /* 
                     26:  * Mach Operating System
                     27:  * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University
                     28:  * All Rights Reserved.
                     29:  * 
                     30:  * Permission to use, copy, modify and distribute this software and its
                     31:  * documentation is hereby granted, provided that both the copyright
                     32:  * notice and this permission notice appear in all copies of the
                     33:  * software, derivative works or modified versions, and any portions
                     34:  * thereof, and that both notices appear in supporting documentation.
                     35:  * 
                     36:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     37:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     38:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     39:  * 
                     40:  * Carnegie Mellon requests users of this software to return to
                     41:  * 
                     42:  *  Software Distribution Coordinator  or  [email protected]
                     43:  *  School of Computer Science
                     44:  *  Carnegie Mellon University
                     45:  *  Pittsburgh PA 15213-3890
                     46:  * 
                     47:  * any improvements or extensions that they make and grant Carnegie Mellon
                     48:  * the rights to redistribute these changes.
                     49:  */
                     50: /*
                     51:  */
                     52: 
                     53: /*
                     54:  *     kern/ipc_host.c
                     55:  *
                     56:  *     Routines to implement host ports.
                     57:  */
                     58: #include <mach/message.h>
                     59: #include <mach/mach_traps.h>
                     60: #include <mach/mach_host_server.h>
                     61: #include <kern/host.h>
                     62: #include <kern/processor.h>
                     63: #include <kern/task.h>
                     64: #include <kern/thread.h>
                     65: #include <kern/ipc_host.h>
                     66: #include <kern/ipc_kobject.h>
                     67: #include <kern/misc_protos.h>
                     68: #include <kern/spl.h>
                     69: #include <ipc/ipc_port.h>
                     70: #include <ipc/ipc_space.h>
                     71: 
                     72: /*
                     73:  * Forward declarations
                     74:  */
                     75: 
                     76: void
                     77: ipc_processor_terminate(
                     78:        processor_t     processor);
                     79: 
                     80: void
                     81: ipc_processor_disable(
                     82:        processor_t     processor);
                     83: 
                     84: boolean_t
                     85: ref_pset_port_locked(
                     86:        ipc_port_t port, boolean_t matchn, processor_set_t *ppset);
                     87: 
                     88: /*
                     89:  *     ipc_host_init: set up various things.
                     90:  */
                     91: 
                     92: void ipc_host_init(void)
                     93: {
                     94:        ipc_port_t      port;
                     95:        /*
                     96:         *      Allocate and set up the two host ports.
                     97:         */
                     98:        port = ipc_port_alloc_kernel();
                     99:        if (port == IP_NULL)
                    100:                panic("ipc_host_init");
                    101: 
                    102:        ipc_kobject_set(port, (ipc_kobject_t) &realhost, IKOT_HOST);
                    103:        realhost.host_self = port;
                    104: 
                    105:        port = ipc_port_alloc_kernel();
                    106:        if (port == IP_NULL)
                    107:                panic("ipc_host_init");
                    108: 
                    109:        ipc_kobject_set(port, (ipc_kobject_t) &realhost, IKOT_HOST_PRIV);
                    110:        realhost.host_priv_self = port;
                    111: 
                    112:        port = ipc_port_alloc_kernel();
                    113:        if (port == IP_NULL)
                    114:                panic("ipc_host_init");
                    115: 
                    116:        ipc_kobject_set(port, (ipc_kobject_t) &realhost, IKOT_HOST_SECURITY);
                    117:        realhost.host_security_self = port;
                    118:        /*
                    119:         *      Set up ipc for default processor set.
                    120:         */
                    121:        ipc_pset_init(&default_pset);
                    122:        ipc_pset_enable(&default_pset);
                    123: 
                    124:        /*
                    125:         *      And for master processor
                    126:         */
                    127:        ipc_processor_init(master_processor);
                    128:        ipc_processor_enable(master_processor);
                    129: }
                    130: 
                    131: /*
                    132:  *     Routine:        mach_host_self [mach trap]
                    133:  *     Purpose:
                    134:  *             Give the caller send rights for his own host port.
                    135:  *     Conditions:
                    136:  *             Nothing locked.
                    137:  *     Returns:
                    138:  *             MACH_PORT_NULL if there are any resource failures
                    139:  *             or other errors.
                    140:  */
                    141: 
                    142: mach_port_name_t
                    143: mach_host_self(void)
                    144: {
                    145:        ipc_port_t sright;
                    146: 
                    147:        sright = ipc_port_make_send(realhost.host_self);
                    148:        return ipc_port_copyout_send(sright, current_space());
                    149: }
                    150: 
                    151: /*
                    152:  *     ipc_processor_init:
                    153:  *
                    154:  *     Initialize ipc access to processor by allocating port.
                    155:  */
                    156: 
                    157: void
                    158: ipc_processor_init(
                    159:        processor_t     processor)
                    160: {
                    161:        ipc_port_t      port;
                    162: 
                    163:        port = ipc_port_alloc_kernel();
                    164:        if (port == IP_NULL)
                    165:                panic("ipc_processor_init");
                    166:        processor->processor_self = port;
                    167: }
                    168: 
                    169: /*
                    170:  *     ipc_processor_enable:
                    171:  *
                    172:  *     Enable ipc control of processor by setting port object.
                    173:  */
                    174: void
                    175: ipc_processor_enable(
                    176:        processor_t     processor)
                    177: {
                    178:        ipc_port_t      myport;
                    179: 
                    180:        myport = processor->processor_self;
                    181:        ipc_kobject_set(myport, (ipc_kobject_t) processor, IKOT_PROCESSOR);
                    182: }
                    183: 
                    184: /*
                    185:  *     ipc_processor_disable:
                    186:  *
                    187:  *     Disable ipc control of processor by clearing port object.
                    188:  */
                    189: void
                    190: ipc_processor_disable(
                    191:        processor_t     processor)
                    192: {
                    193:        ipc_port_t      myport;
                    194: 
                    195:        myport = processor->processor_self;
                    196:        if (myport == IP_NULL)
                    197:                return;
                    198:        ipc_kobject_set(myport, IKO_NULL, IKOT_NONE);
                    199: }
                    200: 
                    201: /*
                    202:  *     ipc_processor_terminate:
                    203:  *
                    204:  *     Processor is off-line.  Destroy ipc control port.
                    205:  */
                    206: void
                    207: ipc_processor_terminate(
                    208:        processor_t     processor)
                    209: {
                    210:        ipc_port_t      myport;
                    211:        spl_t           s;
                    212: 
                    213:        s = splsched();
                    214:        processor_lock(processor);
                    215:        myport = processor->processor_self;
                    216:        if (myport == IP_NULL) {
                    217:                processor_unlock(processor);
                    218:                splx(s);
                    219:                return;
                    220:        }
                    221: 
                    222:        processor->processor_self = IP_NULL;
                    223:        processor_unlock(processor);
                    224:        splx(s);
                    225: 
                    226:        ipc_port_dealloc_kernel(myport);
                    227: }
                    228:        
                    229: /*
                    230:  *     ipc_pset_init:
                    231:  *
                    232:  *     Initialize ipc control of a processor set by allocating its ports.
                    233:  */
                    234: 
                    235: void
                    236: ipc_pset_init(
                    237:        processor_set_t         pset)
                    238: {
                    239:        ipc_port_t      port;
                    240: 
                    241:        port = ipc_port_alloc_kernel();
                    242:        if (port == IP_NULL)
                    243:                panic("ipc_pset_init");
                    244:        pset->pset_self = port;
                    245: 
                    246:        port = ipc_port_alloc_kernel();
                    247:        if (port == IP_NULL)
                    248:                panic("ipc_pset_init");
                    249:        pset->pset_name_self = port;
                    250: }
                    251: 
                    252: /*
                    253:  *     ipc_pset_enable:
                    254:  *
                    255:  *     Enable ipc access to a processor set.
                    256:  */
                    257: void
                    258: ipc_pset_enable(
                    259:        processor_set_t         pset)
                    260: {
                    261:        pset_lock(pset);
                    262:        if (pset->active) {
                    263:                ipc_kobject_set(pset->pset_self,
                    264:                                (ipc_kobject_t) pset, IKOT_PSET);
                    265:                ipc_kobject_set(pset->pset_name_self,
                    266:                                (ipc_kobject_t) pset, IKOT_PSET_NAME);
                    267:                pset->ref_count += 2;
                    268:        }
                    269:        pset_unlock(pset);
                    270: }
                    271: 
                    272: /*
                    273:  *     ipc_pset_disable:
                    274:  *
                    275:  *     Disable ipc access to a processor set by clearing the port objects.
                    276:  *     Caller must hold pset lock and a reference to the pset.  Ok to
                    277:  *     just decrement pset reference count as a result.
                    278:  */
                    279: void
                    280: ipc_pset_disable(
                    281:        processor_set_t         pset)
                    282: {
                    283:        ipc_kobject_set(pset->pset_self, IKO_NULL, IKOT_NONE);
                    284:        ipc_kobject_set(pset->pset_name_self, IKO_NULL, IKOT_NONE);
                    285:        pset->ref_count -= 2;
                    286: }
                    287: 
                    288: /*
                    289:  *     ipc_pset_terminate:
                    290:  *
                    291:  *     Processor set is dead.  Deallocate the ipc control structures.
                    292:  */
                    293: void
                    294: ipc_pset_terminate(
                    295:        processor_set_t         pset)
                    296: {
                    297:        ipc_port_dealloc_kernel(pset->pset_self);
                    298:        ipc_port_dealloc_kernel(pset->pset_name_self);
                    299: }
                    300: 
                    301: /*
                    302:  *     processor_set_default, processor_set_default_priv:
                    303:  *
                    304:  *     Return ports for manipulating default_processor set.  MiG code
                    305:  *     differentiates between these two routines.
                    306:  */
                    307: kern_return_t
                    308: processor_set_default(
                    309:        host_t                  host,
                    310:        processor_set_t         *pset)
                    311: {
                    312:        if (host == HOST_NULL)
                    313:                return(KERN_INVALID_ARGUMENT);
                    314: 
                    315:        *pset = &default_pset;
                    316:        pset_reference(*pset);
                    317:        return(KERN_SUCCESS);
                    318: }
                    319: 
                    320: /*
                    321:  *     Routine:        convert_port_to_host
                    322:  *     Purpose:
                    323:  *             Convert from a port to a host.
                    324:  *             Doesn't consume the port ref; the host produced may be null.
                    325:  *     Conditions:
                    326:  *             Nothing locked.
                    327:  */
                    328: 
                    329: host_t
                    330: convert_port_to_host(
                    331:        ipc_port_t      port)
                    332: {
                    333:        host_t host = HOST_NULL;
                    334: 
                    335:        if (IP_VALID(port)) {
                    336:                ip_lock(port);
                    337:                if (ip_active(port) &&
                    338:                    ((ip_kotype(port) == IKOT_HOST) ||
                    339:                     (ip_kotype(port) == IKOT_HOST_PRIV) 
                    340:                     ))
                    341:                        host = (host_t) port->ip_kobject;
                    342:                ip_unlock(port);
                    343:        }
                    344: 
                    345:        return host;
                    346: }
                    347: 
                    348: /*
                    349:  *     Routine:        convert_port_to_host_priv
                    350:  *     Purpose:
                    351:  *             Convert from a port to a host.
                    352:  *             Doesn't consume the port ref; the host produced may be null.
                    353:  *     Conditions:
                    354:  *             Nothing locked.
                    355:  */
                    356: 
                    357: host_t
                    358: convert_port_to_host_priv(
                    359:        ipc_port_t      port)
                    360: {
                    361:        host_t host = HOST_NULL;
                    362: 
                    363:        if (IP_VALID(port)) {
                    364:                ip_lock(port);
                    365:                if (ip_active(port) &&
                    366:                    (ip_kotype(port) == IKOT_HOST_PRIV))
                    367:                        host = (host_t) port->ip_kobject;
                    368:                ip_unlock(port);
                    369:        }
                    370: 
                    371:        return host;
                    372: }
                    373: 
                    374: /*
                    375:  *     Routine:        convert_port_to_processor
                    376:  *     Purpose:
                    377:  *             Convert from a port to a processor.
                    378:  *             Doesn't consume the port ref;
                    379:  *             the processor produced may be null.
                    380:  *     Conditions:
                    381:  *             Nothing locked.
                    382:  */
                    383: 
                    384: processor_t
                    385: convert_port_to_processor(
                    386:        ipc_port_t      port)
                    387: {
                    388:        processor_t processor = PROCESSOR_NULL;
                    389: 
                    390:        if (IP_VALID(port)) {
                    391:                ip_lock(port);
                    392:                if (ip_active(port) &&
                    393:                    (ip_kotype(port) == IKOT_PROCESSOR))
                    394:                        processor = (processor_t) port->ip_kobject;
                    395:                ip_unlock(port);
                    396:        }
                    397: 
                    398:        return processor;
                    399: }
                    400: 
                    401: /*
                    402:  *     Routine:        convert_port_to_pset
                    403:  *     Purpose:
                    404:  *             Convert from a port to a pset.
                    405:  *             Doesn't consume the port ref; produces a pset ref,
                    406:  *             which may be null.
                    407:  *     Conditions:
                    408:  *             Nothing locked.
                    409:  */
                    410: 
                    411: processor_set_t
                    412: convert_port_to_pset(
                    413:        ipc_port_t      port)
                    414: {
                    415:        boolean_t r;
                    416:        processor_set_t pset = PROCESSOR_SET_NULL;
                    417: 
                    418:        r = FALSE;
                    419:        while (!r && IP_VALID(port)) {
                    420:                ip_lock(port);
                    421:                r = ref_pset_port_locked(port, FALSE, &pset);
                    422:                /* port unlocked */
                    423:        }
                    424:        return pset;
                    425: }
                    426: 
                    427: /*
                    428:  *     Routine:        convert_port_to_pset_name
                    429:  *     Purpose:
                    430:  *             Convert from a port to a pset.
                    431:  *             Doesn't consume the port ref; produces a pset ref,
                    432:  *             which may be null.
                    433:  *     Conditions:
                    434:  *             Nothing locked.
                    435:  */
                    436: 
                    437: processor_set_name_t
                    438: convert_port_to_pset_name(
                    439:        ipc_port_t      port)
                    440: {
                    441:        boolean_t r;
                    442:        processor_set_t pset = PROCESSOR_SET_NULL;
                    443: 
                    444:        r = FALSE;
                    445:        while (!r && IP_VALID(port)) {
                    446:                ip_lock(port);
                    447:                r = ref_pset_port_locked(port, TRUE, &pset);
                    448:                /* port unlocked */
                    449:        }
                    450:        return pset;
                    451: }
                    452: 
                    453: boolean_t
                    454: ref_pset_port_locked(ipc_port_t port, boolean_t matchn, processor_set_t *ppset)
                    455: {
                    456:        processor_set_t pset;
                    457: 
                    458:        pset = PROCESSOR_SET_NULL;
                    459:        if (ip_active(port) &&
                    460:                ((ip_kotype(port) == IKOT_PSET) ||
                    461:                 (matchn && (ip_kotype(port) == IKOT_PSET_NAME)))) {
                    462:                pset = (processor_set_t) port->ip_kobject;
                    463:                if (!pset_lock_try(pset)) {
                    464:                        ip_unlock(port);
                    465:                        mutex_pause();
                    466:                        return (FALSE);
                    467:                }
                    468:                pset->ref_count++;
                    469:                pset_unlock(pset);
                    470:        }
                    471:        *ppset = pset;
                    472:        ip_unlock(port);
                    473:        return (TRUE);
                    474: }
                    475: 
                    476: /*
                    477:  *     Routine:        convert_host_to_port
                    478:  *     Purpose:
                    479:  *             Convert from a host to a port.
                    480:  *             Produces a naked send right which may be invalid.
                    481:  *     Conditions:
                    482:  *             Nothing locked.
                    483:  */
                    484: 
                    485: ipc_port_t
                    486: convert_host_to_port(
                    487:        host_t          host)
                    488: {
                    489:        ipc_port_t port;
                    490: 
                    491:        port = ipc_port_make_send(host->host_self);
                    492: 
                    493:        return port;
                    494: }
                    495: 
                    496: /*
                    497:  *     Routine:        convert_processor_to_port
                    498:  *     Purpose:
                    499:  *             Convert from a processor to a port.
                    500:  *             Produces a naked send right which may be invalid.
                    501:  *     Conditions:
                    502:  *             Nothing locked.
                    503:  */
                    504: 
                    505: ipc_port_t
                    506: convert_processor_to_port(
                    507:        processor_t             processor)
                    508: {
                    509:        ipc_port_t port;
                    510:        spl_t   s;
                    511: 
                    512:        s = splsched();
                    513:        processor_lock(processor);
                    514: 
                    515:        if (processor->processor_self != IP_NULL)
                    516:                port = ipc_port_make_send(processor->processor_self);
                    517:        else
                    518:                port = IP_NULL;
                    519: 
                    520:        processor_unlock(processor);
                    521:        splx(s);
                    522: 
                    523:        return port;
                    524: }
                    525: 
                    526: /*
                    527:  *     Routine:        convert_pset_to_port
                    528:  *     Purpose:
                    529:  *             Convert from a pset to a port.
                    530:  *             Consumes a pset ref; produces a naked send right
                    531:  *             which may be invalid.
                    532:  *     Conditions:
                    533:  *             Nothing locked.
                    534:  */
                    535: 
                    536: ipc_port_t
                    537: convert_pset_to_port(
                    538:        processor_set_t         pset)
                    539: {
                    540:        ipc_port_t port;
                    541: 
                    542:        pset_lock(pset);
                    543:        if (pset->active)
                    544:                port = ipc_port_make_send(pset->pset_self);
                    545:        else
                    546:                port = IP_NULL;
                    547:        pset_unlock(pset);
                    548: 
                    549:        pset_deallocate(pset);
                    550:        return port;
                    551: }
                    552: 
                    553: /*
                    554:  *     Routine:        convert_pset_name_to_port
                    555:  *     Purpose:
                    556:  *             Convert from a pset to a port.
                    557:  *             Consumes a pset ref; produces a naked send right
                    558:  *             which may be invalid.
                    559:  *     Conditions:
                    560:  *             Nothing locked.
                    561:  */
                    562: 
                    563: ipc_port_t
                    564: convert_pset_name_to_port(
                    565:        processor_set_name_t            pset)
                    566: {
                    567:        ipc_port_t port;
                    568: 
                    569:        pset_lock(pset);
                    570:        if (pset->active)
                    571:                port = ipc_port_make_send(pset->pset_name_self);
                    572:        else
                    573:                port = IP_NULL;
                    574:        pset_unlock(pset);
                    575: 
                    576:        pset_deallocate(pset);
                    577:        return port;
                    578: }
                    579: 
                    580: /*
                    581:  *     Routine:        convert_port_to_host_security
                    582:  *     Purpose:
                    583:  *             Convert from a port to a host security.
                    584:  *             Doesn't consume the port ref; the port produced may be null.
                    585:  *     Conditions:
                    586:  *             Nothing locked.
                    587:  */
                    588: 
                    589: host_t
                    590: convert_port_to_host_security(
                    591:        ipc_port_t port)
                    592: {
                    593:        host_t host = HOST_NULL;
                    594: 
                    595:        if (IP_VALID(port)) {
                    596:                ip_lock(port);
                    597:                if (ip_active(port) &&
                    598:                    (ip_kotype(port) == IKOT_HOST_SECURITY))
                    599:                        host = (host_t) port->ip_kobject;
                    600:                ip_unlock(port);
                    601:        }
                    602: 
                    603:        return host;
                    604: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.