|
|
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_ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.