+mach_msg_return_t
+kernel_mach_msg_send(
+ mach_msg_header_t *msg,
+ mach_msg_size_t send_size,
+ mach_msg_option_t option,
+ mach_msg_timeout_t timeout_val,
+ boolean_t *message_moved)
+{
+ ipc_kmsg_t kmsg;
+ mach_msg_return_t mr;
+
+ KDBG(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_KMSG_INFO) | DBG_FUNC_START);
+
+ if (message_moved) {
+ *message_moved = FALSE;
+ }
+
+ mr = ipc_kmsg_get_from_kernel(msg, send_size, &kmsg);
+ if (mr != MACH_MSG_SUCCESS) {
+ KDBG(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_KMSG_INFO) | DBG_FUNC_END, mr);
+ return mr;
+ }
+
+ mr = ipc_kmsg_copyin_from_kernel(kmsg);
+ if (mr != MACH_MSG_SUCCESS) {
+ ipc_kmsg_free(kmsg);
+ KDBG(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_KMSG_INFO) | DBG_FUNC_END, mr);
+ return mr;
+ }
+
+ if (message_moved) {
+ *message_moved = TRUE;
+ }
+
+ /*
+ * Until we are sure of its effects, we are disabling
+ * importance donation from the kernel-side of user
+ * threads in importance-donating tasks - unless the
+ * option to force importance donation is passed in,
+ * or the thread's SEND_IMPORTANCE option has been set.
+ * (11938665 & 23925818)
+ */
+ if (current_thread()->options & TH_OPT_SEND_IMPORTANCE) {
+ option &= ~MACH_SEND_NOIMPORTANCE;
+ } else if ((option & MACH_SEND_IMPORTANCE) == 0) {
+ option |= MACH_SEND_NOIMPORTANCE;
+ }
+
+ mr = ipc_kmsg_send(kmsg, option, timeout_val);
+
+ if (mr != MACH_MSG_SUCCESS) {
+ ipc_kmsg_destroy(kmsg);
+ KDBG(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_KMSG_INFO) | DBG_FUNC_END, mr);
+ }
+
+ return mr;
+}
+
+
+#if IKM_SUPPORT_LEGACY
+
+mach_msg_return_t
+mach_msg_send_from_kernel_with_options_legacy(
+ mach_msg_header_t *msg,
+ mach_msg_size_t send_size,
+ mach_msg_option_t option,
+ mach_msg_timeout_t timeout_val)
+{
+ ipc_kmsg_t kmsg;
+ mach_msg_return_t mr;
+
+ KDBG(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_KMSG_INFO) | DBG_FUNC_START);
+
+ mr = ipc_kmsg_get_from_kernel(msg, send_size, &kmsg);
+ if (mr != MACH_MSG_SUCCESS) {
+ KDBG(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_KMSG_INFO) | DBG_FUNC_END, mr);
+ return mr;
+ }
+
+ mr = ipc_kmsg_copyin_from_kernel_legacy(kmsg);
+ if (mr != MACH_MSG_SUCCESS) {
+ ipc_kmsg_free(kmsg);
+ KDBG(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_KMSG_INFO) | DBG_FUNC_END, mr);
+ return mr;
+ }
+
+ /*
+ * Until we are sure of its effects, we are disabling
+ * importance donation from the kernel-side of user
+ * threads in importance-donating tasks.
+ * (11938665 & 23925818)
+ */
+ if (current_thread()->options & TH_OPT_SEND_IMPORTANCE) {
+ option &= ~MACH_SEND_NOIMPORTANCE;
+ } else {
+ option |= MACH_SEND_NOIMPORTANCE;
+ }
+
+ mr = ipc_kmsg_send(kmsg, option, timeout_val);
+
+ if (mr != MACH_MSG_SUCCESS) {
+ ipc_kmsg_destroy(kmsg);
+ KDBG(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_KMSG_INFO) | DBG_FUNC_END, mr);
+ }
+
+ return mr;
+}
+
+#endif /* IKM_SUPPORT_LEGACY */
+