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 25 /* 26 * Mach RPC Subsystem Interfaces 27 */ 28 29 #ifndef _MACH_RPC_H_ 30 #define _MACH_RPC_H_ 31 32 #include <sys/mach/kern_return.h> 33 #include <sys/mach/port.h> 34 #include <sys/mach/vm_types.h> 35 36 #include <sys/mach/mig_errors.h> 37 #include <sys/mach/ipc_common.h> 38 39 #ifdef MACH_KERNEL 40 #include <ipc/ipc_object.h> 41 #endif /* MACH_KERNEL */ 42 43 #pragma clang diagnostic ignored "-Wunused-local-typedef" 44 45 /* 46 * 47 * Definition of RPC "glue code" operations vector -- entry 48 * points needed to accomplish short-circuiting 49 */ 50 typedef struct rpc_glue_vector { 51 kern_return_t (*rpc_simple)(int, int, void *); 52 boolean_t (*copyin)(mach_port_t, void *); 53 boolean_t (*copyout)(mach_port_t, void *); 54 boolean_t (*copyinstr)(mach_port_t, void *); 55 kern_return_t (*thread_switch)(void *); 56 kern_return_t (*thread_depress_abort)(mach_port_t); 57 } *rpc_glue_vector_t; 58 59 /* 60 * Macros used to dereference glue code ops vector -- note 61 * hard-wired references to global defined below. Also note 62 * that most of the macros assume their caller has stacked 63 * the target args somewhere, so that they can pass just the 64 * address of the first arg to the short-circuited 65 * implementation. 66 */ 67 #define CAN_SHCIRCUIT(name) (_rpc_glue_vector->name != 0) 68 #define RPC_SIMPLE(port, rtn_num, argc, argv) \ 69 ((*(_rpc_glue_vector->rpc_simple))(rtn_num, argc, (void *)(&(port)))) 70 #define COPYIN(map, from, to, count) \ 71 ((*(_rpc_glue_vector->copyin))(map, (void *)(&(from)))) 72 #define COPYOUT(map, from, to, count) \ 73 ((*(_rpc_glue_vector->copyout))(map, (void *)(&(from)))) 74 #define COPYINSTR(map, from, to, max, actual) \ 75 ((*(_rpc_glue_vector->copyinstr))(map, (void *)(&(from)))) 76 #define THREAD_SWITCH(thread, option, option_time) \ 77 ((*(_rpc_glue_vector->thread_switch))((void *)(&(thread)))) 78 #define THREAD_DEPRESS_ABORT(act) \ 79 ((*(_rpc_glue_vector->thread_depress_abort))(act)) 80 81 /* 82 * User machine dependent macros for mach rpc 83 */ 84 #define MACH_RPC(sig_ptr, sig_size, id, dest, arg_list) \ 85 mach_rpc_trap(dest, id, (mach_rpc_signature_t) sig_ptr, sig_size) 86 87 /* 88 * Kernel machine dependent macros for mach rpc 89 * 90 * User args (argv) begin two words above the frame pointer (past saved ebp 91 * and return address) on the user stack. Return code is stored in register 92 * ecx, by convention (must be a caller-saves register, to survive return 93 * from server work function). The user space instruction pointer is eip, 94 * and the user stack pointer is uesp. 95 */ 96 #define MACH_RPC_ARGV(act) ( (char *)(USER_REGS(act)->ebp + 8) ) 97 #define MACH_RPC_RET(act) ( USER_REGS(act)->ecx ) 98 #define MACH_RPC_UIP(act) ( USER_REGS(act)->eip ) 99 #define MACH_RPC_USP(act) ( USER_REGS(act)->uesp ) 100 101 102 extern boolean_t klcopyin( 103 mach_port_t, 104 void *); 105 106 extern boolean_t klcopyout( 107 mach_port_t, 108 void *); 109 110 extern boolean_t klcopyinstr( 111 mach_port_t, 112 void *); 113 114 extern kern_return_t klthread_switch( 115 void *); 116 117 /* 118 * The various bits of the type field of the routine_arg_descriptor 119 */ 120 121 /* The basic types */ 122 123 #define TYPE_SHIFT 0 124 #define MACH_RPC_PORT (1 << TYPE_SHIFT) 125 #define MACH_RPC_ARRAY (1 << (TYPE_SHIFT + 1)) 126 #define MACH_RPC_VARIABLE (1 << (TYPE_SHIFT + 2)) 127 #define LAST_TYPE_BIT (TYPE_SHIFT+3) 128 129 /* XXX Port arrays need not be variable arrays, as assumed below. Fixme. */ 130 #define MACH_RPC_ARRAY_FIX (MACH_RPC_ARRAY) 131 #define MACH_RPC_ARRAY_FIXED (MACH_RPC_ARRAY) 132 #define MACH_RPC_ARRAY_VAR (MACH_RPC_ARRAY | MACH_RPC_VARIABLE) 133 #define MACH_RPC_ARRAY_VARIABLE (MACH_RPC_ARRAY | MACH_RPC_VARIABLE) 134 #define MACH_RPC_PORT_ARRAY (MACH_RPC_PORT | MACH_RPC_ARRAY_VAR) 135 136 /* Argument direction bits */ 137 138 #define DIRECT_SHIFT LAST_TYPE_BIT 139 #define DIRECTION_SHIFT LAST_TYPE_BIT 140 #define MACH_RPC_IN (1 << DIRECTION_SHIFT) 141 #define MACH_RPC_OUT (1 << (DIRECTION_SHIFT + 1)) 142 #define LAST_DIRECT_BIT (DIRECTION_SHIFT + 2) 143 #define LAST_DIRECTION_BIT (DIRECTION_SHIFT + 2) 144 145 #define MACH_RPC_INOUT (MACH_RPC_IN | MACH_RPC_OUT) 146 147 /* Persist and pointer bit */ 148 149 #define POINTER_SHIFT LAST_DIRECTION_BIT 150 #define MACH_RPC_POINTER (1 << POINTER_SHIFT) 151 #define LAST_POINTER_BIT (POINTER_SHIFT + 1) 152 153 /* Port disposition bits */ 154 155 #define NAME_SHIFT LAST_POINTER_BIT 156 #define MACH_RPC_RECEIVE (1 << NAME_SHIFT) 157 #define MACH_RPC_SEND (2 << NAME_SHIFT) 158 #define MACH_RPC_SEND_ONCE (3 << NAME_SHIFT) 159 #define LAST_NAME_BIT (NAME_SHIFT + 2) 160 161 #define ACTION_SHIFT LAST_NAME_BIT 162 #define MACH_RPC_MOVE (1 << ACTION_SHIFT) 163 #define MACH_RPC_COPY (2 << ACTION_SHIFT) 164 #define MACH_RPC_MAKE (3 << ACTION_SHIFT) 165 #define LAST_ACTION_BIT (ACTION_SHIFT + 2) 166 167 #define MACH_RPC_MOVE_RECEIVE (MACH_RPC_MOVE | MACH_RPC_RECEIVE) 168 #define MACH_RPC_MOVE_SEND (MACH_RPC_MOVE | MACH_RPC_SEND) 169 #define MACH_RPC_COPY_SEND (MACH_RPC_COPY | MACH_RPC_SEND) 170 #define MACH_RPC_MAKE_SEND (MACH_RPC_MAKE | MACH_RPC_SEND) 171 #define MACH_RPC_MOVE_SEND_ONCE (MACH_RPC_MOVE | MACH_RPC_SEND_ONCE) 172 #define MACH_RPC_MAKE_SEND_ONCE (MACH_RPC_MAKE | MACH_RPC_SEND_ONCE) 173 174 /* Hint for virtual vs. physical copy */ 175 176 #define OPTION_SHIFT LAST_ACTION_BIT 177 #define MACH_RPC_PHYSICAL_COPY (1 << OPTION_SHIFT) 178 #define MACH_RPC_VIRTUAL_COPY (1 << (OPTION_SHIFT + 1)) 179 #define LAST_OPTION_BIT (OPTION_SHIFT + 2) 180 181 /* Deallocate? */ 182 183 #define DEALLOCATE_SHIFT LAST_OPTION_BIT 184 #define MACH_RPC_DEALLOCATE (1 << DEALLOCATE_SHIFT) 185 #define LAST_DEALLOCATE_BIT (DEALLOCATE_SHIFT + 1) 186 187 /* Argument is already on the stack */ 188 189 #define ONSTACK_SHIFT LAST_DEALLOCATE_BIT 190 #define MACH_RPC_ONSTACK (1 << ONSTACK_SHIFT) 191 #define LAST_ONSTACK_BIT (ONSTACK_SHIFT + 1) 192 193 /* Is variable array bounded? Derived from type and arg.size */ 194 195 #define BOUND_SHIFT LAST_ONSTACK_BIT 196 #define MACH_RPC_BOUND (1 << BOUND_SHIFT) 197 #define MACH_RPC_UNBOUND (0) 198 #define BOUND MACH_RPC_BOUND 199 #define UNBND MACH_RPC_UNBOUND 200 #define LAST_BOUND_BIT (BOUND_SHIFT + 1) 201 202 /* 203 * Temporarily map old MiG names to the new names, until the 204 * new MiG is ready. This allows us to continue developing the 205 * RPC path while MiG is being enhanced. *Temporary* 206 */ 207 #define OLD 208 #ifdef OLD 209 #define ROUTINE_ARG_PORT MACH_RPC_PORT 210 #define ROUTINE_ARG_FIXED_ARRAY MACH_RPC_ARRAY_FIXED 211 #define ROUTINE_ARG_VAR_ARRAY MACH_RPC_ARRAY_VARIABLE 212 213 #define ROUTINE_ARG_IN MACH_RPC_IN 214 #define ROUTINE_ARG_OUT MACH_RPC_OUT 215 #define ROUTINE_ARG_INOUT MACH_RPC_INOUT 216 217 #define direction type 218 #endif /* OLD */ 219 220 221 /* 222 * Basic mach rpc types. 223 */ 224 typedef unsigned int routine_arg_type; 225 typedef unsigned int routine_arg_offset; 226 typedef unsigned int routine_arg_size; 227 228 /* 229 * Definition for MIG-generated server stub routines. These routines 230 * unpack the request message, call the server procedure, and pack the 231 * reply message. 232 */ 233 typedef void (*mig_stub_routine_t) (mach_msg_header_t *InHeadP, 234 mach_msg_header_t *OutHeadP); 235 236 typedef mig_stub_routine_t mig_routine_t; 237 238 /* 239 * Definition for MIG-generated server routine. This routine takes a 240 * message, and returns the appropriate stub function for handling that 241 * message. 242 */ 243 typedef mig_routine_t (*mig_server_routine_t) (mach_msg_header_t *InHeadP); 244 245 246 /* 247 * Definition for server implementation routines. This is the routine 248 * called by the MIG-generated server stub routine. 249 */ 250 typedef kern_return_t (*mig_impl_routine_t)(void); 251 252 /* 253 * Definitions for a signature's argument and routine descriptor's. 254 */ 255 struct routine_arg_descriptor { 256 routine_arg_type type; /* Port, Array, etc. */ 257 routine_arg_size size; /* element size in bytes */ 258 routine_arg_size count; /* number of elements */ 259 routine_arg_offset offset; /* Offset in list of routine args */ 260 }; 261 typedef struct routine_arg_descriptor *routine_arg_descriptor_t; 262 263 struct routine_descriptor { 264 mig_impl_routine_t impl_routine; /* Server work func pointer */ 265 mig_stub_routine_t stub_routine; /* Unmarshalling func pointer */ 266 unsigned int argc; /* Number of argument words */ 267 unsigned int descr_count; /* Number of complex argument */ 268 /* descriptors */ 269 struct routine_arg_descriptor * 270 arg_descr; /* Pointer to beginning of */ 271 /* the arg_descr array */ 272 unsigned int max_reply_msg; /* Max size for reply msg */ 273 }; 274 typedef struct routine_descriptor *routine_descriptor_t; 275 276 struct mach_rpc_signature { 277 struct routine_descriptor rd; 278 struct routine_arg_descriptor rad[1]; 279 }; 280 typedef struct mach_rpc_signature *mach_rpc_signature_t; 281 282 /* 283 * A subsystem describes a set of server routines that can be invoked by 284 * mach_rpc() on the ports that are registered with the subsystem. For 285 * each routine, the routine number is given, along with the 286 * address of the implementation function in the server and a 287 * description of the arguments of the routine (it's "signature"). 288 * 289 * This structure definition is only a template for what is really a 290 * variable-length structure (generated by MIG for each subsystem). 291 * The actual structures do not always have one entry in the routine 292 * array, and also have a varying number of entries in the arg_descr 293 * array. Each routine has an array of zero or more arg descriptors 294 * one for each complex arg. These arrays are all catenated together 295 * to form the arg_descr field of the subsystem struct. The 296 * arg_descr field of each routine entry points to a unique sub-sequence 297 * within this catenated array. The goal is to keep everything 298 * contiguous. 299 */ 300 struct rpc_subsystem { 301 struct subsystem *subsystem; /* Reserved for system use */ 302 303 mach_msg_id_t start; /* Min routine number */ 304 mach_msg_id_t end; /* Max routine number + 1 */ 305 unsigned int maxsize; /* Max mach_msg size */ 306 vm_address_t base_addr; /* Address of this struct in user */ 307 308 struct routine_descriptor /* Array of routine descriptors */ 309 routine[1 /* Actually, (start-end+1) */ 310 ]; 311 312 struct routine_arg_descriptor 313 arg_descriptor[1 /* Actually, the sum of the descr_ */ 314 ]; /* count fields for all routines */ 315 }; 316 typedef struct rpc_subsystem *rpc_subsystem_t; 317 318 #define RPC_SUBSYSTEM_NULL ((rpc_subsystem_t) 0) 319 320 /* 321 * This structure is user-visible, both to user-mode RPC code 322 * and to kernel-loaded servers. 323 */ 324 typedef struct rpc_port { 325 326 /* 327 * Initial sub-structure in common with ipc_pset and rpc_port 328 * First element is an ipc_object 329 */ 330 struct ipc_common_data rpc_port_comm; 331 332 unsigned int rpc_unused_pad[1]; /* XXX unused */ 333 334 } *rpc_port_t; 335 336 #define rp_object rpc_port_comm.icd_object 337 /* access to rp_object internals not needed */ 338 #define rp_kobject rpc_port_comm.icd_kobject 339 #define rp_subsystem rpc_port_comm.icd_subsystem 340 #define rp_sobject rpc_port_comm.icd_sobject 341 #define rp_sbits rpc_port_comm.icd_sbits 342 #define rp_receiver_name rpc_port_comm.icd_receiver_name 343 344 345 /* 346 * New RPC declarations 347 * 348 * First pass at definitions and types for the new rpc service. 349 * This is subject to revision. 350 */ 351 352 /* 353 * RPC macros 354 */ 355 356 #define RPC_MASK(shift,last) \ 357 ( ((1 << ((last)-(shift)))-1) << (shift) ) 358 359 #define RPC_FIELD(field,shift,last) \ 360 ( (field) & (((1 << ((last)-(shift)))-1) << (shift)) ) 361 362 #define RPC_BOUND(dsc) \ 363 (((RPC_FIELD((dsc).type,TYPE_SHIFT+1,TYPE_SHIFT+3) == \ 364 MACH_RPC_ARRAY_VARIABLE) && (dsc).count != 0) ? MACH_RPC_BOUND : 0) 365 366 #define ROUNDUP2(x,n) ((((unsigned)(x)) + (n) - 1) & ~((n)-1)) 367 #define ROUNDWORD(x) ROUNDUP2(x,sizeof(int)) 368 369 /* 370 * RPC errors 371 * 372 * Display and process errors of different severity, from just for 373 * information only to fatal (panic). Error code colors indicate how 374 * difficult it is for the subsystem to handle the error correctly. 375 * The implication is that, for example, early versions of the code may 376 * not be handling code red errors properly. The code should use this 377 * facility instead of regular printf's. 378 */ 379 380 #define MACH_RPC_DEBUG 1 381 382 #define ERR_INFO 1 /* purely informational */ 383 #define ERR_GREEN 2 /* easily handled error */ 384 #define ERR_YELLOW 3 /* medium difficult error */ 385 #define ERR_RED 4 /* difficult to handle error */ 386 #define ERR_FATAL 5 /* unrecoverable error, panic */ 387 388 #if MACH_RPC_DEBUG > 1 389 #define rpc_error(E,S) \ 390 printf("RPC error "); \ 391 rpc_error_show_severity(S); \ 392 printf("in file \"%s\", line %d: ", __FILE__, __LINE__); \ 393 printf E ; \ 394 printf("\n"); \ 395 rpc_error_severity(S) 396 #else 397 #define rpc_error(E,S) \ 398 if ((S) == ERR_FATAL || (S) == ERR_RED) { \ 399 printf("RPC error "); \ 400 rpc_error_show_severity(S); \ 401 printf("in file \"%s\", line %d: ", __FILE__, __LINE__); \ 402 printf E ; \ 403 printf("\n"); \ 404 rpc_error_severity(S); \ 405 } 406 #endif /* MACH_RPC_DEBUG */ 407 408 /* 409 * RPC buffer size and break points 410 * 411 * These values define the rpc buffer size on the kernel stack, 412 * and break point values for switching to virtual copy (cow). 413 * This should be in a machine dependent include file. All sizes 414 * are in word (sizeof(int)) units. 415 */ 416 417 #define RPC_KBUF_SIZE 16 /* kernel stack buffer size (ints) */ 418 #define RPC_COW_SIZE 1024 /* size where COW is a win (ints) */ 419 #define RPC_DESC_COUNT 4 /* default descriptor count */ 420 421 422 /* 423 * RPC copy state 424 * 425 * Record the rpc copy state for arrays, so we can unwind our state 426 * during error processing. There is one entry per complex (signatured) 427 * argument. The first entry is marked COPY_TYPE_ALLOC_KRN if this record 428 * itself was kalloc'd because the number of complex arg descriptors 429 * exceeded the default value (RPC_DESC_COUNT). This is not a conflict 430 * since the first argument is always the destination port, never an array. 431 */ 432 433 #define COPY_TYPE_NO_COPY 0 /* nothing special */ 434 #define COPY_TYPE_ON_KSTACK 1 /* array is on kernel stack */ 435 #define COPY_TYPE_ON_SSTACK 2 /* array is on server stack */ 436 #define COPY_TYPE_VIRTUAL_IN 3 /* vm_map_copyin part of cow */ 437 #define COPY_TYPE_VIRTUAL_OUT_SVR 4 /* map cpyout svr part of cow */ 438 #define COPY_TYPE_VIRTUAL_OUT_CLN 5 /* map cpyout cln part of cow */ 439 #define COPY_TYPE_ALLOC_KRN 6 /* kernel kalloc'd for array */ 440 #define COPY_TYPE_ALLOC_SVR 7 /* vm_alloc'd in server space */ 441 #define COPY_TYPE_ALLOC_CLN 8 /* vm_alloc'd in client space */ 442 #define COPY_TYPE_PORT 9 /* plain port translated */ 443 #define COPY_TYPE_PORT_ARRAY 10 /* port array translated */ 444 445 446 /* 447 * RPC types 448 */ 449 450 typedef int mach_rpc_id_t; 451 typedef int mach_rpc_return_t; 452 typedef unsigned int mach_rpc_size_t; 453 typedef unsigned int mach_rpc_offset_t; 454 455 struct rpc_copy_state { 456 unsigned copy_type; /* what kind of copy */ 457 vm_offset_t alloc_addr; /* address to free */ 458 }; 459 typedef struct rpc_copy_state *rpc_copy_state_t; 460 typedef struct rpc_copy_state rpc_copy_state_data_t; 461 462 typedef boolean_t (*copyfunc_t)(const char *, char *, vm_size_t); 463 464 465 /* 466 * RPC function declarations 467 */ 468 469 #ifdef MACH_KERNEL 470 471 extern 472 mach_rpc_return_t mach_rpc_trap( 473 mach_port_t dest_port, 474 mach_rpc_id_t routine_num, 475 mach_rpc_signature_t signature_ptr, 476 mach_rpc_size_t signature_size ); 477 478 extern 479 mach_rpc_return_t mach_rpc_return_trap( void ); 480 481 extern 482 mach_rpc_return_t mach_rpc_return_error( void ); 483 484 void mach_rpc_return_wrapper( void ); 485 486 void rpc_upcall( 487 vm_offset_t stack, 488 vm_offset_t new_stack, 489 vm_offset_t server_func, 490 int return_code ); 491 492 void rpc_error_severity( int severity ); 493 void rpc_error_show_severity( int severity ); 494 unsigned int name_rpc_to_ipc( unsigned int action ); 495 496 void clean_port_array( 497 ipc_object_t * array, 498 unsigned count, 499 unsigned cooked, 500 unsigned direct ); 501 502 void unwind_rpc_state( 503 routine_descriptor_t routine, 504 rpc_copy_state_t state, 505 int * arg_buf ); 506 507 kern_return_t unwind_invoke_state( 508 thread_act_t thr_act ); 509 510 kern_return_t rpc_invke_args_in( 511 routine_descriptor_t routine, 512 rpc_copy_state_t state, 513 int * arg_buf, 514 copyfunc_t infunc ); 515 516 kern_return_t rpc_invke_args_out( 517 routine_descriptor_t routine, 518 rpc_copy_state_t state, 519 int * arg_buf, 520 int ** new_sp, 521 copyfunc_t outfunc ); 522 523 kern_return_t rpc_reply_args_in( 524 routine_descriptor_t routine, 525 rpc_copy_state_t state, 526 int * svr_buf, 527 copyfunc_t infunc ); 528 529 kern_return_t rpc_reply_args_out( 530 routine_descriptor_t routine, 531 rpc_copy_state_t state, 532 int * svr_buf, 533 int * cln_buf, 534 copyfunc_t outfunc ); 535 536 #endif /* MACH_KERNEL */ 537 538 #ifndef __alpha 539 /* 540 * This is machine dependent and doesn't belong here. 541 * jfraser 542 */ 543 544 /* 545 * Glue function extern declarations 546 */ 547 extern kern_return_t machine_rpc_simple( 548 int, 549 int, 550 void *); 551 552 extern kern_return_t klthread_depress_abort( 553 mach_port_t); 554 555 #endif /* __alpha */ 556 /* 557 * An rpc_glue_vector_t defined either by the kernel or by crt0 558 */ 559 extern rpc_glue_vector_t _rpc_glue_vector; 560 561 /* 562 * libmach helper functions: 563 */ 564 extern rpc_subsystem_t mach_subsystem_join( 565 rpc_subsystem_t, 566 rpc_subsystem_t, 567 unsigned int *, 568 void *(* )(int)); 569 570 571 /* Allocate memory for out-of-line mig structures */ 572 extern void mig_allocate(vm_address_t *, vm_size_t); 573 574 /* Deallocate memory used for out-of-line mig structures */ 575 extern void mig_deallocate(vm_address_t, vm_size_t); 576 577 578 579 580 #endif /* _MACH_RPC_H_ */ 581 582 583