Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | /* * Copyright (c) 2015-2020 Apple Computer, Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. The rights granted to you under the License * may not be used to create, or enable the creation or redistribution of, * unlawful or unlicensed copies of an Apple operating system, or to * circumvent, violate, or enable the circumvention or violation of, any * terms of an Apple operating system software license agreement. * * Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* * File: ipc/flipc.h * Author: Dean Reece * Date: 2016 * * Definitions for fast local ipc (flipc). */ #ifndef _IPC_FLIPC_H_ #define _IPC_FLIPC_H_ #if MACH_KERNEL_PRIVATE && MACH_FLIPC #include <kern/mach_node.h> #include <ipc/ipc_kmsg.h> #include <sys/cdefs.h> __BEGIN_DECLS /*** FLIPC Port Declarations ***/ /* A FLIPC port (flipc_port_t) is a companion structure to ipc_port_t. * Any ipc_port object that is known to the flipc layer has one of these * structures to maintain the state of the port with respect to flipc. * When a port reverts to a purely local object (all rights for the port exist * on a single node) the flipc port companion structure will be de-allocated. */ typedef struct flipc_port { struct mnl_obj obj; // Necessary to be in mnl_name_table[] ipc_port_t lport; // The associated local ipc_port mach_node_t hostnode; // Node holding the recieve right uint32_t peek_count; // How many kmsgs in mq have been peeked uint32_t state:3;// See FPORT_STATE_* defines below } *flipc_port_t; #define FPORT_NULL ((flipc_port_t) 0UL) #define FPORT_VALID(fport) ((fport) != FPORT_NULL) #define FPORT_STATE_INIT (0) // Port is being initialized #define FPORT_STATE_PROXY (1) // Principal is on another node #define FPORT_STATE_PRINCIPAL (2) // Principal is on this node #define FPORT_STATE_PREPRINCIPAL (3) // Principal moving to this node #define FPORT_STATE_POSTPRINCIPAL (4) // Principal moving to other node #define FPORT_STATE_DEAD (5) // Port is being destroyed /*** FLIPC Node Managment Declarations (used by mach node layer) ***/ extern mach_node_id_t localnode_id; // This node's FLIPC id. /* flipc_node_prepare() is called by mach node layer when a remote node is * registered by a link driver. This is the flipc layer's opportunity to * convert it to a flipc port and hook it into any appropriate structures. * Note that the node is not yet in the mach node table. Returns KERN_SUCCESS * on success; otherwise node is not prepared and cannot be used. */ kern_return_t flipc_node_prepare(mach_node_t node); /* flipc_node_retire() is called by mach node layer when a remote node is * terminated by a link driver. This is the flipc layer's opportunity to * convert it back to a local port and unhook it into any structures. * Returns KERN_SUCCESS on success. */ kern_return_t flipc_node_retire(mach_node_t node); /*** FLIPC Message Declarations (used by mach node layer) ***/ /* Definition for a flipc ack/nak message. These messages are sent to the * originating node of a message to ack or nak the message. Ack'd messages * are destroyed by the originating node (to avoid duplicate delivery). Nak'd * messages are re-sent to the node specified in <resend_to> (used when a * receive right moves to a different node). These messages are queued onto * the originating node's control_port and sent along with other ipc traffic. */ typedef struct flipc_ack_msg { struct mnl_msg mnl; // Flipc message starts with mnl message mach_node_id_t resend_to; // Node ID for resends (if NAK) uint8_t msg_count; // Number of msgs being ackd/nakd } __attribute__((__packed__)) * flipc_ack_msg_t; #define FLIPC_CMD_ID (0x43504952UL) // msgh_id "RIPC" for FLIPC msgs #define FLIPC_CMD_IPCMESSAGE (1) // IPC Msg: <node> is sender; <fname> is dest port #define FLIPC_CMD_ACKMESSAGE (2) // <fname> is port being ack'd #define FLIPC_CMD_NAKMESSAGE (3) // <fname> is port being nak'd /* The node layer calls flipc_msg_to_remote_node() to fetch the next message * for <to_node>. This function will block until a message is available or the * node is terminated, in which case it returns MNL_MSG_NULL. */ mnl_msg_t flipc_msg_to_remote_node(mach_node_t to_node, uint32_t flags); /* The node layer calls flipc_msg_to_remote_node() to post the next message * from <from_node>. This function will block until a message is available * or the node is terminated, in which case it returns MNL_MSG_NULL. */ void flipc_msg_from_node(mach_node_t from_node, mnl_msg_t msg_arg, uint32_t flags); /* The node layer calls flipc_msg_free() to dispose of sent messages that * originated in the FLIPC layer. */ void flipc_msg_free(mnl_msg_t msg, uint32_t flags); /*** FLIPC Message Declarations (used by mach ipc subsystem) ***/ /* Ack a message sent by <mqueue> to <fport>. A new kmsg is allocated and * filled in as an ack (or nak if <delivered> is false), then posted to the * node's contol port. This will wake the link driver (if sleeping) and cause * the ack to be included with normal IPC traffic. * * This function immediately returns if <fport> or <node> is invalid, so it * is safe & quick to call speculatively. * * Called from mach ipc_mqueue.c when a flipc-originated message is consumed. */ void flipc_msg_ack(mach_node_t node, ipc_mqueue_t mqueue, boolean_t delivered); __END_DECLS #endif // MACH_KERNEL_PRIVATE #endif // _IPC_FLIPC_H_ |