Annotation of kernel/kernserv/kern_server.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:  * Copyright (c) 1989 NeXT, Inc.
        !            27:  *
        !            28:  * HISTORY
        !            29:  *  4-Jun-91  Gregg Kellogg (gk) at NeXT
        !            30:  *     Abort server_thread before calling thread_dowait when trying to
        !            31:  *     service callouts.
        !            32:  *
        !            33:  * 27-Aug-90  Gregg Kellogg (gk) at NeXT
        !            34:  *     Fixed bugs in kern_serv_callout.
        !            35:  *     Remove compatibility for servers < version 2.
        !            36:  *
        !            37:  * 12-Jul-90  Gregg Kellogg (gk) at NeXT
        !            38:  *     Don't allocate MSG_SIZE_MAX for in and out messages.  Only allocate
        !            39:  *     a minimal amount fo input message and use RCV_TOO_LARGE logic
        !            40:  *     to allocate more.  Output message is only allocated for servers
        !            41:  *     and older style handlers.
        !            42:  *
        !            43:  * 23-May-90  Gregg kellogg (gk) at NeXT
        !            44:  *     Changed to use thread_reply port instead of bootstrap port.
        !            45:  *     Checks to see if it's running in the kernel_task and uses
        !            46:  *     kernel_ipc_space accordingly.
        !            47:  *     Terminates on shutdown, doesn't suspend.
        !            48:  *     Doesn't depend on being in a separate task now.
        !            49:  *
        !            50:  * 06-Feb-89  Gregg Kellogg (gk) at NeXT
        !            51:  *     Created.
        !            52:  *
        !            53:  */ 
        !            54: 
        !            55: /*
        !            56:  * Generic Kernel Server for loaded server tasks.
        !            57:  *
        !            58:  * This code is run by dynamically loaded Mach kernel servers.  It recieves
        !            59:  * instructions from it's boot port server to set up it's local environment
        !            60:  * and enter the server loop to do per-server processing.
        !            61:  *
        !            62:  * The server basically exists to dispatch messages recieved on ports
        !            63:  * to procedures.  Any un-handled messages are either thrown away or handled
        !            64:  * directly by the server.  Handled messages are either acked, or not acked.
        !            65:  * If the return status is > 0, then any resources passed (other than ports)
        !            66:  * are deallocated from the message as well.
        !            67:  */
        !            68: 
        !            69: #import <mach/mig_errors.h>
        !            70: #import <sys/callout.h>
        !            71: #import <mach/notify.h>
        !            72: #import <kern/kern_port.h>
        !            73: #import <kern/sched_prim.h>
        !            74: #import <mach/mach_traps.h>
        !            75: #import <kern/kalloc.h>
        !            76: #import <kernserv/kern_notify.h>
        !            77: #import <mach/vm_param.h>
        !            78: #import "kernobjc.h"
        !            79: #import <kern/thread_call.h>
        !            80: 
        !            81: #import <machine/spl.h>
        !            82: 
        !            83: #import <kernserv/kern_server_handler.h>
        !            84: #import <kernserv/kern_server_reply.h>
        !            85: 
        !            86: #define panic(s) (curipl() == 0 ? kern_serv_panic(ksp->bootstrap_port, s) \
        !            87:                                : printf("can't panic: %s\n", s))
        !            88: 
        !            89: /* Now a per server static port_t kernel_port; */
        !            90: 
        !            91: /*
        !            92:  * Use internal version of thread_terminate.
        !            93:  */
        !            94: #undef thread_terminate
        !            95: 
        !            96: /*
        !            97:  * Locally used functions
        !            98:  */
        !            99: static kern_return_t kern_serv_dispatch (
        !           100:        msg_header_t *in_msg,
        !           101:        kern_server_t ksp);
        !           102: 
        !           103: static void kern_serv_send_log(void *arg);
        !           104: static void kern_serv_log_init (       // initialize server's log buffer
        !           105:        log_t   *log,                   // uninitialized log struct
        !           106:        int     num_entries);           // size of log
        !           107: 
        !           108: static void kern_serv_log_free (log_t *log); // deallocate log structure
        !           109: static void kern_serv_interrupt_server(thread_t thread);
        !           110: 
        !           111: const kern_serv_t kern_serv_proto = {
        !           112:        0,              // arg to be filled in
        !           113:        0,              // don't wait for message to be sent
        !           114:        kern_serv_instance_loc,
        !           115:        kern_serv_boot_port,
        !           116:        kern_serv_wire_range,
        !           117:        kern_serv_unwire_range,
        !           118:        kern_serv_port_proc,
        !           119:        kern_serv_port_death_proc,
        !           120:        kern_serv_call_proc,
        !           121:        kern_serv_shutdown,
        !           122:        kern_serv_log_level,
        !           123:        kern_serv_get_log,
        !           124:        kern_serv_port_serv,
        !           125:        kern_serv_version,
        !           126:        kern_serv_load_objc};
        !           127: 
        !           128: /*
        !           129:  * Prototypes for kernel functions not yet prototyped.
        !           130:  */
        !           131: int bcopy(void *to, void *from, int size);
        !           132: int curipl(void);
        !           133: kern_return_t vm_map_pageable(
        !           134:        vm_map_t        map,
        !           135:        vm_offset_t     start,
        !           136:        vm_offset_t     end,
        !           137:        boolean_t       new_pageable);
        !           138: #if    DEBUG
        !           139: void xpr(char *msg, ...);
        !           140: #endif DEBUG
        !           141: 
        !           142: #if    DEBUG
        !           143: static boolean_t kserv_debug = TRUE;
        !           144: #define ks_log(s) {if (kserv_debug) XPR(XPR_LDD, s); }
        !           145: #define ks_log2(s) ks_log(s)
        !           146: void kern_server_main1(void);
        !           147: void kern_server_main2(void);
        !           148: #else  DEBUG
        !           149: #define ks_log(s)
        !           150: #define ks_log2(s)
        !           151: #endif DEBUG
        !           152: 
        !           153: /*
        !           154:  * Entry point to kernel server, set up task environment.
        !           155:  */
        !           156: void kern_server_main(void)
        !           157: {
        !           158: #if    DEBUG
        !           159:        int foo[10];
        !           160:        kern_server_main1();
        !           161: }
        !           162: void kern_server_main1(void)
        !           163: {
        !           164:        int foo[10];
        !           165:        kern_server_main2();
        !           166: }
        !           167: void kern_server_main2(void)
        !           168: {
        !           169: #endif DEBUG
        !           170:        kern_return_t   r;
        !           171:        kern_server_t   ksp = (kern_server_t)kalloc(sizeof *ksp);
        !           172:        port_t          boot_listener_port;
        !           173:        port_t          reply_port;
        !           174:        port_set_name_t port_set;
        !           175:        msg_header_t    *in_msg;
        !           176:        int             error;
        !           177:        register int    i, s;
        !           178:        kern_serv_t kern_serv = kern_serv_proto;
        !           179: 
        !           180: #if    0
        !           181:        volatile int instr;
        !           182: 
        !           183:        /*
        !           184:         * Write to the loaded text so that the debugger can set break-points.
        !           185:         */
        !           186:        instr = *(int *)&kern_server_main2;
        !           187:        *(int *)&kern_server_main2 = instr;
        !           188: #endif 0
        !           189: 
        !           190:        kern_serv.arg = (void *)&ksp;
        !           191: 
        !           192:        /*
        !           193:         *      Find out who we are.
        !           194:         */
        !           195: 
        !           196:        if (current_task() != kernel_task) {
        !           197:                current_task()->kernel_vm_space = TRUE;
        !           198:        }
        !           199: 
        !           200:        bzero((char *)ksp, sizeof(*ksp));
        !           201:        ksp->version = -1;
        !           202: 
        !           203:        /*
        !           204:         * Our task port.
        !           205:         */
        !           206:        ksp->task_port = task_self();
        !           207: 
        !           208:        /*
        !           209:         * Our thread structure.
        !           210:         */
        !           211:        ksp->server_thread = current_thread();
        !           212:        simple_lock_init(&ksp->slock);
        !           213: 
        !           214:        /*
        !           215:         * Initialize message send queue.
        !           216:         */
        !           217:        queue_init(&ksp->msg_callout_q);
        !           218:        queue_init(&ksp->msg_callout_fq);
        !           219:        queue_init(&ksp->notify_q);
        !           220:        for (  i = sizeof(ksp->msg_send_array)/sizeof(ksp->msg_send_array[0])-1
        !           221:             ; i >= 0
        !           222:             ; i--)
        !           223:        {
        !           224:                queue_enter(&ksp->msg_callout_fq, &ksp->msg_send_array[i],
        !           225:                        struct msg_send_entry *, link);
        !           226:        }
        !           227: 
        !           228:        /*
        !           229:         * Use our thread_reply port as the bootstrap port.  This is
        !           230:         * claimed by the kern_loader before we startup, so there's no
        !           231:         * race condition.
        !           232:         */
        !           233:        r = thread_get_special_port(thread_self(), THREAD_REPLY_PORT,
        !           234:                &boot_listener_port);
        !           235:        if (r != KERN_SUCCESS || boot_listener_port == PORT_NULL) {
        !           236:                printf("k_server: can't find listener port..terminating\n");
        !           237:                thread_terminate(current_thread());
        !           238:                thread_halt_self();
        !           239:        }
        !           240:        ksp->boot_listener_port = boot_listener_port;
        !           241: 
        !           242:        /*
        !           243:         * Allocate a new reply port.
        !           244:         */
        !           245:        r = port_allocate(task_self(), &reply_port);
        !           246:        if (r != KERN_SUCCESS) {
        !           247:                printf("k_server: can't allocate reply port..terminating\n");
        !           248:                thread_terminate(current_thread());
        !           249:                thread_halt_self();
        !           250:        }
        !           251:        
        !           252:        r = thread_set_special_port(thread_self(), THREAD_REPLY_PORT,
        !           253:                reply_port);
        !           254:        if (r != KERN_SUCCESS) {
        !           255:                printf("k_server: can't set reply port..terminating\n");
        !           256:                thread_terminate(current_thread());
        !           257:                thread_halt_self();
        !           258:        }
        !           259: 
        !           260:        /*
        !           261:         * Forget the reply_port we were using so that it isn't
        !           262:         * cached anymore.
        !           263:         */
        !           264: 
        !           265:        /*
        !           266:         * Allocate the basic set of ports we need for communication
        !           267:         * (notify port).
        !           268:         */
        !           269:        r = port_set_allocate(task_self(), &port_set);
        !           270:        if (r != KERN_SUCCESS) {
        !           271:                printf("k_server: can't allocate port set..terminating\n");
        !           272:                thread_terminate(current_thread());
        !           273:                thread_halt_self();
        !           274:        }
        !           275:        ksp->port_set = port_set;
        !           276: 
        !           277:        /*
        !           278:         * Add boot listener port to the port set.
        !           279:         */
        !           280:        if (   port_set_add(task_self(), port_set, boot_listener_port)
        !           281:            != KERN_SUCCESS)
        !           282:        {
        !           283:                printf("k_server: can't add listener port\n");
        !           284:                thread_terminate(current_thread());
        !           285:                thread_halt_self();
        !           286:        }
        !           287: 
        !           288:        /*
        !           289:         * Allocate and set up the notify port.
        !           290:         */
        !           291:        r = port_allocate(ksp->task_port, &ksp->notify_port);
        !           292:        if (r == KERN_SUCCESS)
        !           293:                (void) port_set_add(ksp->task_port, ksp->port_set,
        !           294:                        ksp->notify_port);
        !           295:        else
        !           296:                kern_serv_panic(ksp->bootstrap_port,
        !           297:                        "k_server: can't get notify port");
        !           298: 
        !           299:        if (current_task() != kernel_task) {
        !           300:                /*
        !           301:                 * Set this port as our task's notify port.
        !           302:                 */
        !           303:                (void) task_set_special_port(task_self(),
        !           304:                        TASK_NOTIFY_PORT, ksp->notify_port);
        !           305:        }
        !           306: 
        !           307:        kern_serv_notify(&ksp, ksp->notify_port, ksp->bootstrap_port);
        !           308: 
        !           309:        /*
        !           310:         * The kernel's task port.
        !           311:         */
        !           312:        ksp->kernel_port = kern_serv_kernel_task_port();
        !           313: 
        !           314:        /*
        !           315:         *      Service loop... receive messages and process them.
        !           316:         */
        !           317: 
        !           318:        in_msg = (msg_header_t *)kalloc(kern_servMaxRequestSize);
        !           319:        ksp->msg = in_msg;
        !           320:        ksp->msg_size = kern_servMaxRequestSize;
        !           321:        for (;;) {
        !           322:                /*
        !           323:                 * Look for things to do that need to be done
        !           324:                 * from this task/thread.
        !           325:                 * Send messages.
        !           326:                 */
        !           327:                s = splhigh();
        !           328:                simple_lock(&ksp->slock);
        !           329: 
        !           330:                while (!queue_empty(&ksp->msg_callout_q)) {
        !           331:                        struct msg_send_entry *msep;
        !           332: 
        !           333:                        queue_remove_first(&ksp->msg_callout_q,
        !           334:                                msep, struct msg_send_entry *, link);
        !           335: 
        !           336:                        simple_unlock(&ksp->slock);
        !           337:                        splx(s);
        !           338: 
        !           339:                        ks_log(("kern_server_main: qed callout func 0x%x\n",
        !           340:                                msep->func));
        !           341:                        (*msep->func)(msep->arg);
        !           342: 
        !           343:                        s = splhigh();
        !           344:                        simple_lock(&ksp->slock);
        !           345: 
        !           346:                        queue_enter(&ksp->msg_callout_fq, msep,
        !           347:                                struct msg_send_entry *, link);
        !           348:                }
        !           349: 
        !           350:                simple_unlock(&ksp->slock);
        !           351:                splx(s);
        !           352: 
        !           353:                /*
        !           354:                 * Wait for the next request.
        !           355:                 */
        !           356:            receive:
        !           357:                in_msg->msg_local_port = port_set;
        !           358:                in_msg->msg_size = ksp->msg_size;
        !           359:                r = msg_receive(in_msg, RCV_TIMEOUT|RCV_INTERRUPT|RCV_LARGE,
        !           360:                                1000);
        !           361: 
        !           362:                /*
        !           363:                 * If our receive was interrupted, go back to it.
        !           364:                 */
        !           365:                switch (r) {
        !           366:                case RCV_INTERRUPTED:
        !           367:                        break;
        !           368:                case RCV_TIMED_OUT:
        !           369:                        continue;
        !           370:                case RCV_TOO_LARGE:
        !           371:                {
        !           372:                        vm_size_t       new_msg_size = ksp->msg->msg_size;
        !           373:                        /*
        !           374:                         * We need to allocate a larger message to return.
        !           375:                         */
        !           376:                        kfree(ksp->msg, ksp->msg_size);
        !           377:                        ksp->msg_size = new_msg_size;
        !           378:                        ksp->msg = (void *)kalloc(ksp->msg_size);
        !           379:                        in_msg = ksp->msg;
        !           380:                        goto receive;
        !           381:                }
        !           382: 
        !           383:                case KERN_SUCCESS:
        !           384:                        break;
        !           385:                default:
        !           386:                        kern_serv_panic(ksp->bootstrap_port,
        !           387:                                "kern_server_main: received return bad return"
        !           388:                                " from msg_receive");
        !           389:                        break;
        !           390:                }
        !           391: 
        !           392:                ks_log(("kern_server_main: received msgid %d "
        !           393:                        "on port %d\n", in_msg->msg_id,
        !           394:                        in_msg->msg_local_port));
        !           395: 
        !           396:                /*
        !           397:                 * Dispatch the message based on it's port.
        !           398:                 */
        !           399:                if (in_msg->msg_local_port == ksp->notify_port) {
        !           400:                        notification_t  *n = (notification_t *) in_msg;
        !           401:                        switch(in_msg->msg_id) {
        !           402:                        case NOTIFY_PORT_DELETED:
        !           403:                                /*
        !           404:                                 * Give loaded code a chance to handle it
        !           405:                                 */
        !           406:                                if (ksp->pd_proc) {
        !           407:                                        if ((*ksp->pd_proc)(n->notify_port))
        !           408:                                                break;
        !           409:                                } else if (ksp->pn_proc)
        !           410:                                        (*ksp->pn_proc)(n->notify_port,
        !           411:                                                in_msg->msg_id);
        !           412:                                kern_serv_port_gone(&ksp, n->notify_port);
        !           413:                                break;
        !           414:                        default:
        !           415:                                if (ksp->pn_proc)
        !           416:                                        (*ksp->pn_proc)(n->notify_port,
        !           417:                                                        in_msg->msg_id);
        !           418:                                break;
        !           419:                        }
        !           420:                        continue;
        !           421:                } else if (   in_msg->msg_id >= NOTIFY_FIRST
        !           422:                           && in_msg->msg_id < NOTIFY_LAST)
        !           423:                {
        !           424:                        notification_t  *n = (notification_t *) in_msg;
        !           425:                        ks_notify_t *np;
        !           426: 
        !           427:                        /*
        !           428:                         * If we have a notify request on this port, forward
        !           429:                         * the message to the requested port.
        !           430:                         */
        !           431:                        for (  np = (ks_notify_t *)queue_first(&ksp->notify_q)
        !           432:                             ; !queue_end(&ksp->notify_q, (queue_entry_t)np)
        !           433:                             ; np = (ks_notify_t *)queue_next(&np->link))
        !           434:                                if (np->req_port == n->notify_port) {
        !           435:                                        in_msg->msg_remote_port =
        !           436:                                                np->reply_port;
        !           437:                                        ks_log2(("kern_server_main: "
        !           438:                                                 "forwarding notification "
        !           439:                                                 "request to port %d\n",
        !           440:                                                 np->reply_port));
        !           441:                                        msg_send(in_msg, MSG_OPTION_NONE, 0);
        !           442:                                        queue_remove(&ksp->notify_q, np,
        !           443:                                                ks_notify_t *, link);
        !           444:                                        kfree(np, sizeof(*np));
        !           445:                                        continue;
        !           446:                                }
        !           447:                }
        !           448: 
        !           449:                ksp->local_port = in_msg->msg_local_port;
        !           450: 
        !           451:                error = kern_serv_dispatch(in_msg, ksp);
        !           452:                ks_log2(("kern_server_main: return from ks_disp %d\n",
        !           453:                        error));
        !           454: 
        !           455:                if (   error == MIG_BAD_ID
        !           456:                    && in_msg->msg_local_port == boot_listener_port)
        !           457:                {
        !           458:                        error = kern_serv_handler(in_msg, &kern_serv);
        !           459:                        ks_log2(("kern_server_main: "
        !           460:                                "return from ks_server %d\n",
        !           461:                                error));
        !           462:                }
        !           463:        }
        !           464: }
        !           465: 
        !           466: typedef struct {
        !           467:        msg_header_t Head;
        !           468:        msg_type_t RetCodeType;
        !           469:        kern_return_t RetCode;
        !           470: } Reply;
        !           471: 
        !           472: static kern_return_t kern_serv_port_proc_call (
        !           473:        msg_header_t *in_msg,
        !           474:        port_proc_map_t *pp)
        !           475: {
        !           476:        Reply *out_msg;
        !           477:        kern_return_t ret_code;
        !           478:        port_t local_port;
        !           479: 
        !           480:        if (pp->type == PP_handler)
        !           481:                return (*pp->proc)(in_msg, pp->uarg);
        !           482: 
        !           483:        out_msg = (Reply *)kalloc(MSG_SIZE_MAX);
        !           484:        local_port = in_msg->msg_local_port;
        !           485:        in_msg->msg_local_port = (port_t)pp->uarg;
        !           486: 
        !           487:        (*((port_map_serv_t)pp->proc))(in_msg, (msg_header_t *)out_msg);
        !           488:        ret_code = out_msg->RetCode;
        !           489: 
        !           490:        if (out_msg->RetCode == MIG_NO_REPLY)
        !           491:                ret_code = KERN_SUCCESS;
        !           492:        else
        !           493:                ret_code = msg_send(&out_msg->Head, MSG_OPTION_NONE, 0);
        !           494: 
        !           495:        kfree(out_msg, MSG_SIZE_MAX);
        !           496: 
        !           497:        return ret_code;
        !           498: }
        !           499: 
        !           500: #define RCV_IN_PROGRESS                RCV_ERRORS_START
        !           501: /*
        !           502:  * Call a proc indirectly based on the port.
        !           503:  */
        !           504: static kern_return_t kern_serv_dispatch (
        !           505:        msg_header_t *in_msg,
        !           506:        kern_server_t ksp)
        !           507: {
        !           508:        int i = ksp->last_rec_index;
        !           509:        kern_return_t r = RCV_IN_PROGRESS;
        !           510: 
        !           511:        if (!ksp)
        !           512:                return MIG_BAD_ID;
        !           513: 
        !           514:        if (in_msg->msg_local_port == ksp->last_unrec_port) {
        !           515:                ks_log2(("kern_serv_dispatch: port %d was unrec\n",
        !           516:                        in_msg->msg_local_port));
        !           517:                r = MIG_BAD_ID;
        !           518:        } else if (in_msg->msg_local_port == ksp->last_rec_port) {
        !           519:                ks_log2(("kern_serv_dispatch: port %d was rec(%d), "
        !           520:                        "proc 0x%x(%d)\n",
        !           521:                        in_msg->msg_local_port, i, ksp->port_proc[i].proc,
        !           522:                        ksp->port_proc[i].uarg));
        !           523:                r = kern_serv_port_proc_call(in_msg, &ksp->port_proc[i]);
        !           524:        } else {
        !           525:                for (   i = 0
        !           526:                     ;    i < KERN_SERVER_NPORTPROC
        !           527:                       && ksp->port_proc[i].port != in_msg->msg_local_port
        !           528:                     ; i++)
        !           529:                        ;
        !           530: 
        !           531:                if (i != KERN_SERVER_NPORTPROC) {
        !           532:                        ksp->last_rec_port = in_msg->msg_local_port;
        !           533:                        ksp->last_rec_index = i;
        !           534:                        ks_log2(("kern_serv_dispatch: port %d now rec(%d), "
        !           535:                                "proc 0x%x(%d)\n",
        !           536:                                in_msg->msg_local_port, i,
        !           537:                                ksp->port_proc[i].proc,
        !           538:                                ksp->port_proc[i].uarg));
        !           539:                        r = kern_serv_port_proc_call(in_msg,
        !           540:                                &ksp->port_proc[i]);
        !           541:                }
        !           542:        }
        !           543: 
        !           544:        if (r == RCV_IN_PROGRESS) {
        !           545:                ks_log2(("kern_serv_dispatch: port %d now unrec\n",
        !           546:                        in_msg->msg_local_port));
        !           547:                ksp->last_unrec_port = in_msg->msg_local_port;
        !           548:                r = MIG_BAD_ID;
        !           549:        }
        !           550: 
        !           551:        return r;
        !           552: }
        !           553: 
        !           554: /*
        !           555:  * Got notification that port we have send rights on has gone away, clean up.
        !           556:  */
        !           557: void kern_serv_port_gone (
        !           558:        kern_server_t   *kspp,
        !           559:        port_name_t     port)
        !           560: {
        !           561:        kern_server_t   ksp = *kspp;
        !           562:        register int i;
        !           563: 
        !           564:        if (ksp == 0)
        !           565:                return;
        !           566: 
        !           567:        if (ksp->last_rec_port == port)
        !           568:                ksp->last_rec_port = PORT_NULL;
        !           569: 
        !           570:        /*
        !           571:         * If this is the log port, don't try to send anything to it.
        !           572:         */
        !           573:        if (ksp->log_port && port == ksp->log_port)
        !           574:                ksp->log_port == PORT_NULL;
        !           575:                
        !           576:        /*
        !           577:         * Free up port/proc pairs
        !           578:         */
        !           579:        for (i = 0; i < KERN_SERVER_NPORTPROC; i++)
        !           580:                if (ksp->port_proc[i].port == port) {
        !           581:                        ksp->port_proc[i].port = PORT_NULL;
        !           582:                        ksp->port_proc[i].proc = 0;
        !           583:                        break;
        !           584:                }
        !           585:        return;
        !           586: }
        !           587: 
        !           588: kern_return_t kern_serv_instance_loc (
        !           589:        void            *arg,
        !           590:        vm_address_t    instance_loc)
        !           591: {
        !           592:        kern_server_t ksp = *((kern_server_t *)arg);
        !           593:        kern_server_t *kspp = (kern_server_t *)instance_loc;
        !           594: 
        !           595:        ks_log(("kern_serv_instance_loc: 0x%x\n", instance_loc));
        !           596:        *kspp = ksp;
        !           597: 
        !           598:        return KERN_SUCCESS;
        !           599: }
        !           600: 
        !           601: /*
        !           602:  * Specify user's version of system user compiled with.
        !           603:  */
        !           604: kern_return_t kern_serv_version (
        !           605:        void            *arg,
        !           606:        int             version)
        !           607: {
        !           608:        kern_server_t ksp = *((kern_server_t *)arg);
        !           609: 
        !           610:        if (version < KS_COMPAT)
        !           611:                return KERN_SERVER_BAD_VERSION;
        !           612:        ksp->version = version;
        !           613: 
        !           614:        return KERN_SUCCESS;
        !           615: }
        !           616: kern_return_t kern_serv_load_objc(
        !           617:        void            *arg,
        !           618:        vm_address_t    header)
        !           619: {
        !           620:        kern_server_t ksp = *((kern_server_t *)arg);
        !           621:        int             error;
        !           622: 
        !           623: #if    KERNOBJC
        !           624:        ksp->mach_header = (struct mach_header *) header;
        !           625:        error = objc_registerModule (ksp->mach_header, 0);
        !           626: #endif KERNOBJC
        !           627:        return KERN_SUCCESS;
        !           628: }
        !           629: 
        !           630:                                  
        !           631: kern_return_t kern_serv_boot_port (    // how to talk to loader
        !           632:        void            *arg,
        !           633:        port_t          boot_port)
        !           634: {
        !           635:        kern_server_t ksp = *((kern_server_t *)arg);
        !           636: 
        !           637:        ksp->bootstrap_port = boot_port;
        !           638:        return KERN_SUCCESS;
        !           639: }
        !           640: 
        !           641: /*
        !           642:  * Kernel version of kern_serv_notify, doesn't contact kern_loader, uses
        !           643:  * internal port_request_notification facility.
        !           644:  */
        !           645: kern_return_t kern_serv_notify (
        !           646:        kern_server_t   *kspp,
        !           647:        port_t          reply_port,
        !           648:        port_t          req_port)
        !           649: {
        !           650:        kern_server_t ksp;
        !           651:        port_t  bootstrap_port;
        !           652:        kern_return_t r;
        !           653:        kern_port_t rp, np;
        !           654: 
        !           655:        ksp = *kspp;
        !           656:        bootstrap_port = ksp->bootstrap_port;
        !           657: 
        !           658:        if (current_task() != kernel_task) {
        !           659:                ks_notify_t *np;
        !           660: 
        !           661:                if (reply_port == ksp->notify_port)
        !           662:                        /*
        !           663:                         * Notification will happen automatically.
        !           664:                         */
        !           665:                        return KERN_SUCCESS;
        !           666: 
        !           667:                /*
        !           668:                 * Make sure that an entry doesn't already exist for this
        !           669:                 * pair.
        !           670:                 */
        !           671:                for (  np = (ks_notify_t *)queue_first(&ksp->notify_q)
        !           672:                     ; !queue_end(&ksp->notify_q, (queue_entry_t)np)
        !           673:                     ; np = (ks_notify_t *)queue_next(&np->link))
        !           674:                        if (   np->reply_port == reply_port
        !           675:                            && np->req_port == req_port)
        !           676:                                return KERN_FAILURE;
        !           677: 
        !           678:                np = (kern_port_t)kalloc(sizeof *np);
        !           679:                np->reply_port = reply_port;
        !           680:                np->req_port = req_port;
        !           681:                queue_enter(&ksp->notify_q, np, ks_notify_t *, link);
        !           682: 
        !           683:                /*
        !           684:                 * Notification will be forwarded from kern_server.
        !           685:                 */
        !           686:                return KERN_SUCCESS;
        !           687:        }
        !           688: 
        !           689:        r = get_kern_port(current_task(), req_port, &rp);
        !           690:        if (r != KERN_SUCCESS)
        !           691:                return r;
        !           692:        r = get_kern_port(current_task(), reply_port, &np);
        !           693:        if (r != KERN_SUCCESS)
        !           694:                return r;
        !           695:        port_request_notification(rp, np);
        !           696:        return KERN_SUCCESS;
        !           697: }
        !           698: 
        !           699: kern_return_t kern_serv_wire_range (   // wire the specified range or memory
        !           700:        void            *arg,
        !           701:        vm_address_t    addr,
        !           702:        vm_size_t       size)
        !           703: {
        !           704:        kern_server_t ksp = *((kern_server_t *)arg);
        !           705: 
        !           706:        ks_log(("kern_serv_wire_range: addr 0x%x for 0x%x bytes\n",
        !           707:                addr, size));
        !           708: #if    DIAGNOSTIC
        !           709:        printf("kern_server: wiring 0x%x to 0x%x\n", trunc_page(addr),
        !           710:                round_page(addr+size));
        !           711: #endif
        !           712:        return vm_map_pageable(kernel_task->map, trunc_page(addr),
        !           713:                round_page(addr+size), FALSE);
        !           714: }
        !           715: 
        !           716: kern_return_t kern_serv_unwire_range ( // unwire the specified range or memory
        !           717:        void            *arg,
        !           718:        vm_address_t    addr,
        !           719:        vm_size_t       size)
        !           720: {
        !           721:        kern_server_t ksp = *((kern_server_t *)arg);
        !           722: 
        !           723:        ks_log(("kern_serv_unwire_range: addr 0x%x for 0x%x bytes\n",
        !           724:                addr, size));
        !           725: #if    DIAGNOSTIC
        !           726:        printf("kern_server: unwiring 0x%x to 0x%x\n", trunc_page(addr),
        !           727:                round_page(addr+size));
        !           728: #endif
        !           729:        return vm_map_pageable(kernel_task->map, trunc_page(addr),
        !           730:                round_page(addr+size), TRUE);
        !           731: }
        !           732: 
        !           733: /*
        !           734:  * Map messages coming on on the specified port to call the specified proc.
        !           735:  * If this mapping can't be made FALSE is returned.
        !           736:  * The port is added to the portset for this server.
        !           737:  */
        !           738: kern_return_t kern_serv_port_proc (    // map a message on port to proc/arg
        !           739:        void            *arg,           // record into structure
        !           740:        port_all_t      port,           // port to map (all rights passed)
        !           741:        port_map_proc_t proc,           // proc to call
        !           742:        int             uarg)           // replace local_port with uarg
        !           743: {
        !           744:        register int i;
        !           745:        kern_return_t r;
        !           746:        kern_server_t ksp = *((kern_server_t *)arg);
        !           747: 
        !           748:        ks_log(("kern_serv_port_proc: port %d proc 0x%x uarg %d\n",
        !           749:                port, proc, uarg));
        !           750: 
        !           751:        if (ksp->last_unrec_port == port)
        !           752:                ksp->last_unrec_port = PORT_NULL;
        !           753: 
        !           754:        for (i = 0; i < KERN_SERVER_NPORTPROC; i++)
        !           755:                if (ksp->port_proc[i].port == port)
        !           756:                        ksp->port_proc[i].port = PORT_NULL;
        !           757: 
        !           758:        for (i = 0; i < KERN_SERVER_NPORTPROC; i++)
        !           759:                if (ksp->port_proc[i].port == PORT_NULL)
        !           760:                        break;
        !           761: 
        !           762:        r = KERN_RESOURCE_SHORTAGE;
        !           763:        if (   i == KERN_SERVER_NPORTPROC
        !           764:            || (r = port_set_add(ksp->task_port, ksp->port_set, port))
        !           765:                != KERN_SUCCESS)
        !           766:                return r;
        !           767: 
        !           768:        ksp->port_proc[i].port = port;
        !           769:        ksp->port_proc[i].proc = proc;
        !           770:        ksp->port_proc[i].uarg = (void *)uarg;
        !           771:        ksp->port_proc[i].type = PP_handler;
        !           772: 
        !           773:        return KERN_SUCCESS;
        !           774: }
        !           775: 
        !           776: /*
        !           777:  * Map messages coming on on the specified port to call the specified proc.
        !           778:  * If this mapping can't be made FALSE is returned.
        !           779:  * The port is added to the portset for this server.
        !           780:  */
        !           781: kern_return_t kern_serv_port_serv (    // map a message on port to proc/arg
        !           782:        void            *arg,           // record into structure
        !           783:        port_all_t      port,           // port to map (all rights passed)
        !           784:        port_map_proc_t proc,           // proc to call
        !           785:        int             uarg)           // replace local_port with uarg
        !           786: {
        !           787:        register int i;
        !           788:        kern_return_t r;
        !           789:        kern_server_t ksp = *((kern_server_t *)arg);
        !           790: 
        !           791:        ks_log(("kern_serv_port_serv: port %d proc 0x%x uarg %d\n",
        !           792:                port, proc, uarg));
        !           793: 
        !           794:        if (ksp->last_unrec_port == port)
        !           795:                ksp->last_unrec_port = PORT_NULL;
        !           796: 
        !           797:        for (i = 0; i < KERN_SERVER_NPORTPROC; i++)
        !           798:                if (ksp->port_proc[i].port == port)
        !           799:                        ksp->port_proc[i].port = PORT_NULL;
        !           800: 
        !           801:        for (i = 0; i < KERN_SERVER_NPORTPROC; i++)
        !           802:                if (ksp->port_proc[i].port == PORT_NULL)
        !           803:                        break;
        !           804: 
        !           805:        r = KERN_RESOURCE_SHORTAGE;
        !           806:        if (   i == KERN_SERVER_NPORTPROC
        !           807:            || (r = port_set_add(ksp->task_port, ksp->port_set, port))
        !           808:                != KERN_SUCCESS)
        !           809:                return r;
        !           810: 
        !           811:        ksp->port_proc[i].port = port;
        !           812:        ksp->port_proc[i].proc = proc;
        !           813:        ksp->port_proc[i].uarg = (void *)uarg;
        !           814:        ksp->port_proc[i].type = PP_server;
        !           815: 
        !           816:        return KERN_SUCCESS;
        !           817: }
        !           818: 
        !           819: kern_return_t kern_serv_port_death_proc ( // specify port death handler
        !           820:        void                    *arg,   // record into structure
        !           821:        port_death_proc_t       proc)   // record into structure
        !           822: {
        !           823:        kern_server_t ksp = *((kern_server_t *)arg);
        !           824: 
        !           825:        ksp->pd_proc = proc;
        !           826:        return KERN_SUCCESS;
        !           827: }
        !           828: 
        !           829: kern_return_t kern_serv_call_proc (    // call procedure with argument
        !           830:        void            *arg,           // record into structure
        !           831:        call_proc_t     proc,           // record into structure
        !           832:        int             uarg)           // arg to supply
        !           833: {
        !           834:        kern_server_t ksp = *((kern_server_t *)arg);
        !           835: 
        !           836:        ks_log(("kern_serv_call_proc: proc 0x%x uarg %d\n",
        !           837:                proc, uarg));
        !           838: 
        !           839:        if (proc) {
        !           840:                (*proc)(uarg);
        !           841:                return KERN_SUCCESS;
        !           842:        }
        !           843:        return KERN_SERVER_ERROR;
        !           844: }
        !           845: 
        !           846: kern_return_t kern_serv_shutdown (
        !           847:        void            *arg)
        !           848: {
        !           849:        kern_server_t ksp = *((kern_server_t *)arg);
        !           850:        int i;
        !           851: 
        !           852:        ks_log(("kern_serv_shutdown\n"));
        !           853: 
        !           854: #if    KERNOBJC
        !           855:        /*
        !           856:         * Detach from Objective-C runtime.
        !           857:         */
        !           858:        if (ksp->mach_header)
        !           859:                objc_unregisterModule (ksp->mach_header, 0);
        !           860: #endif KERNOBJC
        !           861: 
        !           862:        /*
        !           863:         * Stop logging and free the data
        !           864:         * if we were logging.
        !           865:         */
        !           866:        if (ksp->log.level) {
        !           867:                kern_serv_log_free(&ksp->log);
        !           868:                ksp->log.level = 0;
        !           869:        }
        !           870: 
        !           871:        /*
        !           872:         * Deallocate all the port mappings we have.
        !           873:         */
        !           874:        for (i = 0; i < KERN_SERVER_NPORTPROC; i++)
        !           875:                if (ksp->port_proc[i].port != PORT_NULL) {
        !           876:                        port_deallocate(ksp->task_port,
        !           877:                                ksp->port_proc[i].port);
        !           878:                        ksp->port_proc[i].port = PORT_NULL;
        !           879:                        ksp->port_proc[i].proc = 0;
        !           880:                }
        !           881: 
        !           882:        /*
        !           883:         * Deallocate our boot_listener and notify ports.
        !           884:         */
        !           885:        port_deallocate(ksp->task_port, ksp->boot_listener_port);
        !           886:        port_deallocate(ksp->task_port, ksp->notify_port);
        !           887: 
        !           888:        /*
        !           889:         * Deallocate our port_set
        !           890:         */
        !           891:        port_set_deallocate(ksp->task_port, ksp->port_set);
        !           892: 
        !           893:        /*
        !           894:         * Deallocate our message frame.
        !           895:         */
        !           896:        kfree(ksp->msg, ksp->msg_size);
        !           897:        kfree(ksp, sizeof *ksp);
        !           898:        thread_terminate(current_thread());
        !           899:        while (1)
        !           900:                /*
        !           901:                 * Wait to be killed.
        !           902:                 */
        !           903:                thread_halt_self();
        !           904: 
        !           905:        return KERN_SUCCESS;
        !           906: }
        !           907: 
        !           908: // log level from message on port
        !           909: kern_return_t kern_serv_log_level (
        !           910:        void            *arg,
        !           911:        int             log_level)
        !           912: {
        !           913:        kern_server_t ksp = *((kern_server_t *)arg);
        !           914:        int old_level = ksp->log.level;
        !           915: 
        !           916:        ksp->log.level = log_level;
        !           917: 
        !           918:        /*
        !           919:         * Only keep space around for the log
        !           920:         * if we need it.
        !           921:         */
        !           922:        if (old_level == 0 && ksp->log.level)
        !           923:                kern_serv_log_init(&ksp->log,
        !           924:                        KERN_SERVER_LOG_SIZE);
        !           925:        else if (ksp->log.level == 0 && old_level)
        !           926:                kern_serv_log_free(&ksp->log);
        !           927: 
        !           928:        return KERN_SUCCESS;
        !           929: }
        !           930: 
        !           931: kern_return_t kern_serv_get_log (
        !           932:        void            *arg,
        !           933:        port_t          reply_port)     // port to send log information to
        !           934: {
        !           935:        int s, n;
        !           936:        kern_server_t ksp = *((kern_server_t *)arg);
        !           937: 
        !           938:        if (ksp->log.level == 0) {
        !           939:                port_deallocate(ksp->task_port, reply_port);
        !           940:                return KERN_SERVER_NOTLOGGING;
        !           941:        }
        !           942: 
        !           943:        if (ksp->log.ptr == ksp->log.base) {
        !           944:                ksp->log_port = reply_port;
        !           945:                return KERN_SUCCESS;
        !           946:        } else {
        !           947:                vm_size_t size =
        !           948:                    round_page((char *)ksp->log.ptr - (char *)ksp->log.base);
        !           949:                pointer_t ldata;
        !           950:                unsigned int ldata_count;
        !           951:                kern_return_t r;
        !           952: 
        !           953:                ASSERT(    (void *)ksp->log.base
        !           954:                        == (void *)round_page(ksp->log.base));
        !           955:                r = vm_read(ksp->kernel_port,
        !           956:                        (vm_address_t)ksp->log.base, size, &ldata,
        !           957:                        &ldata_count);
        !           958:                ASSERT(r == KERN_SUCCESS);
        !           959:                kern_serv_log_data(reply_port,
        !           960:                        (log_entry_t *)ldata,
        !           961:                        ksp->log.ptr - ksp->log.base);
        !           962: 
        !           963:                port_deallocate(ksp->task_port, reply_port);
        !           964:                vm_deallocate(ksp->task_port, ldata, size);
        !           965:        }
        !           966: 
        !           967:        s = splhigh();
        !           968:        simple_lock(&ksp->slock);
        !           969:        ksp->log.ptr = ksp->log.base;
        !           970:        simple_unlock(&ksp->slock);
        !           971:        splx(s);
        !           972: 
        !           973:        return KERN_SUCCESS;
        !           974: }
        !           975: 
        !           976: void kern_serv_log (                   // log a message
        !           977:        kern_server_t   *kspp,          // kern_server instance vars
        !           978:        int             log_level,      // level to log at
        !           979:        char            *msg,           // what to log (followed by args)
        !           980:        int             arg1,
        !           981:        int             arg2,
        !           982:        int             arg3,
        !           983:        int             arg4,
        !           984:        int             arg5)
        !           985: {
        !           986:        kern_server_t ksp = *kspp;
        !           987:        register int s;
        !           988:        log_entry_t *x;
        !           989: 
        !           990:        if (log_level > ksp->log.level || ksp->log.base == 0)
        !           991:                return;
        !           992: 
        !           993:        s = splhigh();
        !           994:        simple_lock(&ksp->slock);
        !           995: 
        !           996:        x = ksp->log.ptr++;
        !           997:        if (ksp->log.ptr == ksp->log.last) {
        !           998:                ksp->log.ptr--;
        !           999:                simple_unlock(&ksp->slock);
        !          1000:                splx(s);
        !          1001:                return;
        !          1002:        }
        !          1003:        simple_unlock(&ksp->slock);
        !          1004:        splx(s);
        !          1005: 
        !          1006:        x->msg = msg;
        !          1007:        x->arg1 = arg1;
        !          1008:        x->arg2 = arg2;
        !          1009:        x->arg3 = arg3;
        !          1010:        x->arg4 = arg4;
        !          1011:        x->arg5 = arg5;
        !          1012:        x->timestamp = XPR_TIMESTAMP;
        !          1013:        x->cpuinfo = log_level;
        !          1014: 
        !          1015:        if (ksp->log_port)
        !          1016:                kern_serv_callout(kspp, kern_serv_send_log, (void *)ksp);
        !          1017: }
        !          1018: 
        !          1019: /*
        !          1020:  * Send the log back to the user.  Have to copy the log into our address
        !          1021:  * space.
        !          1022:  */
        !          1023: static void kern_serv_send_log(void *arg)
        !          1024: {
        !          1025:        kern_server_t ksp = (kern_server_t)arg;
        !          1026:        port_name_t log_port;
        !          1027:        int s;
        !          1028:        vm_size_t size =
        !          1029:                round_page((char *)ksp->log.ptr - (char *)ksp->log.base);
        !          1030:        pointer_t ldata;
        !          1031:        unsigned int ldata_count;
        !          1032:        kern_return_t r;
        !          1033: 
        !          1034:        s = splhigh();
        !          1035:        simple_lock(&ksp->slock);
        !          1036: 
        !          1037:        log_port = ksp->log_port;
        !          1038:        ksp->log_port = PORT_NULL;
        !          1039: 
        !          1040:        simple_unlock(&ksp->slock);
        !          1041:        splx(s);
        !          1042:        if (log_port == PORT_NULL)
        !          1043:                return;
        !          1044: 
        !          1045:        ASSERT((void *)ksp->log.base == (void *)round_page(ksp->log.base));
        !          1046:        r = vm_read(ksp->kernel_port, (vm_address_t)ksp->log.base,
        !          1047:                size, &ldata, &ldata_count);
        !          1048:        ASSERT(r == KERN_SUCCESS);
        !          1049:        kern_serv_log_data(log_port, (log_entry_t *)ldata,
        !          1050:                ksp->log.ptr - ksp->log.base);
        !          1051: 
        !          1052:        port_deallocate(ksp->task_port, log_port);
        !          1053:        vm_deallocate(ksp->task_port, ldata, size);
        !          1054: 
        !          1055:        s = splhigh();
        !          1056:        simple_lock(&ksp->slock);
        !          1057: 
        !          1058:        ksp->log.ptr = ksp->log.base;
        !          1059: 
        !          1060:        simple_unlock(&ksp->slock);
        !          1061:        splx(s);
        !          1062: 
        !          1063: }
        !          1064: 
        !          1065: /*
        !          1066:  * Ensure that the number of entries is rounded up to a page boundary.
        !          1067:  */
        !          1068: static void kern_serv_log_init (       // initialize server's log buffer
        !          1069:        log_t   *log,                   // uninitialized log struct
        !          1070:        int     num_entries)            // size of log
        !          1071: {
        !          1072:        vm_size_t size = round_page(sizeof(log_entry_t)*num_entries);
        !          1073:        num_entries = size / sizeof(log_entry_t);
        !          1074: 
        !          1075:        log->base = (log_entry_t *)kalloc(size);
        !          1076: 
        !          1077:        log->last = log->base + num_entries;
        !          1078:        log->ptr = log->base;
        !          1079: #if    DIAGNOSTIC
        !          1080:        printf("kern_serv_log_init: log 0x%x log.last 0x%x, log.base 0x%x\n",
        !          1081:                log, log->last, log->base);
        !          1082: #endif 
        !          1083: }
        !          1084: 
        !          1085: static void kern_serv_log_free (log_t *log) // deallocate log structure
        !          1086: {
        !          1087:        kfree(log->base, round_page((char *)log->last - (char *)log->base));
        !          1088:        log->base = log->last = log->ptr = 0;
        !          1089: }
        !          1090: 
        !          1091: kern_return_t kern_serv_callout (
        !          1092:        kern_server_t   *kspp,
        !          1093:        void            (*proc)(void *arg),
        !          1094:        void *          arg)
        !          1095: {
        !          1096:        kern_server_t ksp = *kspp;
        !          1097:        struct msg_send_entry *msep;
        !          1098:        int s;
        !          1099: 
        !          1100:        /*
        !          1101:         * Just call this guy directly if the conditions are right.
        !          1102:         */
        !          1103:        if (
        !          1104:            curipl() == 0
        !          1105:            && task_self() == ksp->task_port) {
        !          1106:                (*proc)(arg);
        !          1107:                return KERN_SUCCESS;
        !          1108:        }
        !          1109: 
        !          1110:        s = splhigh();
        !          1111:        simple_lock(&ksp->slock);
        !          1112: 
        !          1113:        if (queue_empty(&ksp->msg_callout_fq)) {
        !          1114: #if    DIAGNOSTIC
        !          1115:                printf("kern_serv_callout: no free messages");
        !          1116: #endif
        !          1117:                simple_unlock(&ksp->slock);
        !          1118:                splx(s);
        !          1119:                return KERN_RESOURCE_SHORTAGE;
        !          1120:        }
        !          1121: 
        !          1122:        queue_remove_first(&ksp->msg_callout_fq, msep, struct msg_send_entry *,
        !          1123:                link);
        !          1124:        ks_log(("kern_serv_send: (queue) proc 0x%x\n", proc));
        !          1125: 
        !          1126:        msep->func = proc;
        !          1127:        msep->arg = arg;
        !          1128:        queue_enter(&ksp->msg_callout_q, msep, struct msg_send_entry *, link);
        !          1129: 
        !          1130:        simple_unlock(&ksp->slock);
        !          1131:        splx(s);
        !          1132: 
        !          1133:        /*
        !          1134:         * Interrupt the server thread to that it'll look at this sucker.
        !          1135:         */
        !          1136:        thread_call_func(
        !          1137:                (thread_call_func_t)kern_serv_interrupt_server,
        !          1138:                (thread_call_spec_t)ksp->server_thread, TRUE);
        !          1139: 
        !          1140:        return KERN_SUCCESS;
        !          1141: }
        !          1142: 
        !          1143: static void kern_serv_interrupt_server(thread_t thread)
        !          1144: {
        !          1145:        /*
        !          1146:         * Sending the guy a message sounds like the best way to ensure
        !          1147:         * that he see's that there's something to do.
        !          1148:         */
        !          1149:        send_notification(thread->task, NOTIFY_MSG_ACCEPTED, PORT_NULL);
        !          1150: }
        !          1151: 
        !          1152: /*
        !          1153:  * Structure access functions.
        !          1154:  */
        !          1155: port_t kern_serv_local_port(kern_server_t *ksp)
        !          1156: {
        !          1157:        return (*ksp)->local_port;
        !          1158: }
        !          1159: 
        !          1160: port_t kern_serv_bootstrap_port(kern_server_t *ksp)
        !          1161: {
        !          1162:        return (*ksp)->bootstrap_port;
        !          1163: }
        !          1164: 
        !          1165: port_t kern_serv_notify_port(kern_server_t *ksp)
        !          1166: {
        !          1167:        return (*ksp)->notify_port;
        !          1168: }
        !          1169: 
        !          1170: port_set_name_t kern_serv_port_set(kern_server_t *ksp)
        !          1171: {
        !          1172:        return (*ksp)->port_set;
        !          1173: }
        !          1174: 
        !          1175: /* Get the kernel task port. */
        !          1176: port_t kern_serv_kernel_task_port(void)
        !          1177: {
        !          1178:        extern task_t kernel_task;      // global kernel variable.
        !          1179:        port_t my_kernel_port;
        !          1180: 
        !          1181:        task_reference(kernel_task);
        !          1182:        my_kernel_port = convert_task_to_port(kernel_task);
        !          1183:        if (my_kernel_port == PORT_NULL)
        !          1184:                return PORT_NULL;
        !          1185: 
        !          1186:        object_copyout(current_task(), my_kernel_port, MSG_TYPE_PORT,
        !          1187:                &my_kernel_port);
        !          1188:        return my_kernel_port;
        !          1189: }

unix.superglobalmegacorp.com

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