Annotation of kernel/kern/ipc_host.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
        !             7:  * Reserved.  This file contains Original Code and/or Modifications of
        !             8:  * Original Code as defined in and that are subject to the Apple Public
        !             9:  * Source License Version 1.1 (the "License").  You may not use this file
        !            10:  * except in compliance with the License.  Please obtain a copy of the
        !            11:  * License at http://www.apple.com/publicsource and read it before using
        !            12:  * this file.
        !            13:  * 
        !            14:  * The Original Code and all software distributed under the License are
        !            15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            19:  * License for the specific language governing rights and limitations
        !            20:  * under the License.
        !            21:  * 
        !            22:  * @APPLE_LICENSE_HEADER_END@
        !            23:  */
        !            24: 
        !            25: /* 
        !            26:  * Mach Operating System
        !            27:  * Copyright (c) 1992,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:  *     kern/ipc_host.c
        !            53:  *
        !            54:  *     Routines to implement host ports.
        !            55:  */
        !            56: 
        !            57: #import <mach_ipc_compat.h>
        !            58: 
        !            59: #include <mach/message.h>
        !            60: #include <kern/host.h>
        !            61: #include <kern/processor.h>
        !            62: #include <kern/task.h>
        !            63: #include <kern/thread.h>
        !            64: #include <kern/ipc_host.h>
        !            65: #include <kern/ipc_kobject.h>
        !            66: #include <ipc/ipc_port.h>
        !            67: #include <ipc/ipc_space.h>
        !            68: 
        !            69: #include <machine/machspl.h>   /* for spl */
        !            70: 
        !            71: 
        !            72: 
        !            73: /*
        !            74:  *     ipc_host_init: set up various things.
        !            75:  */
        !            76: 
        !            77: void ipc_host_init(void)
        !            78: {
        !            79:        ipc_port_t      port;
        !            80:        /*
        !            81:         *      Allocate and set up the two host ports.
        !            82:         */
        !            83:        port = ipc_port_alloc_kernel();
        !            84:        if (port == IP_NULL)
        !            85:                panic("ipc_host_init");
        !            86: 
        !            87:        ipc_kobject_set(port, (ipc_kobject_t) &realhost, IKOT_HOST);
        !            88:        realhost.host_self = port;
        !            89: 
        !            90:        port = ipc_port_alloc_kernel();
        !            91:        if (port == IP_NULL)
        !            92:                panic("ipc_host_init");
        !            93: 
        !            94:        ipc_kobject_set(port, (ipc_kobject_t) &realhost, IKOT_HOST_PRIV);
        !            95:        realhost.host_priv_self = port;
        !            96: 
        !            97:        /*
        !            98:         *      Set up ipc for default processor set.
        !            99:         */
        !           100:        ipc_pset_init(&default_pset);
        !           101:        ipc_pset_enable(&default_pset);
        !           102: 
        !           103:        /*
        !           104:         *      And for master processor
        !           105:         */
        !           106:        ipc_processor_init(master_processor);
        !           107: }
        !           108: 
        !           109: /*
        !           110:  *     Routine:        mach_host_self [mach trap]
        !           111:  *     Purpose:
        !           112:  *             Give the caller send rights for his own host port.
        !           113:  *     Conditions:
        !           114:  *             Nothing locked.
        !           115:  *     Returns:
        !           116:  *             MACH_PORT_NULL if there are any resource failures
        !           117:  *             or other errors.
        !           118:  */
        !           119: 
        !           120: mach_port_t
        !           121: mach_host_self(void)
        !           122: {
        !           123:        ipc_port_t sright;
        !           124: 
        !           125:        sright = ipc_port_make_send(realhost.host_self);
        !           126:        return ipc_port_copyout_send(sright, current_space());
        !           127: }
        !           128: 
        !           129: #if    MACH_IPC_COMPAT
        !           130: 
        !           131: /*
        !           132:  *     Routine:        host_self [mach trap]
        !           133:  *     Purpose:
        !           134:  *             Give the caller send rights for his own host port.
        !           135:  *             If new, the send right is marked with IE_BITS_COMPAT.
        !           136:  *     Conditions:
        !           137:  *             Nothing locked.
        !           138:  *     Returns:
        !           139:  *             MACH_PORT_NULL if there are any resource failures
        !           140:  *             or other errors.
        !           141:  */
        !           142: 
        !           143: port_name_t
        !           144: host_self(void)
        !           145: {
        !           146:        ipc_port_t sright;
        !           147: 
        !           148:        sright = ipc_port_make_send(realhost.host_self);
        !           149:        return (port_name_t)
        !           150:                ipc_port_copyout_send_compat(sright, current_space());
        !           151: }
        !           152: 
        !           153: #endif MACH_IPC_COMPAT
        !           154: 
        !           155: /*
        !           156:  *     ipc_processor_init:
        !           157:  *
        !           158:  *     Initialize ipc access to processor by allocating port.
        !           159:  *     Enable ipc control of processor by setting port object.
        !           160:  */
        !           161: 
        !           162: void
        !           163: ipc_processor_init(
        !           164:        processor_t     processor)
        !           165: {
        !           166:        ipc_port_t      port;
        !           167: 
        !           168:        port = ipc_port_alloc_kernel();
        !           169:        if (port == IP_NULL)
        !           170:                panic("ipc_processor_init");
        !           171:        processor->processor_self = port;
        !           172:        ipc_kobject_set(port, (ipc_kobject_t) processor, IKOT_PROCESSOR);
        !           173: }
        !           174: 
        !           175: 
        !           176: /*
        !           177:  *     ipc_pset_init:
        !           178:  *
        !           179:  *     Initialize ipc control of a processor set by allocating its ports.
        !           180:  */
        !           181: 
        !           182: void
        !           183: ipc_pset_init(
        !           184:        processor_set_t pset)
        !           185: {
        !           186:        ipc_port_t      port;
        !           187: 
        !           188:        port = ipc_port_alloc_kernel();
        !           189:        if (port == IP_NULL)
        !           190:                panic("ipc_pset_init");
        !           191:        pset->pset_self = port;
        !           192: 
        !           193:        port = ipc_port_alloc_kernel();
        !           194:        if (port == IP_NULL)
        !           195:                panic("ipc_pset_init");
        !           196:        pset->pset_name_self = port;
        !           197: }
        !           198: 
        !           199: /*
        !           200:  *     ipc_pset_enable:
        !           201:  *
        !           202:  *     Enable ipc access to a processor set.
        !           203:  */
        !           204: void
        !           205: ipc_pset_enable(
        !           206:        processor_set_t pset)
        !           207: {
        !           208:        pset_lock(pset);
        !           209:        if (pset->active) {
        !           210:                ipc_kobject_set(pset->pset_self,
        !           211:                                (ipc_kobject_t) pset, IKOT_PSET);
        !           212:                ipc_kobject_set(pset->pset_name_self,
        !           213:                                (ipc_kobject_t) pset, IKOT_PSET_NAME);
        !           214:                pset_ref_lock(pset);
        !           215:                pset->ref_count += 2;
        !           216:                pset_ref_unlock(pset);
        !           217:        }
        !           218:        pset_unlock(pset);
        !           219: }
        !           220: 
        !           221: /*
        !           222:  *     ipc_pset_disable:
        !           223:  *
        !           224:  *     Disable ipc access to a processor set by clearing the port objects.
        !           225:  *     Caller must hold pset lock and a reference to the pset.  Ok to
        !           226:  *     just decrement pset reference count as a result.
        !           227:  */
        !           228: void
        !           229: ipc_pset_disable(
        !           230:        processor_set_t pset)
        !           231: {
        !           232:        ipc_kobject_set(pset->pset_self, IKO_NULL, IKOT_NONE);
        !           233:        ipc_kobject_set(pset->pset_name_self, IKO_NULL, IKOT_NONE);
        !           234: 
        !           235:        pset_ref_lock(pset);
        !           236:        pset->ref_count -= 2;
        !           237:        pset_ref_unlock(pset);
        !           238: }
        !           239: 
        !           240: /*
        !           241:  *     ipc_pset_terminate:
        !           242:  *
        !           243:  *     Processor set is dead.  Deallocate the ipc control structures.
        !           244:  */
        !           245: void
        !           246: ipc_pset_terminate(
        !           247:        processor_set_t pset)
        !           248: {
        !           249:        ipc_port_dealloc_kernel(pset->pset_self);
        !           250:        ipc_port_dealloc_kernel(pset->pset_name_self);
        !           251: }
        !           252: 
        !           253: /*
        !           254:  *     processor_set_default, processor_set_default_priv:
        !           255:  *
        !           256:  *     Return ports for manipulating default_processor set.  MiG code
        !           257:  *     differentiates between these two routines.
        !           258:  */
        !           259: kern_return_t
        !           260: processor_set_default(
        !           261:        host_t          host,
        !           262:        processor_set_t *pset)
        !           263: {
        !           264:        if (host == HOST_NULL)
        !           265:                return KERN_INVALID_ARGUMENT;
        !           266: 
        !           267:        *pset = &default_pset;
        !           268:        pset_reference(*pset);
        !           269:        return KERN_SUCCESS;
        !           270: }
        !           271: 
        !           272: kern_return_t
        !           273: xxx_processor_set_default_priv(
        !           274:        host_t          host,
        !           275:        processor_set_t *pset)
        !           276: {
        !           277:        if (host == HOST_NULL)
        !           278:                return KERN_INVALID_ARGUMENT;
        !           279: 
        !           280:        *pset = &default_pset;
        !           281:        pset_reference(*pset);
        !           282:        return KERN_SUCCESS;
        !           283: }
        !           284: 
        !           285: /*
        !           286:  *     Routine:        convert_port_to_host
        !           287:  *     Purpose:
        !           288:  *             Convert from a port to a host.
        !           289:  *             Doesn't consume the port ref; the host produced may be null.
        !           290:  *     Conditions:
        !           291:  *             Nothing locked.
        !           292:  */
        !           293: 
        !           294: host_t
        !           295: convert_port_to_host(ipc_port_t port)
        !           296: {
        !           297:        host_t host = HOST_NULL;
        !           298: 
        !           299:        if (IP_VALID(port)) {
        !           300:                ip_lock(port);
        !           301:                if (ip_active(port) &&
        !           302:                    ((ip_kotype(port) == IKOT_HOST) ||
        !           303:                     (ip_kotype(port) == IKOT_HOST_PRIV)))
        !           304:                        host = (host_t) port->ip_kobject;
        !           305:                ip_unlock(port);
        !           306:        }
        !           307: 
        !           308:        return host;
        !           309: }
        !           310: 
        !           311: /*
        !           312:  *     Routine:        convert_port_to_host_priv
        !           313:  *     Purpose:
        !           314:  *             Convert from a port to a host.
        !           315:  *             Doesn't consume the port ref; the host produced may be null.
        !           316:  *     Conditions:
        !           317:  *             Nothing locked.
        !           318:  */
        !           319: 
        !           320: host_t
        !           321: convert_port_to_host_priv(ipc_port_t port)
        !           322: {
        !           323:        host_t host = HOST_NULL;
        !           324: 
        !           325:        if (IP_VALID(port)) {
        !           326:                ip_lock(port);
        !           327:                if (ip_active(port) &&
        !           328:                    (ip_kotype(port) == IKOT_HOST_PRIV))
        !           329:                        host = (host_t) port->ip_kobject;
        !           330:                ip_unlock(port);
        !           331:        }
        !           332: 
        !           333:        return host;
        !           334: }
        !           335: 
        !           336: /*
        !           337:  *     Routine:        convert_port_to_processor
        !           338:  *     Purpose:
        !           339:  *             Convert from a port to a processor.
        !           340:  *             Doesn't consume the port ref;
        !           341:  *             the processor produced may be null.
        !           342:  *     Conditions:
        !           343:  *             Nothing locked.
        !           344:  */
        !           345: 
        !           346: processor_t
        !           347: convert_port_to_processor(ipc_port_t port)
        !           348: {
        !           349:        processor_t processor = PROCESSOR_NULL;
        !           350: 
        !           351:        if (IP_VALID(port)) {
        !           352:                ip_lock(port);
        !           353:                if (ip_active(port) &&
        !           354:                    (ip_kotype(port) == IKOT_PROCESSOR))
        !           355:                        processor = (processor_t) port->ip_kobject;
        !           356:                ip_unlock(port);
        !           357:        }
        !           358: 
        !           359:        return processor;
        !           360: }
        !           361: 
        !           362: /*
        !           363:  *     Routine:        convert_port_to_pset
        !           364:  *     Purpose:
        !           365:  *             Convert from a port to a pset.
        !           366:  *             Doesn't consume the port ref; produces a pset ref,
        !           367:  *             which may be null.
        !           368:  *     Conditions:
        !           369:  *             Nothing locked.
        !           370:  */
        !           371: 
        !           372: processor_set_t
        !           373: convert_port_to_pset(ipc_port_t port)
        !           374: {
        !           375:        processor_set_t pset = PROCESSOR_SET_NULL;
        !           376: 
        !           377:        if (IP_VALID(port)) {
        !           378:                ip_lock(port);
        !           379:                if (ip_active(port) &&
        !           380:                    (ip_kotype(port) == IKOT_PSET)) {
        !           381:                        pset = (processor_set_t) port->ip_kobject;
        !           382:                        pset_reference(pset);
        !           383:                }
        !           384:                ip_unlock(port);
        !           385:        }
        !           386: 
        !           387:        return pset;
        !           388: }
        !           389: 
        !           390: /*
        !           391:  *     Routine:        convert_port_to_pset_name
        !           392:  *     Purpose:
        !           393:  *             Convert from a port to a pset.
        !           394:  *             Doesn't consume the port ref; produces a pset ref,
        !           395:  *             which may be null.
        !           396:  *     Conditions:
        !           397:  *             Nothing locked.
        !           398:  */
        !           399: 
        !           400: processor_set_t
        !           401: convert_port_to_pset_name(ipc_port_t port)
        !           402: {
        !           403:        processor_set_t pset = PROCESSOR_SET_NULL;
        !           404: 
        !           405:        if (IP_VALID(port)) {
        !           406:                ip_lock(port);
        !           407:                if (ip_active(port) &&
        !           408:                    ((ip_kotype(port) == IKOT_PSET) ||
        !           409:                     (ip_kotype(port) == IKOT_PSET_NAME))) {
        !           410:                        pset = (processor_set_t) port->ip_kobject;
        !           411:                        pset_reference(pset);
        !           412:                }
        !           413:                ip_unlock(port);
        !           414:        }
        !           415: 
        !           416:        return pset;
        !           417: }
        !           418: 
        !           419: /*
        !           420:  *     Routine:        convert_host_to_port
        !           421:  *     Purpose:
        !           422:  *             Convert from a host to a port.
        !           423:  *             Produces a naked send right which is always valid.
        !           424:  *     Conditions:
        !           425:  *             Nothing locked.
        !           426:  */
        !           427: 
        !           428: ipc_port_t
        !           429: convert_host_to_port(host_t host)
        !           430: {
        !           431:        ipc_port_t port;
        !           432: 
        !           433:        port = ipc_port_make_send(host->host_self);
        !           434: 
        !           435:        return port;
        !           436: }
        !           437: 
        !           438: /*
        !           439:  *     Routine:        convert_processor_to_port
        !           440:  *     Purpose:
        !           441:  *             Convert from a processor to a port.
        !           442:  *             Produces a naked send right which is always valid.
        !           443:  *     Conditions:
        !           444:  *             Nothing locked.
        !           445:  */
        !           446: 
        !           447: ipc_port_t
        !           448: convert_processor_to_port(processor_t processor)
        !           449: {
        !           450:        ipc_port_t port;
        !           451: 
        !           452:        port = ipc_port_make_send(processor->processor_self);
        !           453: 
        !           454:        return port;
        !           455: }
        !           456: 
        !           457: /*
        !           458:  *     Routine:        convert_pset_to_port
        !           459:  *     Purpose:
        !           460:  *             Convert from a pset to a port.
        !           461:  *             Consumes a pset ref; produces a naked send right
        !           462:  *             which may be invalid.
        !           463:  *     Conditions:
        !           464:  *             Nothing locked.
        !           465:  */
        !           466: 
        !           467: ipc_port_t
        !           468: convert_pset_to_port(processor_set_t pset)
        !           469: {
        !           470:        ipc_port_t port;
        !           471: 
        !           472:        pset_lock(pset);
        !           473:        if (pset->active)
        !           474:                port = ipc_port_make_send(pset->pset_self);
        !           475:        else
        !           476:                port = IP_NULL;
        !           477:        pset_unlock(pset);
        !           478: 
        !           479:        pset_deallocate(pset);
        !           480:        return port;
        !           481: }
        !           482: 
        !           483: /*
        !           484:  *     Routine:        convert_pset_name_to_port
        !           485:  *     Purpose:
        !           486:  *             Convert from a pset to a port.
        !           487:  *             Consumes a pset ref; produces a naked send right
        !           488:  *             which may be invalid.
        !           489:  *     Conditions:
        !           490:  *             Nothing locked.
        !           491:  */
        !           492: 
        !           493: ipc_port_t
        !           494: convert_pset_name_to_port(processor_set_t pset)
        !           495: {
        !           496:        ipc_port_t port;
        !           497: 
        !           498:        pset_lock(pset);
        !           499:        if (pset->active)
        !           500:                port = ipc_port_make_send(pset->pset_name_self);
        !           501:        else
        !           502:                port = IP_NULL;
        !           503:        pset_unlock(pset);
        !           504: 
        !           505:        pset_deallocate(pset);
        !           506:        return port;
        !           507: }

unix.superglobalmegacorp.com

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