1 /* 2 * Copyright 1991-1998 by Open Software Foundation, Inc. 3 * All Rights Reserved 4 * 5 * Permission to use, copy, modify, and distribute this software and 6 * its documentation for any purpose and without fee is hereby granted, 7 * provided that the above copyright notice appears in all copies and 8 * that both the copyright notice and this permission notice appear in 9 * supporting documentation. 10 * 11 * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 12 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 13 * FOR A PARTICULAR PURPOSE. 14 * 15 * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 16 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 17 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 18 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 19 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20 */ 21 /* 22 * MkLinux 23 */ 24 /* CMU_HIST */ 25 /* 26 * Revision 2.11.2.4 92/05/28 18:14:33 jeffreyh 27 * Add ikm_has_dest_right boolean. Put in union with ikm_norma_acked. 28 * [92/05/28 dlb] 29 * 30 * Revision 2.11.2.3 92/05/26 18:53:43 jeffreyh 31 * Add ikm_norma_acked field for norma message processing. 32 * [92/05/05 dlb] 33 * 34 * Revision 2.11.2.2 92/04/08 15:44:33 jeffreyh 35 * Temporary debugging logic. 36 * [92/04/06 dlb] 37 * 38 * Revision 2.11.2.1 92/01/03 16:35:19 jsb 39 * Added ikm_source_node to support norma_ipc_receive_rright. 40 * [91/12/28 08:38:53 jsb] 41 * 42 * Revision 2.11 91/12/14 14:26:54 jsb 43 * NORMA_IPC: added ikm_copy to struct kmsg. 44 * 45 * Revision 2.10 91/08/28 11:13:31 jsb 46 * Renamed IKM_SIZE_CLPORT to IKM_SIZE_NORMA. 47 * [91/08/15 08:12:02 jsb] 48 * 49 * Revision 2.9 91/08/03 18:18:24 jsb 50 * NORMA_IPC: added ikm_page field to struct ipc_kmsg. 51 * [91/07/17 14:01:38 jsb] 52 * 53 * Revision 2.8 91/06/17 15:46:15 jsb 54 * Renamed NORMA conditionals. 55 * [91/06/17 10:46:12 jsb] 56 * 57 * Revision 2.7 91/05/14 16:33:21 mrt 58 * Correcting copyright 59 * 60 * Revision 2.6 91/03/16 14:48:10 rpd 61 * Replaced ith_saved with ipc_kmsg_cache. 62 * [91/02/16 rpd] 63 * 64 * Revision 2.5 91/02/05 17:22:08 mrt 65 * Changed to new Mach copyright 66 * [91/02/01 15:45:52 mrt] 67 * 68 * Revision 2.4 91/01/08 15:14:04 rpd 69 * Added ipc_kmsg_free. Generalized the notion of special message sizes. 70 * [91/01/05 rpd] 71 * Added declarations of ipc_kmsg_copyout_object, ipc_kmsg_copyout_body. 72 * [90/12/21 rpd] 73 * 74 * Revision 2.3 90/09/28 16:54:48 jsb 75 * Added NORMA_IPC support (hack in ikm_free). 76 * [90/09/28 14:03:06 jsb] 77 * 78 * Revision 2.2 90/06/02 14:50:24 rpd 79 * Increased IKM_SAVED_KMSG_SIZE from 128 to 256. 80 * [90/04/23 rpd] 81 * Created for new IPC. 82 * [90/03/26 20:56:16 rpd] 83 * 84 */ 85 /* CMU_ENDHIST */ 86 /* 87 * Mach Operating System 88 * Copyright (c) 1991,1990,1989 Carnegie Mellon University 89 * All Rights Reserved. 90 * 91 * Permission to use, copy, modify and distribute this software and its 92 * documentation is hereby granted, provided that both the copyright 93 * notice and this permission notice appear in all copies of the 94 * software, derivative works or modified versions, and any portions 95 * thereof, and that both notices appear in supporting documentation. 96 * 97 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 98 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 99 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 100 * 101 * Carnegie Mellon requests users of this software to return to 102 * 103 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 104 * School of Computer Science 105 * Carnegie Mellon University 106 * Pittsburgh PA 15213-3890 107 * 108 * any improvements or extensions that they make and grant Carnegie Mellon 109 * the rights to redistribute these changes. 110 */ 111 /* 112 */ 113 /* 114 * File: ipc/ipc_kmsg.h 115 * Author: Rich Draves 116 * Date: 1989 117 * 118 * Definitions for kernel messages. 119 */ 120 121 #ifndef _IPC_IPC_KMSG_H_ 122 #define _IPC_IPC_KMSG_H_ 123 124 #include <sys/mach/vm_types.h> 125 #include <sys/mach/mach_types.h> 126 #include <sys/mach/message.h> 127 128 #include <sys/mach/ipc/ipc_object.h> 129 130 /* 131 * This structure is only the header for a kmsg buffer; 132 * the actual buffer is normally larger. The rest of the buffer 133 * holds the body of the message. 134 * 135 * In a kmsg, the port fields hold pointers to ports instead 136 * of port names. These pointers hold references. 137 * 138 * The ikm_header.msgh_remote_port field is the destination 139 * of the message. 140 */ 141 142 typedef struct ipc_kmsg { 143 mach_msg_size_t ikm_size; 144 struct ipc_kmsg *ikm_next, *ikm_prev; 145 mach_msg_header_t *ikm_header; 146 ipc_port_t ikm_prealloc; 147 } *ipc_kmsg_t; 148 149 #define IKM_NULL ((ipc_kmsg_t) 0) 150 151 #define IKM_OVERHEAD (sizeof(struct ipc_kmsg)) 152 153 #define ikm_plus_overhead(size) ((mach_msg_size_t)((size) + IKM_OVERHEAD)) 154 #define ikm_less_overhead(size) ((mach_msg_size_t)((size) - IKM_OVERHEAD)) 155 156 /* 157 * XXX For debugging. 158 */ 159 #define IKM_BOGUS ((ipc_kmsg_t) 0xffffff10) 160 161 /* 162 * The size of the kernel message buffers that will be cached. 163 * IKM_SAVED_KMSG_SIZE includes overhead; IKM_SAVED_MSG_SIZE doesn't. 164 */ 165 166 #define IKM_SAVED_KMSG_SIZE 256 167 #define IKM_SAVED_MSG_SIZE ikm_less_overhead(IKM_SAVED_KMSG_SIZE) 168 169 #define ikm_alloc(size) ipc_kmsg_alloc(size); 170 171 #define ikm_init(kmsg, size) \ 172 MACRO_BEGIN \ 173 ikm_init_special((kmsg), ikm_plus_overhead(size)); \ 174 MACRO_END 175 176 #define ikm_init_special(kmsg, size) \ 177 MACRO_BEGIN \ 178 (kmsg)->ikm_size = (size); \ 179 (kmsg)->ikm_prev = NULL; \ 180 (kmsg)->ikm_next = NULL; \ 181 MACRO_END 182 183 #define ikm_check_initialized(kmsg, size) \ 184 MACRO_BEGIN \ 185 assert((kmsg)->ikm_size == (size)); \ 186 MACRO_END 187 188 #define ikm_set_header(kmsg, mtsize) \ 189 MACRO_BEGIN \ 190 (kmsg)->ikm_header = (mach_msg_header_t *)(kmsg + 1); \ 191 MPASS(kmsg->ikm_size >= mtsize + sizeof(*kmsg)); \ 192 MACRO_END 193 194 /* 195 * Non-positive message sizes are special. They indicate that 196 * the message buffer doesn't come from ikm_alloc and 197 * requires some special handling to free. 198 * 199 * ipc_kmsg_free is the non-macro form of ikm_free. 200 * It frees kmsgs of all varieties. 201 */ 202 203 #define IKM_SIZE_NETWORK -1 204 #define IKM_SIZE_INTR_KMSG -2 205 206 207 #define ikm_free(kmsg) ipc_kmsg_free(kmsg) 208 209 struct ipc_kmsg_queue { 210 struct ipc_kmsg *ikmq_base; 211 }; 212 213 typedef struct ipc_kmsg_queue *ipc_kmsg_queue_t; 214 215 #define IKMQ_NULL ((ipc_kmsg_queue_t) 0) 216 extern uma_zone_t ipc_kmsg_zone; 217 218 /* 219 * Exported interfaces 220 */ 221 222 #define ipc_kmsg_queue_init(queue) \ 223 MACRO_BEGIN \ 224 (queue)->ikmq_base = IKM_NULL; \ 225 MACRO_END 226 227 #define ipc_kmsg_queue_empty(queue) ((queue)->ikmq_base == IKM_NULL) 228 229 /* Enqueue a kmsg */ 230 extern void ipc_kmsg_enqueue( 231 ipc_kmsg_queue_t queue, 232 ipc_kmsg_t kmsg); 233 234 /* Dequeue and return a kmsg */ 235 extern ipc_kmsg_t ipc_kmsg_dequeue( 236 ipc_kmsg_queue_t queue); 237 238 /* Pull a kmsg out of a queue */ 239 extern void ipc_kmsg_rmqueue( 240 ipc_kmsg_queue_t queue, 241 ipc_kmsg_t kmsg); 242 243 #define ipc_kmsg_queue_first(queue) ((queue)->ikmq_base) 244 245 /* Return the kmsg following the given kmsg */ 246 extern ipc_kmsg_t ipc_kmsg_queue_next( 247 ipc_kmsg_queue_t queue, 248 ipc_kmsg_t kmsg); 249 250 #define ipc_kmsg_rmqueue_first_macro(queue, kmsg) \ 251 MACRO_BEGIN \ 252 register ipc_kmsg_t _next; \ 253 \ 254 assert((queue)->ikmq_base == (kmsg)); \ 255 \ 256 _next = (kmsg)->ikm_next; \ 257 if (_next == (kmsg)) { \ 258 assert((kmsg)->ikm_prev == (kmsg)); \ 259 (queue)->ikmq_base = IKM_NULL; \ 260 } else { \ 261 register ipc_kmsg_t _prev = (kmsg)->ikm_prev; \ 262 \ 263 (queue)->ikmq_base = _next; \ 264 _next->ikm_prev = _prev; \ 265 _prev->ikm_next = _next; \ 266 } \ 267 /* XXX Debug paranoia */ \ 268 kmsg->ikm_next = IKM_BOGUS; \ 269 kmsg->ikm_prev = IKM_BOGUS; \ 270 MACRO_END 271 272 #define ipc_kmsg_enqueue_macro(queue, kmsg) \ 273 MACRO_BEGIN \ 274 register ipc_kmsg_t _first = (queue)->ikmq_base; \ 275 \ 276 if (_first == IKM_NULL) { \ 277 (queue)->ikmq_base = (kmsg); \ 278 (kmsg)->ikm_next = (kmsg); \ 279 (kmsg)->ikm_prev = (kmsg); \ 280 } else { \ 281 register ipc_kmsg_t _last = _first->ikm_prev; \ 282 \ 283 (kmsg)->ikm_next = _first; \ 284 (kmsg)->ikm_prev = _last; \ 285 _first->ikm_prev = (kmsg); \ 286 _last->ikm_next = (kmsg); \ 287 } \ 288 MACRO_END 289 290 /* scatter list macros */ 291 292 #define SKIP_PORT_DESCRIPTORS(s, e) \ 293 MACRO_BEGIN \ 294 if ((s) != MACH_MSG_DESCRIPTOR_NULL) { \ 295 while ((s) < (e)) { \ 296 if ((s)->type.type != MACH_MSG_PORT_DESCRIPTOR) \ 297 break; \ 298 (s)++; \ 299 } \ 300 if ((s) >= (e)) \ 301 (s) = MACH_MSG_DESCRIPTOR_NULL; \ 302 } \ 303 MACRO_END 304 305 #define INCREMENT_SCATTER(s) \ 306 MACRO_BEGIN \ 307 if ((s) != MACH_MSG_DESCRIPTOR_NULL) { \ 308 (s)++; \ 309 } \ 310 MACRO_END 311 312 /* Destroy kernel message */ 313 extern void ipc_kmsg_destroy( 314 ipc_kmsg_t kmsg); 315 316 /* Allocate a kernel message */ 317 extern ipc_kmsg_t ipc_kmsg_alloc( 318 mach_msg_size_t size); 319 320 /* Free a kernel message buffer */ 321 extern void ipc_kmsg_free( 322 ipc_kmsg_t kmsg); 323 324 /* Allocate a kernel message buffer and copy a user message to the buffer */ 325 extern mach_msg_return_t ipc_kmsg_get( 326 mach_msg_header_t *msg, 327 mach_msg_size_t size, 328 ipc_kmsg_t *kmsgp, 329 ipc_space_t space); 330 331 /* Allocate a kernel message buffer and copy a kernel message to the buffer */ 332 extern mach_msg_return_t ipc_kmsg_get_from_kernel( 333 mach_msg_header_t *msg, 334 mach_msg_size_t size, 335 ipc_kmsg_t *kmsgp); 336 337 /* Copy a kernel message buffer to a user message */ 338 extern mach_msg_return_t ipc_kmsg_put( 339 mach_msg_header_t *msg, 340 ipc_kmsg_t kmsg, 341 mach_msg_size_t size); 342 343 /* Copy a kernel message buffer to a kernel message */ 344 extern void ipc_kmsg_put_to_kernel( 345 mach_msg_header_t *msg, 346 ipc_kmsg_t kmsg, 347 mach_msg_size_t size); 348 349 /* Copyin port rights in the header of a message */ 350 extern mach_msg_return_t ipc_kmsg_copyin_header( 351 ipc_kmsg_t kmsg, 352 ipc_space_t space, 353 mach_port_name_t notify); 354 355 /* Copyin port rights and out-of-line memory from a user message */ 356 extern mach_msg_return_t ipc_kmsg_copyin( 357 ipc_kmsg_t kmsg, 358 ipc_space_t space, 359 vm_map_t map, 360 mach_port_name_t notify); 361 362 /* Copyin port rights and out-of-line memory from a kernel message */ 363 extern void ipc_kmsg_copyin_from_kernel( 364 ipc_kmsg_t kmsg); 365 366 /* Copyout the header and body to a user message */ 367 extern mach_msg_return_t ipc_kmsg_copyout( 368 ipc_kmsg_t kmsg, 369 ipc_space_t space, 370 vm_map_t map, 371 mach_msg_body_t *slist, 372 mach_msg_option_t option); 373 374 /* Compute size of message as copied out to the specified space/map */ 375 extern mach_msg_size_t ipc_kmsg_copyout_size( 376 ipc_kmsg_t kmsg, 377 vm_map_t map); 378 379 /* Copyout port rights and out-of-line memory to a user message, 380 not reversing the ports in the header */ 381 extern mach_msg_return_t ipc_kmsg_copyout_pseudo( 382 ipc_kmsg_t kmsg, 383 ipc_space_t space, 384 vm_map_t map, 385 mach_msg_body_t *slist); 386 387 /* Copyout the destination port in the message */ 388 extern void ipc_kmsg_copyout_dest( 389 ipc_kmsg_t kmsg, 390 ipc_space_t space); 391 392 /* kernel's version of ipc_kmsg_copyout_dest */ 393 extern void ipc_kmsg_copyout_to_kernel( 394 ipc_kmsg_t kmsg, 395 ipc_space_t space); 396 397 /* Check scatter and gather lists for consistency */ 398 extern mach_msg_return_t ipc_kmsg_check_scatter( 399 ipc_kmsg_t kmsg, 400 mach_msg_option_t option, 401 mach_msg_body_t **slistp, 402 mach_msg_size_t *sizep); 403 404 extern boolean_t ikm_cache_get( 405 ipc_kmsg_t *kmsg); 406 extern boolean_t ikm_cache_put( 407 ipc_kmsg_t kmsg); 408 409 #if MACH_KDB 410 411 /* Do a formatted dump of a kernel message */ 412 extern void ipc_kmsg_print( 413 ipc_kmsg_t kmsg); 414 415 /* Do a formatted dump of a user message */ 416 extern void ipc_msg_print( 417 mach_msg_header_t *msgh); 418 419 #endif /* MACH_KDB */ 420 421 #endif /* _IPC_IPC_KMSG_H_ */ 422