xref: /xnu-10002.61.3/osfmk/mach/exclaves.h (revision 0f4c859e951fba394238ab619495c4e1d54d0f34)
1 /*
2  * Copyright (c) 2022 Apple 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 #ifndef _MACH_EXCLAVES_H
30 #define _MACH_EXCLAVES_H
31 
32 #if defined(PRIVATE)
33 
34 #include <os/base.h>
35 #include <mach/mach_types.h>
36 
37 __BEGIN_DECLS
38 
39 typedef uint64_t exclaves_id_t;
40 typedef uint64_t exclaves_tag_t;
41 typedef uint64_t exclaves_error_t;
42 
43 #if !defined(KERNEL)
44 
45 /*!
46  * @function exclaves_endpoint_call
47  *
48  * @abstract
49  * Perform RPC to an exclaves endpoint.
50  *
51  * @param port
52  * Reserved, must be MACH_PORT_NULL for now.
53  *
54  * @param endpoint_id
55  * Identifier of exclaves endpoint to send RPC to.
56  *
57  * @param msg_buffer
58  * Pointer to exclaves IPC buffer.
59  *
60  * @param size
61  * Size of specified exclaves IPC buffer.
62  *
63  * @param tag
64  * In-out parameter for exclaves IPC tag.
65  *
66  * @param error
67  * Out parameter for exclaves IPC error.
68  *
69  * @result
70  * KERN_SUCCESS or mach system call error code.
71  */
72 kern_return_t
73 exclaves_endpoint_call(mach_port_t port, exclaves_id_t endpoint_id,
74     mach_vm_address_t msg_buffer, mach_vm_size_t size, exclaves_tag_t *tag,
75     exclaves_error_t *error);
76 
77 /*!
78  * @function exclaves_named_buffer_create
79  *
80  * @abstract
81  * Setup access by xnu to a pre-defined named exclaves shared memory buffer
82  * and return a mach port for it.
83  *
84  * @param port
85  * Reserved, must be MACH_PORT_NULL for now.
86  *
87  * @param buffer_id
88  * Identifier of named buffer to operate on.
89  *
90  * @param size
91  * Size of requested named buffer.
92  *
93  * @param named_buffer_port
94  * Out parameter filled in with mach port name for the newly created named
95  * buffer object, must be mach_port_deallocate()d to tear down the access to
96  * the named buffer.
97  *
98  * @result
99  * KERN_SUCCESS or mach system call error code.
100  */
101 kern_return_t
102 exclaves_named_buffer_create(mach_port_t port, exclaves_id_t buffer_id,
103     mach_vm_size_t size, mach_port_t* named_buffer_port);
104 
105 /*!
106  * @function exclaves_named_buffer_copyin
107  *
108  * @abstract
109  * Copy from specified userspace buffer into previously setup named exclaves
110  * shared memory buffer.
111  *
112  * @param named_buffer_port
113  * A named buffer port name returned from exclaves_named_buffer_create()
114  *
115  * @param src_buffer
116  * Pointer to userspace buffer to copy into named buffer.
117  *
118  * @param size
119  * Number of bytes to copy (<= size of specified userspace buffer).
120  *
121  * @param offset
122  * Offset in shared memory buffer to start copy at.
123  *
124  * @result
125  * KERN_SUCCESS or mach system call error code.
126  */
127 kern_return_t
128 exclaves_named_buffer_copyin(mach_port_t named_buffer_port,
129     mach_vm_address_t src_buffer, mach_vm_size_t size, mach_vm_size_t offset);
130 
131 /*!
132  * @function exclaves_named_buffer_copyout
133  *
134  * @abstract
135  * Copy out to specified userspace buffer from previously setup named exclaves
136  * shared memory buffer.
137  *
138  * @param named_buffer_port
139  * A named buffer port name returned from exclaves_named_buffer_create()
140  *
141  * @param dst_buffer
142  * Pointer to userspace buffer to copy out from named buffer.
143  *
144  * @param size
145  * Number of bytes to copy (<= size of specified userspace buffer).
146  *
147  * @param offset
148  * Offset in shared memory buffer to start copy at.
149  *
150  * @result
151  * KERN_SUCCESS or mach system call error code.
152  */
153 kern_return_t
154 exclaves_named_buffer_copyout(mach_port_t named_buffer_port,
155     mach_vm_address_t dst_buffer, mach_vm_size_t size, mach_vm_size_t offset);
156 
157 /*!
158  * @function exclaves_boot
159  *
160  * @abstract
161  * Perform exclaves boot.
162  *
163  * @param port
164  * Reserved, must be MACH_PORT_NULL for now.
165  *
166  * @param flags
167  * Reserved, must be 0 for now.
168  *
169  * @result
170  * KERN_SUCCESS or mach system call error code.
171  */
172 kern_return_t
173 exclaves_boot(mach_port_t port, uint64_t flags);
174 
175 #else /* defined(KERNEL) */
176 
177 /*!
178  * @function exclaves_endpoint_call
179  *
180  * @abstract
181  * Perform RPC to an exclaves endpoint via per-thread exclaves IPC buffer.
182  *
183  * @param port
184  * Reserved, must be IPC_PORT_NULL for now.
185  *
186  * @param endpoint_id
187  * Identifier of exclaves endpoint to send RPC to.
188  *
189  * @param tag
190  * In-out parameter for exclaves IPC tag.
191  *
192  * @param error
193  * Out parameter for exclaves IPC error.
194  *
195  * @result
196  * KERN_SUCCESS or mach error code.
197  */
198 kern_return_t
199 exclaves_endpoint_call(ipc_port_t port, exclaves_id_t endpoint_id,
200     exclaves_tag_t *tag, exclaves_error_t *error);
201 
202 /*!
203  * @function exclaves_allocate_ipc_buffer
204  *
205  * @abstract
206  * If necessary, allocate per-thread exclaves IPC buffer.
207  *
208  * @param ipc_buffer
209  * Out parameter filled in with address of IPC buffer. Can be NULL.
210  *
211  * @result
212  * KERN_SUCCESS or mach error code.
213  */
214 kern_return_t
215 exclaves_allocate_ipc_buffer(void **ipc_buffer);
216 
217 /*!
218  * @function exclaves_free_ipc_buffer
219  *
220  * @abstract
221  * If necessary, free per-thread exclaves IPC buffer.
222  *
223  * @result
224  * KERN_SUCCESS or mach error code.
225  */
226 kern_return_t
227 exclaves_free_ipc_buffer(void);
228 
229 /*!
230  * @function exclaves_get_ipc_buffer
231  *
232  * @abstract
233  * Return per-thread exclaves IPC buffer.
234  *
235  * @result
236  * If allocated, pointer to per-thread exclaves IPC buffer, NULL otherwise.
237  */
238 OS_CONST
239 void*
240 exclaves_get_ipc_buffer(void);
241 
242 /* For use by Tightbeam kernel runtime only */
243 
244 typedef uint64_t exclaves_badge_t;
245 
246 /*!
247  * @typedef exclaves_upcall_handler_t
248  *
249  * @abstract
250  * RPC message handler for upcalls from exclaves via per-thread exclaves IPC
251  * buffer.
252  *
253  * @param context
254  * Opaque context pointer specified at handler registration.
255  *
256  * @param tag
257  * In-out parameter for exclaves IPC tag.
258  *
259  * @param badge
260  * Badge value identifying upcall RPC message.
261  *
262  * @result
263  * KERN_SUCCESS or mach error code.
264  */
265 typedef kern_return_t
266 (*exclaves_upcall_handler_t)(void *context, exclaves_tag_t *tag,
267     exclaves_badge_t badge);
268 
269 /*!
270  * @function exclaves_register_upcall_handler
271  *
272  * @abstract
273  * One-time registration of exclaves upcall RPC handler for specified upcall ID.
274  * Must be called during Exclaves boot sequence, will assert otherwise.
275  *
276  * @param upcall_id
277  * Identifier of upcall to configure.
278  *
279  * @param upcall_context
280  * Opaque context pointer to pass to upcall RPC handler.
281  *
282  * @param upcall_handler
283  * Pointer to upcall RPC handler.
284  *
285  * @result
286  * KERN_SUCCESS or mach error code.
287  */
288 kern_return_t
289 exclaves_register_upcall_handler(exclaves_id_t upcall_id, void *upcall_context,
290     exclaves_upcall_handler_t upcall_handler);
291 
292 struct XrtHosted_Callbacks;
293 
294 /*!
295  * @function xrt_hosted_register_callbacks
296  *
297  * @abstract
298  * Exclaves XRT hosted kext interface.
299  *
300  * @param callbacks
301  * Pointer to callback function table.
302  */
303 void
304 exclaves_register_xrt_hosted_callbacks(struct XrtHosted_Callbacks *callbacks);
305 
306 #endif /* defined(KERNEL) */
307 
308 #if defined(MACH_KERNEL_PRIVATE)
309 
310 /* -------------------------------------------------------------------------- */
311 
312 /* Internal kernel interface */
313 
314 kern_return_t
315 exclaves_thread_terminate(thread_t thread);
316 
317 kern_return_t
318 exclaves_boot(ipc_port_t port, uint64_t flags);
319 
320 #endif /* defined(MACH_KERNEL_PRIVATE) */
321 
322 /* -------------------------------------------------------------------------- */
323 
324 /* Private interface between Libsyscall and xnu */
325 
326 OS_ENUM(exclaves_ctl_op, uint8_t,
327     EXCLAVES_CTL_OP_ENDPOINT_CALL = 1,
328     EXCLAVES_CTL_OP_NAMED_BUFFER_CREATE = 2,
329     EXCLAVES_CTL_OP_NAMED_BUFFER_COPYIN = 3,
330     EXCLAVES_CTL_OP_NAMED_BUFFER_COPYOUT = 4,
331     EXCLAVES_CTL_OP_BOOT = 5,
332     EXCLAVES_CTL_OP_LAST,
333     );
334 #define EXCLAVES_CTL_FLAGS_MASK (0xfffffful)
335 #define EXCLAVES_CTL_OP_AND_FLAGS(op, flags) \
336 	((uint32_t)EXCLAVES_CTL_OP_##op << 24 | \
337 	((uint32_t)(flags) & EXCLAVES_CTL_FLAGS_MASK))
338 #define EXCLAVES_CTL_OP(op_and_flags) \
339 	((uint8_t)((op_and_flags) >> 24))
340 #define EXCLAVES_CTL_FLAGS(op_and_flags) \
341 	((uint32_t)(op_and_flags) & EXCLAVES_CTL_FLAGS_MASK)
342 
343 #if !defined(KERNEL)
344 
345 OS_NOT_TAIL_CALLED
346 kern_return_t
347 _exclaves_ctl_trap(mach_port_name_t name, uint32_t operation_and_flags,
348     exclaves_id_t identifier, mach_vm_address_t buffer, mach_vm_size_t size);
349 
350 #endif /* !defined(KERNEL) */
351 
352 /* -------------------------------------------------------------------------- */
353 
354 /* Sysctl interface */
355 
356 OS_ENUM(exclaves_status, uint8_t,
357     EXCLAVES_STATUS_NOT_STARTED = 0x00,
358     EXCLAVES_STATUS_AVAILABLE = 0x01,
359     EXCLAVES_STATUS_FAILED = 0xFE,
360     EXCLAVES_STATUS_NOT_SUPPORTED = 0xFF,
361     );
362 
363 #if defined(KERNEL)
364 
365 /*!
366  * @function exclaves_get_status
367  *
368  * @abstract
369  * Return the current running status of exclaves.
370  *
371  * @result
372  * The status of exclaves.
373  */
374 exclaves_status_t
375 exclaves_get_status(void);
376 
377 #endif /* defined(KERNEL) */
378 
379 __END_DECLS
380 
381 #endif /* defined(PRIVATE) */
382 
383 #endif /* _MACH_EXCLAVES_H */
384