diff options
Diffstat (limited to 'ipc/ipc_kmsg.h')
-rw-r--r-- | ipc/ipc_kmsg.h | 77 |
1 files changed, 69 insertions, 8 deletions
diff --git a/ipc/ipc_kmsg.h b/ipc/ipc_kmsg.h index c6cd77f0..9ee1aa4a 100644 --- a/ipc/ipc_kmsg.h +++ b/ipc/ipc_kmsg.h @@ -102,6 +102,46 @@ extern ipc_kmsg_t ipc_kmsg_cache[NCPUS]; #define ikm_cache() ipc_kmsg_cache[cpu_number()] +#define ikm_cache_alloc_try() \ +MACRO_BEGIN \ + ipc_kmsg_t __kmsg = ikm_cache(); \ + if (__kmsg != IKM_NULL) { \ + ikm_cache() = IKM_NULL; \ + ikm_check_initialized(__kmsg, IKM_SAVED_KMSG_SIZE); \ + } \ + __kmsg; \ +MACRO_END + +#define ikm_cache_alloc() \ +MACRO_BEGIN \ + ipc_kmsg_t __kmsg = ikm_cache_alloc_try(); \ + if (!__kmsg) { \ + __kmsg = ikm_alloc(IKM_SAVED_MSG_SIZE); \ + if (__kmsg != IKM_NULL) \ + ikm_init(__kmsg, IKM_SAVED_MSG_SIZE); \ + } \ + __kmsg; \ +MACRO_END + +#define ikm_cache_free_try(kmsg) \ +MACRO_BEGIN \ + int __success = 0; \ + if (ikm_cache() == IKM_NULL) { \ + ikm_cache() = (kmsg); \ + __success = 1; \ + } \ + __success; \ +MACRO_END + +#define ikm_cache_free(kmsg) \ +MACRO_BEGIN \ + if (((kmsg)->ikm_size == IKM_SAVED_KMSG_SIZE) && \ + (ikm_cache() == IKM_NULL)) \ + ikm_cache() = (kmsg); \ + else \ + ikm_free(kmsg); \ +MACRO_END + /* * The size of the kernel message buffers that will be cached. * IKM_SAVED_KMSG_SIZE includes overhead; IKM_SAVED_MSG_SIZE doesn't. @@ -116,6 +156,16 @@ extern ipc_kmsg_t ipc_kmsg_cache[NCPUS]; #define ikm_alloc(size) \ ((ipc_kmsg_t) kalloc(ikm_plus_overhead(size))) +/* + * The conversion between userland and kernel-land has to convert from port + * names to ports. This may increase the size that needs to be allocated + * on the kernel size. At worse the message is full of port names to be + * converted. + */ +#define IKM_EXPAND_FACTOR ((sizeof(mach_port_t) + sizeof(mach_port_name_t) - 1) / sizeof(mach_port_name_t)) +/* But make sure it's not the converse. */ +_Static_assert(sizeof(mach_port_t) >= sizeof(mach_port_name_t)); + #define ikm_init(kmsg, size) \ MACRO_BEGIN \ ikm_init_special((kmsg), ikm_plus_overhead(size)); \ @@ -242,38 +292,49 @@ extern void ipc_kmsg_free(ipc_kmsg_t); extern mach_msg_return_t -ipc_kmsg_get(mach_msg_header_t *, mach_msg_size_t, ipc_kmsg_t *); +ipc_kmsg_get(mach_msg_user_header_t *, mach_msg_size_t, ipc_kmsg_t *); extern mach_msg_return_t ipc_kmsg_get_from_kernel(mach_msg_header_t *, mach_msg_size_t, ipc_kmsg_t *); extern mach_msg_return_t -ipc_kmsg_put(mach_msg_header_t *, ipc_kmsg_t, mach_msg_size_t); +ipc_kmsg_put(mach_msg_user_header_t *, ipc_kmsg_t, mach_msg_size_t); extern void ipc_kmsg_put_to_kernel(mach_msg_header_t *, ipc_kmsg_t, mach_msg_size_t); extern mach_msg_return_t -ipc_kmsg_copyin_header(mach_msg_header_t *, ipc_space_t, mach_port_t); +ipc_kmsg_copyin_header(mach_msg_header_t *, ipc_space_t, mach_port_name_t); extern mach_msg_return_t -ipc_kmsg_copyin(ipc_kmsg_t, ipc_space_t, vm_map_t, mach_port_t); +ipc_kmsg_copyin(ipc_kmsg_t, ipc_space_t, vm_map_t, mach_port_name_t); extern void ipc_kmsg_copyin_from_kernel(ipc_kmsg_t); extern mach_msg_return_t -ipc_kmsg_copyout_header(mach_msg_header_t *, ipc_space_t, mach_port_t); +ipc_kmsg_copyout_header(mach_msg_header_t *, ipc_space_t, mach_port_name_t); extern mach_msg_return_t ipc_kmsg_copyout_object(ipc_space_t, ipc_object_t, - mach_msg_type_name_t, mach_port_t *); + mach_msg_type_name_t, mach_port_name_t *); + +static inline mach_msg_return_t +ipc_kmsg_copyout_object_to_port(ipc_space_t space, ipc_object_t object, + mach_msg_type_name_t msgt_name, mach_port_t *portp) +{ + mach_port_name_t name;; + mach_msg_return_t mr; + mr = ipc_kmsg_copyout_object(space, object, msgt_name, &name); + *portp = (mach_port_t)name; + return mr; +} extern mach_msg_return_t -ipc_kmsg_copyout_body(vm_offset_t, vm_offset_t, ipc_space_t, vm_map_t); +ipc_kmsg_copyout_body(ipc_kmsg_t, ipc_space_t, vm_map_t); extern mach_msg_return_t -ipc_kmsg_copyout(ipc_kmsg_t, ipc_space_t, vm_map_t, mach_port_t); +ipc_kmsg_copyout(ipc_kmsg_t, ipc_space_t, vm_map_t, mach_port_name_t); extern mach_msg_return_t ipc_kmsg_copyout_pseudo(ipc_kmsg_t, ipc_space_t, vm_map_t); |