1/* 2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28/* 29 * @OSF_COPYRIGHT@ 30 */ 31/* 32 * Mach Operating System 33 * Copyright (c) 1991,1990,1989 Carnegie Mellon University 34 * All Rights Reserved. 35 * 36 * Permission to use, copy, modify and distribute this software and its 37 * documentation is hereby granted, provided that both the copyright 38 * notice and this permission notice appear in all copies of the 39 * software, derivative works or modified versions, and any portions 40 * thereof, and that both notices appear in supporting documentation. 41 * 42 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 43 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 44 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 45 * 46 * Carnegie Mellon requests users of this software to return to 47 * 48 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 49 * School of Computer Science 50 * Carnegie Mellon University 51 * Pittsburgh PA 15213-3890 52 * 53 * any improvements or extensions that they make and grant Carnegie Mellon 54 * the rights to redistribute these changes. 55 */ 56/* 57 * NOTICE: This file was modified by McAfee Research in 2004 to introduce 58 * support for mandatory and extensible security protections. This notice 59 * is included in support of clause 2.2 (b) of the Apple Public License, 60 * Version 2.0. 61 * Copyright (c) 2005 SPARTA, Inc. 62 */ 63/* 64 */ 65/* 66 * File: ipc/ipc_kmsg.h 67 * Author: Rich Draves 68 * Date: 1989 69 * 70 * Definitions for kernel messages. 71 */ 72 73#ifndef _IPC_IPC_KMSG_H_ 74#define _IPC_IPC_KMSG_H_ 75 76#include <mach/vm_types.h> 77#include <mach/message.h> 78#include <kern/kern_types.h> 79#include <kern/assert.h> 80#include <kern/macro_help.h> 81#include <ipc/ipc_types.h> 82#include <ipc/ipc_object.h> 83 84/* 85 * This structure is only the header for a kmsg buffer; 86 * the actual buffer is normally larger. The rest of the buffer 87 * holds the body of the message. 88 * 89 * In a kmsg, the port fields hold pointers to ports instead 90 * of port names. These pointers hold references. 91 * 92 * The ikm_header.msgh_remote_port field is the destination 93 * of the message. 94 */ 95 96struct ipc_labelh; 97 98struct ipc_kmsg { 99 struct ipc_kmsg *ikm_next; 100 struct ipc_kmsg *ikm_prev; 101 ipc_port_t ikm_prealloc; /* port we were preallocated from */ 102 mach_msg_size_t ikm_size; 103 struct ipc_labelh *ikm_sender; 104 mach_msg_header_t *ikm_header; 105}; 106 107 108#define IKM_OVERHEAD (sizeof(struct ipc_kmsg)) 109 110#define ikm_plus_overhead(size) ((mach_msg_size_t)((size) + IKM_OVERHEAD)) 111#define ikm_less_overhead(size) ((mach_msg_size_t)((size) - IKM_OVERHEAD)) 112 113/* 114 * XXX For debugging. 115 */ 116#define IKM_BOGUS ((ipc_kmsg_t) 0xffffff10) 117 118/* 119 * The size of the kernel message buffers that will be cached. 120 * IKM_SAVED_KMSG_SIZE includes overhead; IKM_SAVED_MSG_SIZE doesn't. 121 */ 122extern zone_t ipc_kmsg_zone; 123#define IKM_SAVED_KMSG_SIZE 256 124#define IKM_SAVED_MSG_SIZE ikm_less_overhead(IKM_SAVED_KMSG_SIZE) 125 126#define ikm_prealloc_inuse_port(kmsg) \ 127 ((kmsg)->ikm_prealloc) 128 129#define ikm_prealloc_inuse(kmsg) \ 130 ((kmsg)->ikm_prealloc != IP_NULL) 131 132#define ikm_prealloc_set_inuse(kmsg, port) \ 133MACRO_BEGIN \ 134 assert((port) != IP_NULL); \ 135 (kmsg)->ikm_prealloc = (port); \ 136 ip_reference(port); \ 137MACRO_END 138 139#define ikm_prealloc_clear_inuse(kmsg, port) \ 140MACRO_BEGIN \ 141 (kmsg)->ikm_prealloc = IP_NULL; \ 142 ip_release(port); \ 143MACRO_END 144 145#define ikm_init(kmsg, size) \ 146MACRO_BEGIN \ 147 (kmsg)->ikm_size = (size); \ 148 (kmsg)->ikm_prealloc = IP_NULL; \ 149 (kmsg)->ikm_sender = NULL; \ 150 assert((kmsg)->ikm_prev = (kmsg)->ikm_next = IKM_BOGUS); \ 151MACRO_END 152 153#define ikm_check_init(kmsg, size) \ 154MACRO_BEGIN \ 155 assert((kmsg)->ikm_size == (size)); \ 156 assert((kmsg)->ikm_prev == IKM_BOGUS); \ 157 assert((kmsg)->ikm_next == IKM_BOGUS); \ 158MACRO_END 159 160struct ipc_kmsg_queue { 161 struct ipc_kmsg *ikmq_base; 162}; 163 164typedef struct ipc_kmsg_queue *ipc_kmsg_queue_t; 165 166#define IKMQ_NULL ((ipc_kmsg_queue_t) 0) 167 168 169/* 170 * Exported interfaces 171 */ 172 173#define ipc_kmsg_queue_init(queue) \ 174MACRO_BEGIN \ 175 (queue)->ikmq_base = IKM_NULL; \ 176MACRO_END 177 178#define ipc_kmsg_queue_empty(queue) ((queue)->ikmq_base == IKM_NULL) 179 180/* Enqueue a kmsg */ 181extern void ipc_kmsg_enqueue( 182 ipc_kmsg_queue_t queue, 183 ipc_kmsg_t kmsg); 184 185/* Dequeue and return a kmsg */ 186extern ipc_kmsg_t ipc_kmsg_dequeue( 187 ipc_kmsg_queue_t queue); 188 189/* Pull a kmsg out of a queue */ 190extern void ipc_kmsg_rmqueue( 191 ipc_kmsg_queue_t queue, 192 ipc_kmsg_t kmsg); 193 194#define ipc_kmsg_queue_first(queue) ((queue)->ikmq_base) 195 196/* Return the kmsg following the given kmsg */ 197extern ipc_kmsg_t ipc_kmsg_queue_next( 198 ipc_kmsg_queue_t queue, 199 ipc_kmsg_t kmsg); 200 201#define ipc_kmsg_rmqueue_first_macro(queue, kmsg) \ 202MACRO_BEGIN \ 203 register ipc_kmsg_t _next; \ 204 \ 205 assert((queue)->ikmq_base == (kmsg)); \ 206 \ 207 _next = (kmsg)->ikm_next; \ 208 if (_next == (kmsg)) { \ 209 assert((kmsg)->ikm_prev == (kmsg)); \ 210 (queue)->ikmq_base = IKM_NULL; \ 211 } else { \ 212 register ipc_kmsg_t _prev = (kmsg)->ikm_prev; \ 213 \ 214 (queue)->ikmq_base = _next; \ 215 _next->ikm_prev = _prev; \ 216 _prev->ikm_next = _next; \ 217 } \ 218 /* XXX Debug paranoia ASSIGNMENTS */ \ 219 assert(kmsg->ikm_next = IKM_BOGUS); \ 220 assert(kmsg->ikm_prev = IKM_BOGUS); \ 221MACRO_END 222 223#define ipc_kmsg_enqueue_macro(queue, kmsg) \ 224MACRO_BEGIN \ 225 register ipc_kmsg_t _first = (queue)->ikmq_base; \ 226 \ 227 if (_first == IKM_NULL) { \ 228 (queue)->ikmq_base = (kmsg); \ 229 (kmsg)->ikm_next = (kmsg); \ 230 (kmsg)->ikm_prev = (kmsg); \ 231 } else { \ 232 register ipc_kmsg_t _last = _first->ikm_prev; \ 233 \ 234 (kmsg)->ikm_next = _first; \ 235 (kmsg)->ikm_prev = _last; \ 236 _first->ikm_prev = (kmsg); \ 237 _last->ikm_next = (kmsg); \ 238 } \ 239MACRO_END 240 241/* 242 * extern void 243 * ipc_kmsg_send_always(ipc_kmsg_t); 244 */ 245#define ipc_kmsg_send_always(kmsg) \ 246 ipc_kmsg_send((kmsg), MACH_SEND_ALWAYS, MACH_MSG_TIMEOUT_NONE) 247 248 249/* Allocate a kernel message */ 250extern ipc_kmsg_t ipc_kmsg_alloc( 251 mach_msg_size_t size); 252 253/* Free a kernel message buffer */ 254extern void ipc_kmsg_free( 255 ipc_kmsg_t kmsg); 256 257/* Destroy kernel message */ 258extern void ipc_kmsg_destroy( 259 ipc_kmsg_t kmsg); 260 261/* destroy kernel message and a reference on the dest */ 262extern void ipc_kmsg_destroy_dest( 263 ipc_kmsg_t kmsg); 264 265 266/* Preallocate a kernel message buffer */ 267extern void ipc_kmsg_set_prealloc( 268 ipc_kmsg_t kmsg, 269 ipc_port_t port); 270 271/* Clear a kernel message buffer */ 272extern void ipc_kmsg_clear_prealloc( 273 ipc_kmsg_t kmsg, 274 ipc_port_t port); 275 276/* Allocate a kernel message buffer and copy a user message to the buffer */ 277extern mach_msg_return_t ipc_kmsg_get( 278 mach_vm_address_t msg_addr, 279 mach_msg_size_t size, 280 ipc_kmsg_t *kmsgp); 281 282/* Allocate a kernel message buffer and copy a kernel message to the buffer */ 283extern mach_msg_return_t ipc_kmsg_get_from_kernel( 284 mach_msg_header_t *msg, 285 mach_msg_size_t size, 286 ipc_kmsg_t *kmsgp); 287 288/* Send a message to a port */ 289extern mach_msg_return_t ipc_kmsg_send( 290 ipc_kmsg_t kmsg, 291 mach_msg_option_t option, 292 mach_msg_timeout_t timeout_val); 293 294/* Copy a kernel message buffer to a user message */ 295extern mach_msg_return_t ipc_kmsg_put( 296 mach_vm_address_t msg_addr, 297 ipc_kmsg_t kmsg, 298 mach_msg_size_t size); 299 300/* Copy a kernel message buffer to a kernel message */ 301extern void ipc_kmsg_put_to_kernel( 302 mach_msg_header_t *msg, 303 ipc_kmsg_t kmsg, 304 mach_msg_size_t size); 305 306/* Copyin port rights in the header of a message */ 307extern mach_msg_return_t ipc_kmsg_copyin_header( 308 mach_msg_header_t *msg, 309 ipc_space_t space, 310 mach_port_name_t notify); 311 312/* Copyin port rights and out-of-line memory from a user message */ 313extern mach_msg_return_t ipc_kmsg_copyin( 314 ipc_kmsg_t kmsg, 315 ipc_space_t space, 316 vm_map_t map, 317 mach_port_name_t notify); 318 319/* Copyin port rights and out-of-line memory from a kernel message */ 320extern void ipc_kmsg_copyin_from_kernel( 321 ipc_kmsg_t kmsg); 322 323/* Copyout port rights in the header of a message */ 324extern mach_msg_return_t ipc_kmsg_copyout_header( 325 mach_msg_header_t *msg, 326 ipc_space_t space, 327 mach_port_name_t notify); 328 329/* Copyout a port right returning a name */ 330extern mach_msg_return_t ipc_kmsg_copyout_object( 331 ipc_space_t space, 332 ipc_object_t object, 333 mach_msg_type_name_t msgt_name, 334 mach_port_name_t *namep); 335 336/* Copyout the header and body to a user message */ 337extern mach_msg_return_t ipc_kmsg_copyout( 338 ipc_kmsg_t kmsg, 339 ipc_space_t space, 340 vm_map_t map, 341 mach_port_name_t notify, 342 mach_msg_body_t *slist); 343 344/* Copyout port rights and out-of-line memory from the body of a message */ 345extern mach_msg_return_t ipc_kmsg_copyout_body( 346 ipc_kmsg_t kmsg, 347 ipc_space_t space, 348 vm_map_t map, 349 mach_msg_body_t *slist); 350 351/* Copyout port rights and out-of-line memory to a user message, 352 not reversing the ports in the header */ 353extern mach_msg_return_t ipc_kmsg_copyout_pseudo( 354 ipc_kmsg_t kmsg, 355 ipc_space_t space, 356 vm_map_t map, 357 mach_msg_body_t *slist); 358 359/* Compute size of message as copied out to the specified space/map */ 360extern mach_msg_size_t ipc_kmsg_copyout_size( 361 ipc_kmsg_t kmsg, 362 vm_map_t map); 363 364/* Copyout the destination port in the message */ 365extern void ipc_kmsg_copyout_dest( 366 ipc_kmsg_t kmsg, 367 ipc_space_t space); 368 369/* kernel's version of ipc_kmsg_copyout_dest */ 370extern void ipc_kmsg_copyout_to_kernel( 371 ipc_kmsg_t kmsg, 372 ipc_space_t space); 373 374/* get a scatter list and check consistency */ 375extern mach_msg_body_t *ipc_kmsg_get_scatter( 376 mach_vm_address_t msg_addr, 377 mach_msg_size_t slist_size, 378 ipc_kmsg_t kmsg); 379 380/* free a scatter list */ 381extern void ipc_kmsg_free_scatter( 382 mach_msg_body_t *slist, 383 mach_msg_size_t slist_size); 384 385#endif /* _IPC_IPC_KMSG_H_ */ 386 387