X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/fe8ab488e9161c46dd9885d58fc52996dc0249ff..b226f5e54a60dc81db17b1260381d7dbfea3cdf1:/osfmk/ipc/ipc_port.h diff --git a/osfmk/ipc/ipc_port.h b/osfmk/ipc/ipc_port.h index ec1f3efc9..16addb831 100644 --- a/osfmk/ipc/ipc_port.h +++ b/osfmk/ipc/ipc_port.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2008 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2016 Apple Computer, Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -72,9 +72,8 @@ #ifndef _IPC_IPC_PORT_H_ #define _IPC_IPC_PORT_H_ -#if MACH_KERNEL_PRIVATE +#ifdef MACH_KERNEL_PRIVATE -#include #include #include @@ -85,6 +84,7 @@ #include #include +#include #include #include @@ -129,17 +129,21 @@ struct ipc_port { union { ipc_kobject_t kobject; ipc_importance_task_t imp_task; - uintptr_t alias; + ipc_port_t sync_inheritor_port; + struct knote *sync_inheritor_knote; + struct turnstile *sync_inheritor_ts; } kdata; - + struct ipc_port *ip_nsrequest; struct ipc_port *ip_pdrequest; struct ipc_port_request *ip_requests; - struct ipc_kmsg *ip_premsg; + union { + struct ipc_kmsg *premsg; + struct turnstile *send_turnstile; + SLIST_ENTRY(ipc_port) dealloc_elm; + } kdata2; - mach_port_mscount_t ip_mscount; - mach_port_rights_t ip_srights; - mach_port_rights_t ip_sorights; + mach_vm_address_t ip_context; natural_t ip_sprequests:1, /* send-possible requests outstanding */ ip_spimportant:1, /* ... at least one is importance donating */ @@ -147,21 +151,27 @@ struct ipc_port { 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 */ - - mach_vm_address_t ip_context; + ip_specialreply:1, /* port is a special reply port */ + ip_sync_link_state:3, /* link the special reply port to destination port/ Workloop */ + ip_impcount:22; /* number of importance donations in nested queue */ + 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 */ uintptr_t ip_callstack[IP_CALLSTACK_MAX]; /* stack trace */ unsigned long ip_spares[IP_NSPARES]; /* for debugging */ #endif /* MACH_ASSERT */ +#if DEVELOPMENT || DEBUG + uint8_t ip_srp_lost_link:1, /* special reply port turnstile link chain broken */ + ip_srp_msg_sent:1; /* special reply port msg sent */ +#endif }; @@ -169,7 +179,7 @@ struct ipc_port { #define ip_bits ip_object.io_bits #define ip_receiver_name ip_messages.imq_receiver_name -#define ip_pset_count ip_messages.imq_pset_count +#define ip_in_pset ip_messages.imq_in_pset #define ip_receiver data.receiver #define ip_destination data.destination @@ -177,7 +187,63 @@ struct ipc_port { #define ip_kobject kdata.kobject #define ip_imp_task kdata.imp_task -#define ip_alias kdata.alias +#define ip_sync_inheritor_port kdata.sync_inheritor_port +#define ip_sync_inheritor_knote kdata.sync_inheritor_knote +#define ip_sync_inheritor_ts kdata.sync_inheritor_ts + +#define ip_premsg kdata2.premsg +#define ip_send_turnstile kdata2.send_turnstile +#define ip_dealloc_elm kdata2.dealloc_elm + +#define port_send_turnstile(port) (IP_PREALLOC(port) ? (port)->ip_premsg->ikm_turnstile : (port)->ip_send_turnstile) + +#define set_port_send_turnstile(port, value) \ +MACRO_BEGIN \ +if (IP_PREALLOC(port)) { \ + (port)->ip_premsg->ikm_turnstile = (value); \ +} else { \ + (port)->ip_send_turnstile = (value); \ +} \ +MACRO_END + +#define port_send_turnstile_address(port) \ +(IP_PREALLOC(port) ? &((port)->ip_premsg->ikm_turnstile) : &((port)->ip_send_turnstile)) + +#define port_rcv_turnstile_address(port) (NULL) + + +/* + * SYNC IPC state flags for special reply port. + * + * PORT_SYNC_LINK_ANY + * Special reply port is not linked to any other port + * or WL and linkage should be allowed. + * + * PORT_SYNC_LINK_PORT + * Special reply port is linked to the port and + * ip_sync_inheritor_port contains the inheritor + * port. + * + * PORT_SYNC_LINK_WORKLOOP_KNOTE + * Special reply port is linked to a WL (via a knote). + * ip_sync_inheritor_knote contains a pointer to the knote + * the port is stashed on. + * + * PORT_SYNC_LINK_WORKLOOP_STASH + * Special reply port is linked to a WL (via a knote stash). + * ip_sync_inheritor_ts contains a pointer to the turnstile with a +1 + * the port is stashed on. + * + * PORT_SYNC_LINK_NO_LINKAGE + * Message sent to special reply port, do + * not allow any linkages till receive is + * complete. + */ +#define PORT_SYNC_LINK_ANY (0) +#define PORT_SYNC_LINK_PORT (0x1) +#define PORT_SYNC_LINK_WORKLOOP_KNOTE (0x2) +#define PORT_SYNC_LINK_WORKLOOP_STASH (0x3) +#define PORT_SYNC_LINK_NO_LINKAGE (0x4) #define IP_NULL IPC_PORT_NULL #define IP_DEAD IPC_PORT_DEAD @@ -187,11 +253,19 @@ struct ipc_port { #define ip_lock_init(port) io_lock_init(&(port)->ip_object) #define ip_lock(port) io_lock(&(port)->ip_object) #define ip_lock_try(port) io_lock_try(&(port)->ip_object) +#define ip_lock_held_kdp(port) io_lock_held_kdp(&(port)->ip_object) #define ip_unlock(port) io_unlock(&(port)->ip_object) #define ip_reference(port) io_reference(&(port)->ip_object) #define ip_release(port) io_release(&(port)->ip_object) +/* get an ipc_port pointer from an ipc_mqueue pointer */ +#define ip_from_mq(mq) \ + __container_of(mq, struct ipc_port, ip_messages) + +#define ip_reference_mq(mq) ip_reference(ip_from_mq(mq)) +#define ip_release_mq(mq) ip_release(ip_from_mq(mq)) + #define ip_kotype(port) io_kotype(&(port)->ip_object) #define ip_full_kernel(port) imq_full_kernel(&(port)->ip_messages) @@ -341,18 +415,12 @@ extern ipc_port_t ipc_port_request_cancel( 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 */ + ipc_port_t port, + mach_port_name_t name, + ipc_port_request_index_t index, + mach_msg_option_t option, + mach_msg_priority_t override); /* Macros for manipulating a port's dead name notificaiton requests */ #define ipc_port_request_rename(port, index, oname, nname) \ @@ -392,9 +460,9 @@ MACRO_BEGIN \ MACRO_END /* Prepare a receive right for transmission/destruction */ -extern void ipc_port_clear_receiver( +extern boolean_t ipc_port_clear_receiver( ipc_port_t port, - queue_t links); + boolean_t should_destroy); /* Initialize a newly-allocated port */ extern void ipc_port_init( @@ -434,6 +502,68 @@ ipc_port_check_circularity( ipc_port_t dest); #if IMPORTANCE_INHERITANCE + +enum { + IPID_OPTION_NORMAL = 0, /* normal boost */ + IPID_OPTION_SENDPOSSIBLE = 1, /* send-possible induced boost */ +}; + +/* link the destination port with special reply port */ +void +ipc_port_link_special_reply_port( + ipc_port_t special_reply_port, + ipc_port_t dest_port); + +#define IPC_PORT_ADJUST_SR_NONE 0 +#define IPC_PORT_ADJUST_SR_CLEAR_SPECIAL_REPLY 0x1 +#define IPC_PORT_ADJUST_SR_ALLOW_SYNC_LINKAGE 0x2 +#define IPC_PORT_ADJUST_SR_LINK_WORKLOOP 0x4 + +#define IPC_PORT_ADJUST_SR_RECEIVED_MSG 0x8 +#define IPC_PORT_ADJUST_SR_ENABLE_EVENT 0x10 + +void +reset_ip_srp_bits(ipc_port_t special_reply_port); + +void +reset_ip_srp_msg_sent(ipc_port_t special_reply_port); + +void +set_ip_srp_msg_sent(ipc_port_t special_reply_port); + +void +set_ip_srp_lost_link(ipc_port_t special_reply_port); + +/* Adjust special reply port linkage */ +void ipc_port_adjust_special_reply_port_locked( + ipc_port_t special_reply_port, + struct knote *kn, + uint8_t flags, + boolean_t get_turnstile); + +/* Adjust special reply port linkage */ +void +ipc_port_adjust_special_reply_port( + ipc_port_t special_reply_port, + uint8_t flags, + boolean_t get_turnstile); + +turnstile_inheritor_t +ipc_port_get_special_reply_port_inheritor( + ipc_port_t special_reply_port); + +void +ipc_port_send_turnstile_prepare(ipc_port_t port); + +void +ipc_port_send_turnstile_complete(ipc_port_t port); + +struct waitq * +ipc_port_rcv_turnstile_waitq(struct waitq *waitq); + +struct turnstile * +ipc_port_rcv_turnstile(ipc_port_t port); + /* apply importance delta to port only */ extern mach_port_delta_t ipc_port_impcount_delta( @@ -445,13 +575,15 @@ ipc_port_impcount_delta( extern boolean_t ipc_port_importance_delta_internal( ipc_port_t port, - mach_port_delta_t *delta, + 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 */ @@ -477,6 +609,12 @@ extern mach_port_name_t ipc_port_copyout_send( ipc_port_t sright, ipc_space_t space); +/* Copyout a naked send right to given name */ +extern mach_port_name_t ipc_port_copyout_name_send( + ipc_port_t sright, + ipc_space_t space, + mach_port_name_t name); + #endif /* MACH_KERNEL_PRIVATE */ #if KERNEL_PRIVATE @@ -493,7 +631,7 @@ extern void ipc_port_release( #endif /* KERNEL_PRIVATE */ -#if MACH_KERNEL_PRIVATE +#ifdef 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( @@ -533,6 +671,9 @@ extern void ipc_port_track_dealloc( extern void ipc_port_debug_init(void); #endif /* MACH_ASSERT */ +extern struct turnstile *ipc_port_get_inheritor( + ipc_port_t port); + #define ipc_port_alloc_kernel() \ ipc_port_alloc_special(ipc_space_kernel) #define ipc_port_dealloc_kernel(port) \