X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/b7266188b87f3620ec3f9f717e57194a7dd989fe..7e41aa883dd258f888d0470250eead40a53ef1f5:/osfmk/ipc/ipc_port.h diff --git a/osfmk/ipc/ipc_port.h b/osfmk/ipc/ipc_port.h index 4998a84bc..92bb0e70a 100644 --- a/osfmk/ipc/ipc_port.h +++ b/osfmk/ipc/ipc_port.h @@ -74,7 +74,6 @@ #if MACH_KERNEL_PRIVATE -#include #include #include #include @@ -84,6 +83,7 @@ #include #include +#include #include #include @@ -120,60 +120,63 @@ struct ipc_port { struct ipc_object ip_object; struct ipc_mqueue ip_messages; + natural_t ip_sprequests:1, /* send-possible requests outstanding */ + ip_spimportant:1, /* ... at least one is importance donating */ + ip_impdonation:1, /* port supports importance donation */ + ip_tempowner:1, /* dont give donations to current receiver */ + ip_guarded:1, /* port guarded (use context value as guard) */ + ip_strict_guard:1, /* Strict guarding; Prevents user manipulation of context values directly */ + ip_reserved:2, + ip_impcount:24; /* number of importance donations in nested queue */ + union { struct ipc_space *receiver; struct ipc_port *destination; ipc_port_timestamp_t timestamp; } data; - ipc_kobject_t ip_kobject; - mach_port_mscount_t ip_mscount; - mach_port_rights_t ip_srights; - mach_port_rights_t ip_sorights; - + union { + ipc_kobject_t kobject; + ipc_importance_task_t imp_task; + uintptr_t alias; + } kdata; + struct ipc_port *ip_nsrequest; struct ipc_port *ip_pdrequest; - struct ipc_port_request *ip_dnrequests; - - unsigned int ip_pset_count; + struct ipc_port_request *ip_requests; struct ipc_kmsg *ip_premsg; + mach_vm_address_t ip_context; -#if NORMA_VM - /* - * These fields are needed for the use of XMM. - * Few ports need this information; it should - * be kept in XMM instead (TBD). XXX - */ - long ip_norma_xmm_object_refs; - struct ipc_port *ip_norma_xmm_object; -#endif + mach_port_mscount_t ip_mscount; + mach_port_rights_t ip_srights; + mach_port_rights_t ip_sorights; #if MACH_ASSERT #define IP_NSPARES 4 #define IP_CALLSTACK_MAX 16 - queue_chain_t ip_port_links; /* all allocated ports */ +/* queue_chain_t ip_port_links;*//* all allocated ports */ thread_t ip_thread; /* who made me? thread context */ unsigned long ip_timetrack; /* give an idea of "when" created */ - natural_t ip_callstack[IP_CALLSTACK_MAX]; /* stack trace */ + uintptr_t ip_callstack[IP_CALLSTACK_MAX]; /* stack trace */ unsigned long ip_spares[IP_NSPARES]; /* for debugging */ #endif /* MACH_ASSERT */ - uintptr_t alias; - -#if CONFIG_MACF_MACH - struct label ip_label; -#endif -}; +} __attribute__((__packed__)); #define ip_references ip_object.io_references #define ip_bits ip_object.io_bits +#define ip_receiver_name ip_messages.imq_receiver_name +#define ip_in_pset ip_messages.imq_in_pset + #define ip_receiver data.receiver #define ip_destination data.destination #define ip_timestamp data.timestamp -#define ip_receiver_name ip_messages.imq_receiver_name +#define ip_kobject kdata.kobject +#define ip_imp_task kdata.imp_task +#define ip_alias kdata.alias #define IP_NULL IPC_PORT_NULL #define IP_DEAD IPC_PORT_DEAD @@ -184,13 +187,15 @@ struct ipc_port { #define ip_lock(port) io_lock(&(port)->ip_object) #define ip_lock_try(port) io_lock_try(&(port)->ip_object) #define ip_unlock(port) io_unlock(&(port)->ip_object) -#define ip_check_unlock(port) io_check_unlock(&(port)->ip_object) #define ip_reference(port) io_reference(&(port)->ip_object) #define ip_release(port) io_release(&(port)->ip_object) #define ip_kotype(port) io_kotype(&(port)->ip_object) +#define ip_full_kernel(port) imq_full_kernel(&(port)->ip_messages) +#define ip_full(port) imq_full(&(port)->ip_messages) + /* * JMM - Preallocation flag * This flag indicates that there is a message buffer preallocated for this @@ -215,7 +220,7 @@ MACRO_BEGIN \ (port)->ip_premsg = IKM_NULL; \ MACRO_END - +/* JMM - address alignment/packing for LP64 */ struct ipc_port_request { union { struct ipc_port *port; @@ -234,6 +239,17 @@ struct ipc_port_request { #define ipr_soright notify.port #define ipr_name name.name +/* + * Use the low bits in the ipr_soright to specify the request type + */ +#define IPR_SOR_SPARM_MASK 1 /* send-possible armed */ +#define IPR_SOR_SPREQ_MASK 2 /* send-possible requested */ +#define IPR_SOR_SPBIT_MASK 3 /* combo */ +#define IPR_SOR_SPARMED(sor) (((uintptr_t)(sor) & IPR_SOR_SPARM_MASK) != 0) +#define IPR_SOR_SPREQ(sor) (((uintptr_t)(sor) & IPR_SOR_SPREQ_MASK) != 0) +#define IPR_SOR_PORT(sor) ((ipc_port_t)((uintptr_t)(sor) & ~IPR_SOR_SPBIT_MASK)) +#define IPR_SOR_MAKE(p,m) ((ipc_port_t)((uintptr_t)(p) | (m))) + extern lck_grp_t ipc_lck_grp; extern lck_attr_t ipc_lck_attr; @@ -243,17 +259,16 @@ extern lck_attr_t ipc_lck_attr; * when it is taken. */ -decl_lck_mtx_data(extern,ipc_port_multiple_lock_data) -extern lck_mtx_ext_t ipc_port_multiple_lock_data_ext; +extern lck_spin_t ipc_port_multiple_lock_data; #define ipc_port_multiple_lock_init() \ - lck_mtx_init_ext(&ipc_port_multiple_lock_data, &ipc_port_multiple_lock_data_ext, &ipc_lck_grp, &ipc_lck_attr) + lck_spin_init(&ipc_port_multiple_lock_data, &ipc_lck_grp, &ipc_lck_attr) #define ipc_port_multiple_lock() \ - lck_mtx_lock(&ipc_port_multiple_lock_data) + lck_spin_lock(&ipc_port_multiple_lock_data) #define ipc_port_multiple_unlock() \ - lck_mtx_unlock(&ipc_port_multiple_lock_data) + lck_spin_unlock(&ipc_port_multiple_lock_data) /* * The port timestamp facility provides timestamps @@ -261,20 +276,8 @@ extern lck_mtx_ext_t ipc_port_multiple_lock_data_ext; * mach_port_names with port death. */ -decl_lck_mtx_data(extern,ipc_port_timestamp_lock_data) -extern lck_mtx_ext_t ipc_port_timestamp_lock_data_ext; - extern ipc_port_timestamp_t ipc_port_timestamp_data; -#define ipc_port_timestamp_lock_init() \ - lck_mtx_init_ext(&ipc_port_timestamp_lock_data, &ipc_port_timestamp_lock_data_ext, &ipc_lck_grp, &ipc_lck_attr) - -#define ipc_port_timestamp_lock() \ - lck_mtx_lock(&ipc_port_timestamp_lock_data) - -#define ipc_port_timestamp_unlock() \ - lck_mtx_unlock(&ipc_port_timestamp_lock_data) - /* Retrieve a port timestamp value */ extern ipc_port_timestamp_t ipc_port_timestamp(void); @@ -297,32 +300,67 @@ extern ipc_port_timestamp_t ipc_port_timestamp(void); MACH_PORT_RIGHT_SEND, \ (ipc_object_t *) (portp)) -/* Allocate a dead-name request slot */ +/* Allocate a notification request slot */ +#if IMPORTANCE_INHERITANCE +extern kern_return_t +ipc_port_request_alloc( + ipc_port_t port, + mach_port_name_t name, + ipc_port_t soright, + boolean_t send_possible, + boolean_t immediate, + ipc_port_request_index_t *indexp, + boolean_t *importantp); +#else extern kern_return_t -ipc_port_dnrequest( +ipc_port_request_alloc( ipc_port_t port, mach_port_name_t name, ipc_port_t soright, + boolean_t send_possible, + boolean_t immediate, ipc_port_request_index_t *indexp); +#endif /* IMPORTANCE_INHERITANCE */ -/* Grow a port's table of dead-name requests */ -extern kern_return_t ipc_port_dngrow( +/* Grow one of a port's tables of notifcation requests */ +extern kern_return_t ipc_port_request_grow( ipc_port_t port, ipc_table_elems_t target_size); -/* Cancel a dead-name request and return the send-once right */ -extern ipc_port_t ipc_port_dncancel( +/* Return the type(s) of notification requests outstanding */ +extern mach_port_type_t ipc_port_request_type( ipc_port_t port, mach_port_name_t name, ipc_port_request_index_t index); -#define ipc_port_dnrename(port, index, oname, nname) \ +/* Cancel a notification request and return the send-once right */ +extern ipc_port_t ipc_port_request_cancel( + ipc_port_t port, + mach_port_name_t name, + ipc_port_request_index_t index); + +/* Arm any delayed send-possible notification */ +#if IMPORTANCE_INHERITANCE +extern boolean_t ipc_port_request_sparm( + ipc_port_t port, + mach_port_name_t name, + ipc_port_request_index_t index, + mach_msg_option_t option); +#else +extern boolean_t ipc_port_request_sparm( + ipc_port_t port, + mach_port_name_t name, + ipc_port_request_index_t index); +#endif /* IMPORTANCE_INHERITANCE */ + +/* Macros for manipulating a port's dead name notificaiton requests */ +#define ipc_port_request_rename(port, index, oname, nname) \ MACRO_BEGIN \ ipc_port_request_t ipr, table; \ \ assert(ip_active(port)); \ \ - table = port->ip_dnrequests; \ + table = port->ip_requests; \ assert(table != IPR_NULL); \ \ ipr = &table[index]; \ @@ -331,6 +369,7 @@ MACRO_BEGIN \ ipr->ipr_name = nname; \ MACRO_END + /* Make a port-deleted request */ extern void ipc_port_pdrequest( ipc_port_t port, @@ -375,8 +414,11 @@ extern kern_return_t ipc_port_alloc_name( /* Generate dead name notifications */ extern void ipc_port_dnnotify( - ipc_port_t port, - ipc_port_request_t dnrequests); + ipc_port_t port); + +/* Generate send-possible notifications */ +extern void ipc_port_spnotify( + ipc_port_t port); /* Destroy a port */ extern void ipc_port_destroy( @@ -389,6 +431,36 @@ ipc_port_check_circularity( ipc_port_t port, ipc_port_t dest); +#if IMPORTANCE_INHERITANCE + +enum { + IPID_OPTION_NORMAL = 0, /* normal boost */ + IPID_OPTION_SENDPOSSIBLE = 1, /* send-possible induced boost */ +}; + +/* apply importance delta to port only */ +extern mach_port_delta_t +ipc_port_impcount_delta( + ipc_port_t port, + mach_port_delta_t delta, + ipc_port_t base); + +/* apply importance delta to port, and return task importance for update */ +extern boolean_t +ipc_port_importance_delta_internal( + ipc_port_t port, + natural_t options, + mach_port_delta_t *deltap, + ipc_importance_task_t *imp_task); + +/* Apply an importance delta to a port and reflect change in receiver task */ +extern boolean_t +ipc_port_importance_delta( + ipc_port_t port, + natural_t options, + mach_port_delta_t delta); +#endif /* IMPORTANCE_INHERITANCE */ + /* Make a send-once notify port from a receive right */ extern ipc_port_t ipc_port_lookup_notify( ipc_space_t space, @@ -419,10 +491,20 @@ extern mach_port_name_t ipc_port_copyout_send( extern void ipc_port_release_send( ipc_port_t port); +extern void ipc_port_reference( + ipc_port_t port); + +extern void ipc_port_release( + ipc_port_t port); + #endif /* KERNEL_PRIVATE */ #if MACH_KERNEL_PRIVATE +/* Make a naked send-once right from a locked and active receive right */ +extern ipc_port_t ipc_port_make_sonce_locked( + ipc_port_t port); + /* Make a naked send-once right from a receive right */ extern ipc_port_t ipc_port_make_sonce( ipc_port_t port); @@ -435,6 +517,10 @@ extern void ipc_port_release_sonce( extern void ipc_port_release_receive( ipc_port_t port); +/* finalize the destruction of a port before it gets freed */ +extern void ipc_port_finalize( + ipc_port_t port); + /* Allocate a port in a special space */ extern ipc_port_t ipc_port_alloc_special( ipc_space_t space); @@ -463,12 +549,6 @@ extern void ipc_port_debug_init(void); #define ipc_port_dealloc_reply(port) \ ipc_port_dealloc_special((port), ipc_space_reply) -#define ipc_port_reference(port) \ - ipc_object_reference(&(port)->ip_object) - -#define ipc_port_release(port) \ - ipc_object_release(&(port)->ip_object) - #endif /* MACH_KERNEL_PRIVATE */ #endif /* _IPC_IPC_PORT_H_ */