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 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 | /* * Copyright (c) 2015-2016 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: kern/mach_node.h * Author: Dean Reece * Date: 2016 * * Definitions for mach internode communication (used by flipc). * This header is intended for use inside the kernel only. */ #ifndef _KERN_MACH_NODE_H_ #define _KERN_MACH_NODE_H_ #if defined(MACH_KERNEL_PRIVATE) || defined(__APPLE_API_PRIVATE) /*** Mach Node Name Server Section * Definitions shared by the mach_node layer in the kernel and the * node's bootstrap server (noded). */ /* This structure describes messages sent from the mach_node layer to the * node bootstrap server. */ #pragma pack(4) typedef struct mach_node_server_msg { mach_msg_header_t header; uint32_t identifier; // See FLIPC_SM_* defines uint32_t options; // Currently unused uint32_t node_id; // Node number } *mach_node_server_msg_t; #pragma pack() /* This structure describes node registration messages sent from the mach_node * layer to the node bootstrap server. */ typedef struct mach_node_server_register_msg { struct mach_node_server_msg node_header; uint8_t datamodel; // 1==ILP32, 2==LP64; matches dtrace uint8_t byteorder; // Uses defines from libkern/OSByteOrder.h } *mach_node_server_register_msg_t; #pragma pack() #define MACH_NODE_SERVER_MSG_ID (0x45444f4eUL) // msgh_id "NODE" for Node msgs #define MACH_NODE_SM_REG_LOCAL (0UL) // Register the local node #define MACH_NODE_SM_REG_REMOTE (1UL) // Register a remote node #if defined(__LP64__) #define LOCAL_DATA_MODEL (2) // Native data model is LP64 #else #define LOCAL_DATA_MODEL (1) // Native data model is ILP32 #endif #endif #if MACH_FLIPC && defined(MACH_KERNEL_PRIVATE) #include <kern/mach_node_link.h> #include <kern/queue.h> #include <sys/cdefs.h> __BEGIN_DECLS #define MACH_NODES_MAX (2) // Must be a power-of-2 #define MACH_NODE_ID_VALID(nid) (((nid) >= 0) && ((nid) < MACH_NODES_MAX)) typedef struct flipc_node *flipc_node_t; // Defined in ipc/flipc.h /*** Mach Node Section * * An instance of mach_node is allocated for each node known to mach. * In-kernel interfaces use a pointer to this structure to refer to a node. * External interfaces and protocols refer to node by id (mach_node_id_t). */ typedef struct mach_node *mach_node_t; struct mach_node { /* Static node details, provided by the link driver at registration */ struct mnl_node_info info; lck_spin_t node_lock_data; /* Flags and status word */ uint32_t link:2; // See MNL_LINK* defines uint32_t published:1;// True if node server has send-right uint32_t active:1; // True if node is up and ready uint32_t suspended:1;// True if node is active but sleeping uint32_t dead:1; // True if node is dead uint32_t _reserved:26;// Fill out the 32b flags field /* port/space/set */ ipc_space_t proxy_space;// Kernel special space for proxy rights ipc_pset_t proxy_port_set;// All proxy ports are in this set ipc_port_t bootstrap_port;// Port for which "noded" holds rcv right ipc_port_t control_port;// For control & ack/nak messages /* Misc */ int proto_vers; // Protocol version in use for this node mach_node_t antecedent; // Pointer to prior encarnation of this node id }; extern mach_node_t localnode; // This node's mach_node_t struct #define MACH_NODE_NULL ((mach_node_t) 0UL) #define MACH_NODE_SIZE ((vm_offset_t)sizeof(struct mach_node)) #define MACH_NODE_VALID(node) ((node) != MACH_NODE_NULL) #define MACH_NODE_ALLOC() ((mach_node_t)kalloc(MACH_NODE_SIZE)) #define MACH_NODE_FREE(node) kfree(node, MACH_NODE_SIZE) #define MACH_NODE_LOCK_INIT(np) lck_spin_init(&(np)->node_lock_data, \ &ipc_lck_grp, &ipc_lck_attr) #define MACH_NODE_LOCK_DESTROY(np) lck_spin_destroy(&(np)->node_lock_data, \ &ipc_lck_grp) #define MACH_NODE_LOCK(np) lck_spin_lock(&(np)->node_lock_data) #define MACH_NODE_UNLOCK(np) lck_spin_unlock(&(np)->node_lock_data) /* Gets or allocates a locked mach_node struct for the specified <node_id>. * The current node is locked and returned if it is not dead, or if it is dead * and <alloc_if_dead> is false. A new node struct is allocated, locked and * returned if the node is dead and <alloc_if_dead> is true, or if the node * is absent and <alloc_if_absent> is true. MACH_NODE_NULL is returned if * the node is absent and <alloc_if_absent> is false. MACH_NODE_NULL is also * returned if a new node structure was not able to be allocated. */ mach_node_t mach_node_for_id_locked(mach_node_id_t node_id, boolean_t alloc_if_dead, boolean_t alloc_if_absent); /*** Mach Node Link Name Section * * A node link name (mnl_name_t) is an oqaque value guaranteed unique across * kernel instances on all nodes. This guarantee requires that node ids not * be recycled. * * Names 0..(MACH_NODES_MAX-1) represent null (invalid) names * Names MACH_NODES_MAX..(MACH_NODES_MAX*2-1) represent bootstrap names * Names >=(MACH_NODES_MAX*2) represent normal names. */ /* Allocate a new unique name and return it. * Dispose of this with mnl_name_free(). * Returns MNL_NAME_NULL on failure. */ extern mnl_name_t mnl_name_alloc(void); /* Deallocate a unique name that was allocated via mnl_name_alloc(). */ extern void mnl_name_free(mnl_name_t name); /* This macro is used to convert a node id to a bootstrap port name. */ #define MNL_NAME_BOOTSTRAP(nid) ((mnl_name_t) MACH_NODES_MAX | (nid)) #define MNL_NAME_NULL ((mnl_name_t) 0UL) #define MNL_NAME_VALID(obj) ((obj) >= MACH_NODES_MAX) /* The mnl hash table may optionally be used by clients to associate mnl_names * with objects. Objects to be stored in the hash table must start with an * instance of struct mnk_obj. It is up to clients of the hash table to * allocate and free the actual objects being stored. */ typedef struct mnl_obj { queue_chain_t links;// List of mnk_name_obj (See kern/queue.h "Method 1") mnl_name_t name;// Unique mnl_name } *mnl_obj_t; #define MNL_OBJ_NULL ((mnl_obj_t) 0UL) #define MNL_OBJ_VALID(obj) ((obj) != MNL_OBJ_NULL) /* Initialize the data structures in the mnl_obj structure at the head of the * provided object. This should be called on an object before it is passed to * any other mnl_obj* routine. */ void mnl_obj_init(mnl_obj_t obj); /* Search the local node's hash table for the object associated with a * mnl_name_t and return it. Returns MNL_NAME_NULL on failure. */ mnl_obj_t mnl_obj_lookup(mnl_name_t name); /* Search the local node's hash table for the object associated with a * mnl_name_t and remove it. The pointer to the removed object is returned so * that the caller can appropriately dispose of the object. * Returns MNL_NAME_NULL on failure. */ mnl_obj_t mnl_obj_remove(mnl_name_t name); /* Insert an object into the locak node's hash table. If the name of the * provided object is MNL_NAME_NULL then a new mnl_name is allocated and * assigned to the object. Returns KERN_SUCCESS, or KERN_NAME_EXISTS if * an object associated with that name is already in the hash table. */ kern_return_t mnl_obj_insert(mnl_obj_t obj); /*** Mach Node Link Message Section *** * * Struct mnl_msg is only the header for a mnl_msg buffer; * the actual buffer is normally larger. The rest of the buffer * holds the body of the message to be transmitted over the link. * * Note: A mnl_msg received over a link will be in the byte-order of the * node that send it. fname and size must be corrected to the hosts' native * byte order by the link driver before it is sent up to the flipc layer. * However, the link driver should not attempt to adjust the data model or * byte order of the payload that follows the mnl_msg header - that will * be done by the flipc layer. */ /* Values for mnl_msg.sub */ #define MACH_NODE_SUB_INVALID (0) // Never sent #define MACH_NODE_SUB_NODE (1) // MNL msg is for node management #define MACH_NODE_SUB_FLIPC (2) // MNL msg is for FLIPC subsystem #define MACH_NODE_SUB_VMSYS (3) // MNL msg is for VM subsystem /* Called whenever the node special port changes */ void mach_node_port_changed(void); __END_DECLS #endif // MACH_FLIPC && MACH_KERNEL_PRIVATE #endif // _KERN_MACH_NODE_H_ |