xref: /xnu-10002.1.13/osfmk/kern/mach_node.h (revision 1031c584a5e37aff177559b9f69dbd3c8c3fd30a)
1 /*
2  * Copyright (c) 2015-2016 Apple Computer, Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 /*
29  *  File:   kern/mach_node.h
30  *  Author: Dean Reece
31  *  Date:   2016
32  *
33  *  Definitions for mach internode communication (used by flipc).
34  *  This header is intended for use inside the kernel only.
35  */
36 
37 #ifndef _KERN_MACH_NODE_H_
38 #define _KERN_MACH_NODE_H_
39 
40 #if defined(MACH_KERNEL_PRIVATE) || defined(__APPLE_API_PRIVATE)
41 
42 /*** Mach Node Name Server Section
43  *  Definitions shared by the mach_node layer in the kernel and the
44  *  node's bootstrap server (noded).
45  */
46 
47 /* This structure describes messages sent from the mach_node layer to the
48  * node bootstrap server.
49  */
50 #pragma pack(4)
51 typedef struct mach_node_server_msg {
52 	mach_msg_header_t   header;
53 	uint32_t    identifier; // See FLIPC_SM_* defines
54 	uint32_t    options;    // Currently unused
55 	uint32_t    node_id;    // Node number
56 } *mach_node_server_msg_t;
57 #pragma pack()
58 
59 /* This structure describes node registration messages sent from the mach_node
60  * layer to the node bootstrap server.
61  */
62 typedef struct mach_node_server_register_msg {
63 	struct mach_node_server_msg node_header;
64 	uint8_t     datamodel;  // 1==ILP32, 2==LP64; matches dtrace
65 	uint8_t     byteorder;  // Uses defines from libkern/OSByteOrder.h
66 } *mach_node_server_register_msg_t;
67 #pragma pack()
68 
69 #define MACH_NODE_SERVER_MSG_ID (0x45444f4eUL)  // msgh_id "NODE" for Node msgs
70 #define MACH_NODE_SM_REG_LOCAL           (0UL)  // Register the local node
71 #define MACH_NODE_SM_REG_REMOTE          (1UL)  // Register a remote node
72 
73 #if defined(__LP64__)
74 #define LOCAL_DATA_MODEL    (2) // Native data model is LP64
75 #else
76 #define LOCAL_DATA_MODEL    (1) // Native data model is ILP32
77 #endif
78 
79 #endif
80 
81 
82 #if MACH_FLIPC && defined(MACH_KERNEL_PRIVATE)
83 
84 #include <kern/mach_node_link.h>
85 #include <kern/queue.h>
86 
87 #include <sys/cdefs.h>
88 
89 __BEGIN_DECLS
90 
91 #define MACH_NODES_MAX          (2)         // Must be a power-of-2
92 #define MACH_NODE_ID_VALID(nid) (((nid) >= 0) && ((nid) < MACH_NODES_MAX))
93 
94 typedef struct  flipc_node  *flipc_node_t;  // Defined in ipc/flipc.h
95 
96 
97 /*** Mach Node Section
98  *
99  *  An instance of mach_node is allocated for each node known to mach.
100  *  In-kernel interfaces use a pointer to this structure to refer to a node.
101  *  External interfaces and protocols refer to node by id (mach_node_id_t).
102  */
103 typedef struct mach_node *mach_node_t;
104 
105 struct mach_node {
106 	/* Static node details, provided by the link driver at registration */
107 	struct mnl_node_info info;
108 
109 	lck_spin_t      node_lock_data;
110 
111 	/* Flags and status word */
112 	uint32_t        link:2;     // See MNL_LINK* defines
113 	uint32_t        published:1;// True if node server has send-right
114 	uint32_t        active:1;   // True if node is up and ready
115 	uint32_t        suspended:1;// True if node is active but sleeping
116 	uint32_t        dead:1;     // True if node is dead
117 	uint32_t        _reserved:26;// Fill out the 32b flags field
118 
119 	/* port/space/set */
120 	ipc_space_t     proxy_space;// Kernel special space for proxy rights
121 	ipc_pset_t      proxy_port_set;// All proxy ports are in this set
122 	ipc_port_t      bootstrap_port;// Port for which "noded" holds rcv right
123 	ipc_port_t      control_port;// For control & ack/nak messages
124 
125 	/* Misc */
126 	int             proto_vers; // Protocol version in use for this node
127 	mach_node_t     antecedent; // Pointer to prior encarnation of this node id
128 };
129 
130 extern mach_node_t  localnode;      // This node's mach_node_t struct
131 
132 #define MACH_NODE_NULL              ((mach_node_t) 0UL)
133 #define MACH_NODE_SIZE              ((vm_offset_t)sizeof(struct mach_node))
134 #define MACH_NODE_VALID(node)       ((node) != MACH_NODE_NULL)
135 #define MACH_NODE_ALLOC()           ((mach_node_t)kalloc(MACH_NODE_SIZE))
136 #define MACH_NODE_FREE(node)        kfree(node, MACH_NODE_SIZE)
137 
138 #define MACH_NODE_LOCK_INIT(np)     lck_spin_init(&(np)->node_lock_data, \
139 	                                          &ipc_lck_grp, &ipc_lck_attr)
140 #define MACH_NODE_LOCK_DESTROY(np)  lck_spin_destroy(&(np)->node_lock_data, \
141 	                                             &ipc_lck_grp)
142 #define MACH_NODE_LOCK(np)          lck_spin_lock(&(np)->node_lock_data)
143 #define MACH_NODE_UNLOCK(np)        lck_spin_unlock(&(np)->node_lock_data)
144 
145 /*  Gets or allocates a locked mach_node struct for the specified <node_id>.
146  *  The current node is locked and returned if it is not dead, or if it is dead
147  *  and <alloc_if_dead> is false.  A new node struct is allocated, locked and
148  *  returned if the node is dead and <alloc_if_dead> is true, or if the node
149  *  is absent and <alloc_if_absent> is true.  MACH_NODE_NULL is returned if
150  *  the node is absent and <alloc_if_absent> is false.  MACH_NODE_NULL is also
151  *  returned if a new node structure was not able to be allocated.
152  */
153 mach_node_t
154 mach_node_for_id_locked(mach_node_id_t  node_id,
155     boolean_t       alloc_if_dead,
156     boolean_t       alloc_if_absent);
157 
158 
159 /*** Mach Node Link Name Section
160  *
161  *  A node link name (mnl_name_t) is an oqaque value guaranteed unique across
162  *  kernel instances on all nodes.  This guarantee requires that node ids not
163  *  be recycled.
164  *
165  *  Names 0..(MACH_NODES_MAX-1) represent null (invalid) names
166  *  Names MACH_NODES_MAX..(MACH_NODES_MAX*2-1) represent bootstrap names
167  *  Names >=(MACH_NODES_MAX*2) represent normal names.
168  */
169 
170 /*  Allocate a new unique name and return it.
171  *  Dispose of this with mnl_name_free().
172  *  Returns MNL_NAME_NULL on failure.
173  */
174 extern mnl_name_t   mnl_name_alloc(void);
175 
176 /*  Deallocate a unique name that was allocated via mnl_name_alloc().
177  */
178 extern void mnl_name_free(mnl_name_t name);
179 
180 /*  This macro is used to convert a node id to a bootstrap port name.
181  */
182 #define MNL_NAME_BOOTSTRAP(nid) ((mnl_name_t) MACH_NODES_MAX | (nid))
183 #define MNL_NAME_NULL ((mnl_name_t) 0UL)
184 #define MNL_NAME_VALID(obj) ((obj) >= MACH_NODES_MAX)
185 
186 
187 /*  The mnl hash table may optionally be used by clients to associate mnl_names
188  *  with objects.  Objects to be stored in the hash table must start with an
189  *  instance of struct mnk_obj.  It is up to clients of the hash table to
190  *  allocate and free the actual objects being stored.
191  */
192 typedef struct mnl_obj {
193 	queue_chain_t   links;// List of mnk_name_obj (See kern/queue.h "Method 1")
194 	mnl_name_t      name;// Unique mnl_name
195 } *mnl_obj_t;
196 
197 #define MNL_OBJ_NULL        ((mnl_obj_t) 0UL)
198 #define MNL_OBJ_VALID(obj)  ((obj) != MNL_OBJ_NULL)
199 
200 
201 /*  Initialize the data structures in the mnl_obj structure at the head of the
202  *  provided object.  This should be called on an object before it is passed to
203  *  any other mnl_obj* routine.
204  */
205 void mnl_obj_init(mnl_obj_t obj);
206 
207 /*  Search the local node's hash table for the object associated with a
208  *  mnl_name_t and return it.  Returns MNL_NAME_NULL on failure.
209  */
210 mnl_obj_t mnl_obj_lookup(mnl_name_t name);
211 
212 /*  Search the local node's hash table for the object associated with a
213  *  mnl_name_t and remove it.  The pointer to the removed object is returned so
214  *  that the caller can appropriately dispose of the object.
215  *  Returns MNL_NAME_NULL on failure.
216  */
217 mnl_obj_t mnl_obj_remove(mnl_name_t name);
218 
219 /*  Insert an object into the locak node's hash table.  If the name of the
220  *  provided object is MNL_NAME_NULL then a new mnl_name is allocated and
221  *  assigned to the object.  Returns KERN_SUCCESS, or KERN_NAME_EXISTS if
222  *  an object associated with that name is already in the hash table.
223  */
224 kern_return_t mnl_obj_insert(mnl_obj_t obj);
225 
226 
227 /*** Mach Node Link Message Section ***
228  *
229  *  Struct mnl_msg is only the header for a mnl_msg buffer;
230  *  the actual buffer is normally larger.  The rest of the buffer
231  *  holds the body of the message to be transmitted over the link.
232  *
233  *  Note: A mnl_msg received over a link will be in the byte-order of the
234  *  node that send it.  fname and size must be corrected to the hosts' native
235  *  byte order by the link driver before it is sent up to the flipc layer.
236  *  However, the link driver should not attempt to adjust the data model or
237  *  byte order of the payload that follows the mnl_msg header - that will
238  *  be done by the flipc layer.
239  */
240 
241 
242 /* Values for mnl_msg.sub
243  */
244 #define MACH_NODE_SUB_INVALID   (0) // Never sent
245 #define MACH_NODE_SUB_NODE      (1) // MNL msg is for node management
246 #define MACH_NODE_SUB_FLIPC     (2) // MNL msg is for FLIPC subsystem
247 #define MACH_NODE_SUB_VMSYS     (3) // MNL msg is for VM subsystem
248 
249 
250 /* Called whenever the node special port changes
251  */
252 void mach_node_port_changed(void);
253 
254 
255 __END_DECLS
256 
257 #endif  // MACH_FLIPC && MACH_KERNEL_PRIVATE
258 #endif  // _KERN_MACH_NODE_H_
259