Annotation of kernel/ipc/ipc_kmsg.h, revision 1.1.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) 1995, 1994, 1993, 1992, 1991, 1990  
                     27:  * Open Software Foundation, Inc. 
                     28:  *  
                     29:  * Permission to use, copy, modify, and distribute this software and 
                     30:  * its documentation for any purpose and without fee is hereby granted, 
                     31:  * provided that the above copyright notice appears in all copies and 
                     32:  * that both the copyright notice and this permission notice appear in 
                     33:  * supporting documentation, and that the name of ("OSF") or Open Software 
                     34:  * Foundation not be used in advertising or publicity pertaining to 
                     35:  * distribution of the software without specific, written prior permission. 
                     36:  *  
                     37:  * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
                     38:  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
                     39:  * FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL OSF BE LIABLE FOR ANY 
                     40:  * SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 
                     41:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 
                     42:  * ACTION OF CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING 
                     43:  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE 
                     44:  */
                     45: /*
                     46:  * OSF Research Institute MK6.1 (unencumbered) 1/31/1995
                     47:  */
                     48: /* 
                     49:  * Mach Operating System
                     50:  * Copyright (c) 1991,1990,1989 Carnegie Mellon University
                     51:  * All Rights Reserved.
                     52:  * 
                     53:  * Permission to use, copy, modify and distribute this software and its
                     54:  * documentation is hereby granted, provided that both the copyright
                     55:  * notice and this permission notice appear in all copies of the
                     56:  * software, derivative works or modified versions, and any portions
                     57:  * thereof, and that both notices appear in supporting documentation.
                     58:  * 
                     59:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     60:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     61:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     62:  * 
                     63:  * Carnegie Mellon requests users of this software to return to
                     64:  * 
                     65:  *  Software Distribution Coordinator  or  [email protected]
                     66:  *  School of Computer Science
                     67:  *  Carnegie Mellon University
                     68:  *  Pittsburgh PA 15213-3890
                     69:  * 
                     70:  * any improvements or extensions that they make and grant Carnegie Mellon
                     71:  * the rights to redistribute these changes.
                     72:  */
                     73: /*
                     74:  *     File:   ipc/ipc_kmsg.h
                     75:  *     Author: Rich Draves
                     76:  *     Date:   1989
                     77:  *
                     78:  *     Definitions for kernel messages.
                     79:  */
                     80: 
                     81: #ifndef        _IPC_IPC_KMSG_H_
                     82: #define _IPC_IPC_KMSG_H_
                     83: 
                     84: #import <mach/features.h>
                     85: 
                     86: #include <mach/machine/vm_types.h>
                     87: #include <mach/message.h>
                     88: #include <kern/assert.h>
                     89: #include <kern/cpu_number.h>
                     90: #include <kern/macro_help.h>
                     91: #include <kern/kalloc.h>
                     92: #include <ipc/ipc_object.h>
                     93: #include <ipc/ipc_marequest.h>
                     94: #include <vm/vm_map.h>
                     95: 
                     96: /*
                     97:  *     This structure is only the header for a kmsg buffer;
                     98:  *     the actual buffer is normally larger.  The rest of the buffer
                     99:  *     holds the body of the message.
                    100:  *
                    101:  *     In a kmsg, the port fields hold pointers to ports instead
                    102:  *     of port names.  These pointers hold references.
                    103:  *
                    104:  *     The ikm_header.msgh_remote_port field is the destination
                    105:  *     of the message.
                    106:  *
                    107:  *     The  ikm_delta field is set such that (ikm_size + ikm_delta)
                    108:  *     indicates the *actual* length of the message and trailer which
                    109:  *     was passed by the sender and will be returned to the receiver.
                    110:  *     This has two uses in practice:
                    111:  *             if (> 0), it indicates the total length of the message
                    112:  *             trailer.  Note that due to alignment, this is always a
                    113:  *             4 byte aligned quantity.  In this case, the message
                    114:  *             *cannot* be in the old format since a trailer is never
                    115:  *             transmitted or generated (this also implies that messages
                    116:  *             in the new format always contains a trailer).
                    117:  *
                    118:  *             Otherwise (<= 0), it indicates that the length of the
                    119:  *             original sent message was not 4 byte aligned.  This
                    120:  *             can only occur in the old message format, and in this
                    121:  *             case ikm_size *will* be rounded normally to avoid
                    122:  *             breaking assertions elsewhere in the implemenatation.
                    123:  */
                    124: 
                    125: typedef struct ipc_kmsg {
                    126:        struct ipc_kmsg *ikm_next, *ikm_prev;
                    127:        vm_size_t ikm_size;
                    128:        ipc_marequest_t ikm_marequest;
                    129:        security_id_t ikm_sender;
                    130:        integer_t ikm_delta;
                    131:        mach_msg_header_t ikm_header;
                    132: } *ipc_kmsg_t;
                    133: 
                    134: #define        IKM_NULL                ((ipc_kmsg_t) 0)
                    135: 
                    136: #define        IKM_OVERHEAD                                                    \
                    137:                (sizeof(struct ipc_kmsg) - sizeof(mach_msg_header_t))
                    138: 
                    139: #define        ikm_plus_overhead(size) ((vm_size_t)((size) + IKM_OVERHEAD))
                    140: #define        ikm_less_overhead(size) ((mach_msg_size_t)((size) - IKM_OVERHEAD))
                    141: 
                    142: /*
                    143:  *     We keep a per-processor cache of kernel message buffers.
                    144:  *     The cache saves the overhead/locking of using kalloc/kfree.
                    145:  *     The per-processor cache seems to miss less than a per-thread cache,
                    146:  *     and it also uses less memory.  Access to the cache doesn't
                    147:  *     require locking.
                    148:  */
                    149: 
                    150: extern ipc_kmsg_t      ipc_kmsg_cache[NCPUS];
                    151: 
                    152: #define ikm_cache()     ipc_kmsg_cache[cpu_number()]
                    153: 
                    154: /*
                    155:  *     The size of the kernel message buffers that will be cached.
                    156:  *     IKM_SAVED_KMSG_SIZE includes overhead; IKM_SAVED_MSG_SIZE doesn't.
                    157:  */
                    158: 
                    159: #define        IKM_SAVED_KMSG_SIZE     ((vm_size_t) 256)
                    160: #define        IKM_SAVED_MSG_SIZE      ikm_less_overhead(IKM_SAVED_KMSG_SIZE)
                    161: 
                    162: #define        ikm_alloc(size)                                                 \
                    163:                ((ipc_kmsg_t) kalloc(ikm_plus_overhead(size)))
                    164: 
                    165: #define        ikm_init(kmsg, size)                                            \
                    166: MACRO_BEGIN                                                            \
                    167:        ikm_init_special((kmsg), ikm_plus_overhead(size));              \
                    168: MACRO_END
                    169: 
                    170: #define        ikm_init_special(kmsg, size)                                    \
                    171: MACRO_BEGIN                                                            \
                    172:        (kmsg)->ikm_size = (size);                                      \
                    173:        (kmsg)->ikm_marequest = IMAR_NULL;                              \
                    174:        (kmsg)->ikm_sender = ANONYMOUS_SECURITY_ID_VALUE;               \
                    175:        (kmsg)->ikm_delta = 0;                                          \
                    176: MACRO_END
                    177: 
                    178: #define        ikm_check_initialized(kmsg, size)                               \
                    179: MACRO_BEGIN                                                            \
                    180:        assert((kmsg)->ikm_size == (size));                             \
                    181:        assert((kmsg)->ikm_marequest == IMAR_NULL);                     \
                    182:        (kmsg)->ikm_sender = ANONYMOUS_SECURITY_ID_VALUE;               \
                    183:        (kmsg)->ikm_delta = 0;                                          \
                    184: MACRO_END
                    185: 
                    186: /*
                    187:  *     Non-positive message sizes are special.  They indicate that
                    188:  *     the message buffer doesn't come from ikm_alloc and
                    189:  *     requires some special handling to free.
                    190:  *
                    191:  *     ipc_kmsg_free is the non-macro form of ikm_free.
                    192:  *     It frees kmsgs of all varieties.
                    193:  */
                    194: 
                    195: #define        IKM_SIZE_NORMA          0
                    196: #define        IKM_SIZE_NETWORK        -1
                    197: #define        IKM_SIZE_DEVICE         -2
                    198: #define IKM_SIZE_NETIPC                -3
                    199: 
                    200: #define        ikm_free(kmsg)                                                  \
                    201: MACRO_BEGIN                                                            \
                    202:        register vm_size_t _size = (kmsg)->ikm_size;                    \
                    203:                                                                        \
                    204:        if ((integer_t)_size > 0)                                       \
                    205:                kfree((vm_offset_t) (kmsg), _size);                     \
                    206:        else                                                            \
                    207:                ipc_kmsg_free(kmsg);                                    \
                    208: MACRO_END
                    209: 
                    210: /*
                    211:  *     struct ipc_kmsg_queue is defined in kern/thread.h instead of here,
                    212:  *     so that kern/thread.h doesn't have to include ipc/ipc_kmsg.h.
                    213:  */
                    214: 
                    215: #include <ipc/ipc_kmsg_queue.h>
                    216: 
                    217: typedef struct ipc_kmsg_queue *ipc_kmsg_queue_t;
                    218: 
                    219: #define        IKMQ_NULL               ((ipc_kmsg_queue_t) 0)
                    220: 
                    221: 
                    222: /*
                    223:  * Exported interfaces
                    224:  */
                    225: 
                    226: #define        ipc_kmsg_queue_init(queue)              \
                    227: MACRO_BEGIN                                    \
                    228:        (queue)->ikmq_base = IKM_NULL;          \
                    229: MACRO_END
                    230: 
                    231: #define        ipc_kmsg_queue_empty(queue)     ((queue)->ikmq_base == IKM_NULL)
                    232: 
                    233: /* Enqueue a kmsg */
                    234: extern void ipc_kmsg_enqueue(
                    235:        ipc_kmsg_queue_t        queue,
                    236:        ipc_kmsg_t              kmsg);
                    237: 
                    238: /* Dequeue and return a kmsg */
                    239: extern ipc_kmsg_t ipc_kmsg_dequeue(
                    240:        ipc_kmsg_queue_t        queue);
                    241: 
                    242: /* Pull a kmsg out of a queue */
                    243: extern void ipc_kmsg_rmqueue(
                    244:        ipc_kmsg_queue_t        queue,
                    245:        ipc_kmsg_t              kmsg);
                    246: 
                    247: #define        ipc_kmsg_queue_first(queue)             ((queue)->ikmq_base)
                    248: 
                    249: /* Return the kmsg following the given kmsg */
                    250: extern ipc_kmsg_t ipc_kmsg_queue_next(
                    251:        ipc_kmsg_queue_t        queue,
                    252:        ipc_kmsg_t              kmsg);
                    253: 
                    254: #define        ipc_kmsg_rmqueue_first_macro(queue, kmsg)                       \
                    255: MACRO_BEGIN                                                            \
                    256:        register ipc_kmsg_t _next;                                      \
                    257:                                                                        \
                    258:        assert((queue)->ikmq_base == (kmsg));                           \
                    259:                                                                        \
                    260:        _next = (kmsg)->ikm_next;                                       \
                    261:        if (_next == (kmsg)) {                                          \
                    262:                assert((kmsg)->ikm_prev == (kmsg));                     \
                    263:                (queue)->ikmq_base = IKM_NULL;                          \
                    264:        } else {                                                        \
                    265:                register ipc_kmsg_t _prev = (kmsg)->ikm_prev;           \
                    266:                                                                        \
                    267:                (queue)->ikmq_base = _next;                             \
                    268:                _next->ikm_prev = _prev;                                \
                    269:                _prev->ikm_next = _next;                                \
                    270:        }                                                               \
                    271: MACRO_END
                    272: 
                    273: #define        ipc_kmsg_enqueue_macro(queue, kmsg)                             \
                    274: MACRO_BEGIN                                                            \
                    275:        register ipc_kmsg_t _first = (queue)->ikmq_base;                \
                    276:                                                                        \
                    277:        if (_first == IKM_NULL) {                                       \
                    278:                (queue)->ikmq_base = (kmsg);                            \
                    279:                (kmsg)->ikm_next = (kmsg);                              \
                    280:                (kmsg)->ikm_prev = (kmsg);                              \
                    281:        } else {                                                        \
                    282:                register ipc_kmsg_t _last = _first->ikm_prev;           \
                    283:                                                                        \
                    284:                (kmsg)->ikm_next = _first;                              \
                    285:                (kmsg)->ikm_prev = _last;                               \
                    286:                _first->ikm_prev = (kmsg);                              \
                    287:                _last->ikm_next = (kmsg);                               \
                    288:        }                                                               \
                    289: MACRO_END
                    290: 
                    291: /* Destroy kernel message */
                    292: extern void ipc_kmsg_destroy(
                    293:        ipc_kmsg_t      kmsg);
                    294: 
                    295: /* Free a kernel message buffer */
                    296: extern void ipc_kmsg_free(
                    297:        ipc_kmsg_t      kmsg);
                    298: 
                    299: /* Allocate a kernel message buffer and copy a user message to the buffer */
                    300: extern mach_msg_return_t ipc_kmsg_get(
                    301:        mach_msg_header_t       *msg,
                    302:        mach_msg_option_t       option,
                    303:        mach_msg_size_t         size,
                    304:        integer_t               delta,
                    305:        ipc_kmsg_t              *kmsgp);
                    306: 
                    307: /* Allocate a kernel message buffer and copy a kernel message to the buffer */
                    308: extern mach_msg_return_t ipc_kmsg_get_from_kernel(
                    309:        mach_msg_header_t       *msg,
                    310:        mach_msg_option_t       option,
                    311:        mach_msg_size_t         size,
                    312:        integer_t               delta,
                    313:        ipc_kmsg_t              *kmsgp);
                    314: 
                    315: /* Copy a kernel message buffer to a user message */
                    316: extern mach_msg_return_t ipc_kmsg_put(
                    317:        mach_msg_header_t       *msg,
                    318:        ipc_kmsg_t              kmsg,
                    319:        mach_msg_size_t         size);
                    320: 
                    321: /* Copy a kernel message buffer to a kernel message */
                    322: extern void ipc_kmsg_put_to_kernel(
                    323:        mach_msg_header_t       *msg,
                    324:        ipc_kmsg_t              kmsg,
                    325:        mach_msg_size_t         size);
                    326: 
                    327: /* Copyin port rights in the header of a message */
                    328: extern mach_msg_return_t ipc_kmsg_copyin_header(
                    329:        mach_msg_header_t       *msg,
                    330:        ipc_space_t             space,
                    331:        mach_port_t             notify);
                    332: 
                    333: /* Copyin port rights and out-of-line memory from a user message */
                    334: extern mach_msg_return_t ipc_kmsg_copyin(
                    335:        ipc_kmsg_t      kmsg,
                    336:        ipc_space_t     space,
                    337:        vm_map_t        map,
                    338:        mach_port_t     notify);
                    339: 
                    340: /* Copyin port rights and out-of-line memory from a kernel message */
                    341: extern void ipc_kmsg_copyin_from_kernel(
                    342:        ipc_kmsg_t      kmsg);
                    343: 
                    344: /* Copyout port rights in the header of a message */
                    345: extern mach_msg_return_t ipc_kmsg_copyout_header(
                    346:        mach_msg_header_t       *msg,
                    347:        ipc_space_t             space,
                    348:        mach_port_t             notify);
                    349: 
                    350: /* Copyout a port right returning a name */
                    351: extern mach_msg_return_t ipc_kmsg_copyout_object(
                    352:        ipc_space_t             space,
                    353:        ipc_object_t            object,
                    354:        mach_msg_type_name_t    msgt_name,
                    355:        mach_port_t             *namep);
                    356: 
                    357: /* Copyout the header and body to a user message */
                    358: extern mach_msg_return_t ipc_kmsg_copyout(
                    359:        ipc_kmsg_t              kmsg,
                    360:        ipc_space_t             space,
                    361:        vm_map_t                map,
                    362:        mach_port_t             notify,
                    363:        ipc_kmsg_t              list);
                    364: 
                    365: /* Copyout port rights and out-of-line memory from the body of a message */
                    366: extern mach_msg_return_t ipc_kmsg_copyout_body(
                    367:        ipc_kmsg_t              kmsg,
                    368:        ipc_space_t             space,
                    369:        vm_map_t                map,
                    370:        ipc_kmsg_t              list);
                    371: 
                    372: /* Copyout port rights and out-of-line memory to a user message,
                    373:    not reversing the ports in the header */
                    374: extern mach_msg_return_t ipc_kmsg_copyout_pseudo(
                    375:        ipc_kmsg_t              kmsg,
                    376:        ipc_space_t             space,
                    377:        vm_map_t                map,
                    378:        ipc_kmsg_t              list);
                    379: 
                    380: /* Copyout the destination port in the message */
                    381: extern void ipc_kmsg_copyout_dest( 
                    382:        ipc_kmsg_t      kmsg,
                    383:        ipc_space_t     space);
                    384: 
                    385: /* kernel's version of ipc_kmsg_copyout_dest */
                    386: extern void ipc_kmsg_copyout_to_kernel(
                    387:        ipc_kmsg_t              kmsg,
                    388:        ipc_space_t             space);
                    389: 
                    390: /* Check scatter and gather lists for consistency */
                    391: extern mach_msg_return_t ipc_kmsg_check_scatter(
                    392:        ipc_kmsg_t              kmsg,
                    393:        mach_msg_option_t       option,
                    394:        ipc_kmsg_t              *list);
                    395: 
                    396: #if    MACH_IPC_COMPAT
                    397: 
                    398: extern mach_msg_return_t
                    399: ipc_kmsg_copyin_compat(/* ipc_kmsg_t, ipc_space_t, vm_map_t */);
                    400: 
                    401: extern mach_msg_return_t
                    402: ipc_kmsg_copyout_compat(/* ipc_kmsg_t, ipc_space_t, vm_map_t */);
                    403: 
                    404: #endif /* MACH_IPC_COMPAT */
                    405: 
                    406: #endif /* _IPC_IPC_KMSG_H_ */

unix.superglobalmegacorp.com

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