xref: /xnu-11215.1.10/osfmk/mach/exclaves.h (revision 8d741a5de7ff4191bf97d57b9f54c2f6d4a15585)
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 #include <mach/mach_param.h>
37 #if !defined(KERNEL)
38 #include <AvailabilityInternalPrivate.h>
39 #endif /* defined(KERNEL) */
40 
41 
42 __BEGIN_DECLS
43 
44 typedef uint64_t exclaves_id_t;
45 typedef uint64_t exclaves_tag_t;
46 typedef uint64_t exclaves_error_t;
47 
48 /*!
49  * @enum exclaves_sensor_status_t
50  *
51  * @brief
52  * The status of an exclaves sensor.
53  *
54  * Indicates if data from this sensor can currently be accessed.
55  * If the data cannot be accessed, exclaves_sensor_start() must be
56  * called (with an accompanying exclaves_sensor_stop()).
57  *
58  * If the data cannot be accessed, then reading sensor data will
59  * only result in 0s.
60  */
61 OS_ENUM(exclaves_sensor_status, uint32_t,
62     EXCLAVES_SENSOR_STATUS_ALLOWED = 1,
63     EXCLAVES_SENSOR_STATUS_DENIED = 2,
64     EXCLAVES_SENSOR_STATUS_CONTROL = 3,
65     );
66 
67 OS_CLOSED_OPTIONS(exclaves_buffer_perm, uint32_t,
68     EXCLAVES_BUFFER_PERM_READ = 1,
69     EXCLAVES_BUFFER_PERM_WRITE = 2,
70     );
71 
72 OS_ENUM(exclaves_boot_stage, uint32_t,
73     EXCLAVES_BOOT_STAGE_NONE = ~0u,
74     EXCLAVES_BOOT_STAGE_2 = 0,
75     EXCLAVES_BOOT_STAGE_EXCLAVEKIT = 100,
76 
77     /* The EXCLAVEKIT boot stage failed in some way. */
78     EXCLAVES_BOOT_STAGE_FAILED = 200,
79     );
80 
81 OS_ENUM(exclaves_status, uint8_t,
82     EXCLAVES_STATUS_NOT_STARTED = 0x00, /* Obsolete. Never used. */
83     EXCLAVES_STATUS_AVAILABLE = 0x01,
84     EXCLAVES_STATUS_FAILED = 0xFE,      /* Obsolete. Never used. */
85     EXCLAVES_STATUS_NOT_SUPPORTED = 0xFF,
86     );
87 
88 #define MAX_CONCLAVE_RESOURCE_NUM 50
89 
90 /*
91  * Having the ability to relax certain exclaves requirements is useful for
92  * development.
93  * These requirements are optional only in the sense that the system can boot
94  * without them and userspace can run.
95  * The system isn't considered fully functional if any of these requirements are
96  * not working.
97  * By default and on RELEASE if any of these requirements fail it will cause a
98  * panic or failure.
99  * Requirements can be relaxed via a boot-arg/tunable:
100  *     "exclaves_relaxed_requirements"
101  * The current value can read via a sysctl:
102  *     "kern.exclaves_relaxed_requirements"
103  */
104 OS_CLOSED_OPTIONS(exclaves_requirement, uint64_t,
105 
106 
107     /*
108      * Exclaves stackshot support.
109      * Also includes other "inspection" functionality like exclaves kperf
110      * data and related.
111      */
112     EXCLAVES_R_STACKSHOT    = 0x04,
113 
114     /* Exclaves logging.
115      * Without this, no exclaves logs will be available.
116      */
117     EXCLAVES_R_LOG_SERVER   = 0x08,
118 
119     /*
120      * Exclaves indicator controller.
121      * Other than supporting the various exclaves_sensor APIs, EIC is also
122      * necessary to allow the use of Audio Buffer/Audio Memory resources.
123      */
124     EXCLAVES_R_EIC          = 0x10,
125 
126     /*
127      * Conclave support.
128      * If this requirement is relaxed it allows tasks to attach to conclaves
129      * even though there is no corresponding conclave manager available.
130      */
131     EXCLAVES_R_CONCLAVE     = 0x20,
132 
133     /*
134      * ExclaveKit initialization.
135      * If relaxed and exclavekit initialization fails, continue on without
136      * panicking. All conclave related functionality will fail.
137      */
138     EXCLAVES_R_EXCLAVEKIT   = 0x40,
139 
140     /*
141      * Conclave resource support.
142      * If this requirement is relaxed it allows tasks access to kernel domain
143      * resources when not actually attched to a conclave (see
144      * EXCLAVES_R_CONCLAVE above).
145      */
146     EXCLAVES_R_CONCLAVE_RESOURCES = 0x80,
147 
148     );
149 
150 #if !defined(KERNEL)
151 
152 /*!
153  * @function exclaves_endpoint_call
154  *
155  * @abstract
156  * Perform RPC to an exclaves endpoint.
157  *
158  * @param port
159  * Reserved, must be MACH_PORT_NULL for now.
160  *
161  * @param endpoint_id
162  * Identifier of exclaves endpoint to send RPC to.
163  *
164  * @param msg_buffer
165  * Pointer to exclaves IPC buffer.
166  *
167  * @param size
168  * Size of specified exclaves IPC buffer.
169  *
170  * @param tag
171  * In-out parameter for exclaves IPC tag.
172  *
173  * @param error
174  * Out parameter for exclaves IPC error.
175  *
176  * @result
177  * KERN_SUCCESS or mach system call error code.
178  */
179 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
180 kern_return_t
181 exclaves_endpoint_call(mach_port_t port, exclaves_id_t endpoint_id,
182     mach_vm_address_t msg_buffer, mach_vm_size_t size, exclaves_tag_t *tag,
183     exclaves_error_t *error);
184 
185 /*!
186  * @function exclaves_outbound_buffer_create
187  *
188  * @abstract
189  * Setup access by xnu to a pre-defined exclaves outbound memory buffer and
190  * return a mach port for it. The buffer can only be read from.
191  *
192  * @param port
193  * Reserved, must be MACH_PORT_NULL for now.
194  *
195  * @param buffer_name
196  * String name of buffer to operate on.
197  *
198  * @param size
199  * Size of requested outbound buffer.
200  *
201  * @param outbound_buffer_port
202  * Out parameter filled in with mach port name for the newly created outbound
203  * buffer object, must be mach_port_deallocate()d to tear down the access to
204  * the outbound buffer.
205  *
206  * @result
207  * KERN_SUCCESS or mach system call error code.
208  */
209 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
210 kern_return_t
211 exclaves_outbound_buffer_create(mach_port_t port, const char *buffer_name,
212     mach_vm_size_t size, mach_port_t *outbound_buffer_port);
213 
214 /*!
215  * @function exclaves_outbound_buffer_copyout
216  *
217  * @abstract
218  * Copy out to specified userspace buffer from previously setup exclaves
219  * outbound memory buffer.
220  *
221  * Two size/offsets are provided to faciliate fast copy that wraps around a ring
222  * buffer that could be placed arbitrarily in the outbound memory region.
223  *
224  * @param outbound_buffer_port
225  * A outbound buffer port name returned from exclaves_outbound_buffer_create()
226  *
227  * @param dst_buffer
228  * Pointer to userspace buffer to copy out from outbound buffer.
229  *
230  * @param size1
231  * Number of bytes to copy (<= size of specified userspace buffer).
232  *
233  * @param offset1
234  * Offset in outbound memory buffer to start copy at.
235  *
236  * @param size2
237  * Number of bytes to copy (<= size of specified userspace buffer). Can be 0,
238  * in which case the 2nd range is not copied.
239  *
240  * @param offset2
241  * Offset in outbound memory buffer to start copy at.
242  *
243  * @result
244  * KERN_SUCCESS or mach system call error code.
245  */
246 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
247 kern_return_t
248 exclaves_outbound_buffer_copyout(mach_port_t outbound_buffer_port,
249     mach_vm_address_t dst_buffer, mach_vm_size_t size1, mach_vm_size_t offset1,
250     mach_vm_size_t size2, mach_vm_size_t offset2);
251 
252 /*!
253  * @function exclaves_inbound_buffer_create
254  *
255  * @abstract
256  * Setup access by xnu to a pre-defined exclaves inbound memory buffer and
257  * return a mach port for it. The buffer can be both read from and written to.
258  *
259  * @param port
260  * Reserved, must be MACH_PORT_NULL for now.
261  *
262  * @param buffer_name
263  * String name of buffer to operate on.
264  *
265  * @param size
266  * Size of requested inbound buffer.
267  *
268  * @param inbound_buffer_port
269  * Out parameter filled in with mach port name for the newly created inbound
270  * buffer object, must be mach_port_deallocate()d to tear down the access to
271  * the inbound buffer.
272  *
273  * @result
274  * KERN_SUCCESS or mach system call error code.
275  */
276 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
277 kern_return_t
278 exclaves_inbound_buffer_create(mach_port_t port, const char *buffer_name,
279     mach_vm_size_t size, mach_port_t *inbound_buffer_port);
280 
281 /*!
282  * @function exclaves_inbound_buffer_copyin
283  *
284  * @abstract
285  * Copy from specified userspace buffer into previously setup inbound exclaves
286  * inbound memory buffer.
287  *
288  * Two size/offsets are provided to faciliate fast copy that wraps around a ring
289  * buffer that could be placed arbitrarily in the inbound memory region.
290  *
291  * @param inbound_buffer_port
292  * An inbound buffer port name returned from exclaves_inbound_buffer_create()
293  *
294  * @param src_buffer
295  * Pointer to userspace buffer to copy into inbound buffer.
296  *
297  * @param size1
298  * Number of bytes to copy (<= size of specified userspace buffer).
299  *
300  * @param offset1
301  * Offset in inbound memory buffer to start copy at.
302  *
303  * @param size2
304  * Number of bytes to copy (<= size of specified userspace buffer). Can be 0,
305  * in which case the 2nd range is not copied.
306  *
307  * @param offset2
308  * Offset in inbound memory buffer to start copy at.
309  *
310  * @result
311  * KERN_SUCCESS or mach system call error code. Some buffers are read-only and
312  * calls to exclaves_inbound_buffer_copyin() will result in
313  * KERN_PROTECTION_FAILURE.
314  */
315 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
316 kern_return_t
317 exclaves_inbound_buffer_copyin(mach_port_t inbound_buffer_port,
318     mach_vm_address_t src_buffer, mach_vm_size_t size1, mach_vm_size_t offset1,
319     mach_vm_size_t size2, mach_vm_size_t offset2);
320 
321 /*!
322  * @function exclaves_named_buffer_create
323  *
324  * @abstract
325  * Setup access by xnu to a pre-defined named exclaves shared memory buffer
326  * and return a mach port for it.
327  *
328  * @param port
329  * Reserved, must be MACH_PORT_NULL for now.
330  *
331  * @param buffer_id
332  * Identifier of named buffer to operate on.
333  *
334  * @param size
335  * Size of requested named buffer.
336  *
337  * @param named_buffer_port
338  * Out parameter filled in with mach port name for the newly created named
339  * buffer object, must be mach_port_deallocate()d to tear down the access to
340  * the named buffer.
341  *
342  * @result
343  * KERN_SUCCESS or mach system call error code.
344  */
345 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
346 kern_return_t
347 exclaves_named_buffer_create(mach_port_t port, exclaves_id_t buffer_id,
348     mach_vm_size_t size, mach_port_t* named_buffer_port);
349 
350 /*!
351  * @function exclaves_named_buffer_copyin
352  *
353  * @abstract
354  * Copy from specified userspace buffer into previously setup named exclaves
355  * shared memory buffer.
356  *
357  * @param named_buffer_port
358  * A named buffer port name returned from exclaves_named_buffer_create()
359  *
360  * @param src_buffer
361  * Pointer to userspace buffer to copy into named buffer.
362  *
363  * @param size
364  * Number of bytes to copy (<= size of specified userspace buffer).
365  *
366  * @param offset
367  * Offset in shared memory buffer to start copy at.
368  *
369  * @result
370  * KERN_SUCCESS or mach system call error code.
371  */
372 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
373 kern_return_t
374 exclaves_named_buffer_copyin(mach_port_t named_buffer_port,
375     mach_vm_address_t src_buffer, mach_vm_size_t size, mach_vm_size_t offset);
376 
377 /*!
378  * @function exclaves_named_buffer_copyout
379  *
380  * @abstract
381  * Copy out to specified userspace buffer from previously setup named exclaves
382  * shared memory buffer.
383  *
384  * @param named_buffer_port
385  * A named buffer port name returned from exclaves_named_buffer_create()
386  *
387  * @param dst_buffer
388  * Pointer to userspace buffer to copy out from named buffer.
389  *
390  * @param size
391  * Number of bytes to copy (<= size of specified userspace buffer).
392  *
393  * @param offset
394  * Offset in shared memory buffer to start copy at.
395  *
396  * @result
397  * KERN_SUCCESS or mach system call error code.
398  */
399 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
400 kern_return_t
401 exclaves_named_buffer_copyout(mach_port_t named_buffer_port,
402     mach_vm_address_t dst_buffer, mach_vm_size_t size, mach_vm_size_t offset);
403 
404 /*!
405  * @function exclaves_boot
406  *
407  * @abstract
408  * Perform exclaves boot.
409  *
410  * @param port
411  * Reserved, must be MACH_PORT_NULL for now.
412  *
413  * @param boot_stage
414  * Stage of boot requested
415  *
416  * @result
417  * KERN_SUCCESS or mach system call error code.
418  */
419 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
420 kern_return_t
421 exclaves_boot(mach_port_t port, exclaves_boot_stage_t boot_stage);
422 
423 /*!
424  * @function exclaves_audio_buffer_create
425  *
426  * @abstract
427  * Setup access by xnu to a pre-defined named exclaves audio shared memory
428  * buffer and return a mach port for it.
429  *
430  * @param port
431  * Reserved, must be MACH_PORT_NULL for now.
432  *
433  * @param buffer_name
434  * String name of buffer to operate on.
435  *
436  * @param size
437  * Size of requested named buffer.
438  *
439  * @param audio_buffer_port
440  * Out parameter filled in with mach port name for the newly created named
441  * buffer object, must be mach_port_deallocate()d to tear down the access to
442  * the named buffer.
443  *
444  * Audio buffers are distiguished from general named buffers as shared memory
445  * is arbitrated by the EIC.
446  *
447  * @result
448  * KERN_SUCCESS or mach system call error code.
449  */
450 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
451 kern_return_t
452 exclaves_audio_buffer_create(mach_port_t port, const char * buffer_name,
453     mach_vm_size_t size, mach_port_t *audio_buffer_port);
454 
455 /*!
456  * @function exclaves_audio_buffer_copyout
457  *
458  * @abstract
459  * Copy out to specified userspace buffer from previously setup named exclaves
460  * audio shared memory buffer.
461  *
462  * Audio buffers are arbitrated via the EIC and copies will return 0's when
463  * access to the sensor is not granted.
464  *
465  * Two size/offsets are provided to faciliate fast copy that wraps around a
466  * ring buffer that could be placed arbitrarily in the shared memory region.
467  *
468  * @param audio_buffer_port
469  * A named buffer port name returned from exclaves_audio_buffer_create()
470  *
471  * @param dst_buffer
472  * Pointer to userspace buffer to copy out from named buffer.
473  *
474  * @param size1
475  * Number of bytes to copy (<= size of specified userspace buffer).
476  *
477  * @param offset1
478  * Offset in shared memory buffer to start copy at.
479  *
480  * @param size2
481  * Number of bytes to copy (<= size of specified userspace buffer). Can be 0,
482  * in which case the 2nd range is not copied.
483  *
484  * @param offset2
485  * Offset in shared memory buffer to start copy at.
486  *
487  * @result
488  * KERN_SUCCESS or mach system call error code.
489  */
490 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
491 kern_return_t
492 exclaves_audio_buffer_copyout(mach_port_t audio_buffer_port,
493     mach_vm_address_t dst_buffer, mach_vm_size_t size1, mach_vm_size_t offset1,
494     mach_vm_size_t size2, mach_vm_size_t offset2);
495 
496 /*!
497  * @function exclaves_sensor_create
498  *
499  * @abstract
500  * Setup access by xnu to a pre-defined named sensor
501  *
502  * @param port
503  * Reserved, must be MACH_PORT_NULL for now.
504  *
505  * @param sensor_name
506  * String name of sensor to operate on.
507  *
508  * @param sensor_port
509  * Out parameter filled in with mach port name for the newly created
510  * sensor object, must be mach_port_deallocate()d to tear down the access to
511  * the sensor.
512  *
513  * @result
514  * KERN_SUCCESS or mach system call error code.
515  */
516 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
517 kern_return_t
518 exclaves_sensor_create(mach_port_t port, const char *sensor_name, mach_port_t *sensor_port);
519 
520 /*!
521  * @function exclaves_sensor_start
522  *
523  * @abstract
524  * Start accessing a sensor and cause any indicators to display.
525  *
526  * If multiple clients start the same sensor, the sensor will only
527  * actually start on the first client.
528  *
529  * @param sensor_port
530  * A sensor buffer port name returned from exclaves_sensor_create()
531  * for the sensor.
532  *
533  * @param flags to pass to the implementation. Must be 0 for now.
534  *
535  * @param sensor_status
536  * Out parameter filled with the sensor status.
537  *
538  * @result
539  * KERN_SUCCESS or mach system call error code.
540  */
541 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
542 kern_return_t
543 exclaves_sensor_start(mach_port_t sensor_port, uint64_t flags,
544     exclaves_sensor_status_t *sensor_status);
545 
546 /*!
547  * @function exclaves_sensor_stop
548  *
549  * @abstract
550  * Stop accessing a sensor and cause any indicators to stop displaying access.
551  *
552  * If multiple clients are accessing the sensor, sensor access will
553  * continue to display until all clients have called this function.
554  *
555  * @param sensor_port
556  * A sensor buffer port name returned from exclaves_sensor_create()
557  * for the sensor.
558  *
559  * @param flags to pass to the implementation. Must be 0 for now.
560  *
561  * @param sensor_status
562  * Out parameter filled with the sensor status.
563  *
564  * @result
565  * KERN_SUCCESS or mach system call error code.
566  */
567 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
568 kern_return_t
569 exclaves_sensor_stop(mach_port_t sensor_port, uint64_t flags,
570     exclaves_sensor_status_t *sensor_status);
571 
572 /*!
573  * @function exclaves_sensor_status
574  *
575  * @abstract
576  * Get the status of access to a sensor
577  *
578  * @param sensor_port
579  * A sensor buffer port name returned from exclaves_sensor_create()
580  * for the sensor.
581  *
582  * @param flags to pass to the implementation. Must be 0 for now.
583  *
584  * @param sensor_status
585  * Out parameter filled with the sensor status.
586  *
587  * @result
588  * KERN_SUCCESS or mach system call error code.
589  */
590 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
591 kern_return_t
592 exclaves_sensor_status(mach_port_t sensor_port, uint64_t flags,
593     exclaves_sensor_status_t *sensor_status);
594 
595 /*!
596  * @function exclaves_launch_conclave
597  *
598  * @abstract
599  * Launch conclave.
600  *
601  * @param port
602  * Reserved, must be MACH_PORT_NULL for now.
603  *
604  * @param arg1
605  * Reserved, must be NULL for now.
606  *
607  * @param arg2
608  * Reserved, must be 0 for now.
609  *
610  * @result
611  * KERN_SUCCESS or mach system call error code.
612  */
613 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
614 kern_return_t
615 exclaves_launch_conclave(mach_port_t port, void *arg1,
616     uint64_t arg2);
617 
618 /*!
619  * @function exclaves_lookup_service
620  *
621  * @abstract
622  * Lookup Conclave Resource.
623  *
624  * @param port
625  * Reserved, must be MACH_PORT_NULL for now.
626  *
627  * @param name
628  * Name of exclave resource to lookup
629  *
630  * @param resource_id
631  * Out param for resource id
632  *
633  * @result
634  * KERN_SUCCESS or mach system call error code.
635  */
636 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
637 kern_return_t
638 exclaves_lookup_service(mach_port_t port, const char *name, exclaves_id_t *resource_id);
639 
640 /*!
641  * @function exclaves_notification_create
642  *
643  * @abstract
644  * Finds the exclave notification resource with the specified name and
645  * makes it available for use by the calling task.
646  *
647  * @param port
648  * Reserved, must be MACH_PORT_NULL for now.
649  *
650  * @param name
651  * Notification identifier.
652  *
653  * @param notification_id
654  * Out parameter filled in with the notification ID
655  *
656  * @result
657  * KERN_SUCCESS or mach system call error code.
658  */
659 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
660 kern_return_t
661 exclaves_notification_create(mach_port_t port, const char *name, uint64_t *notification_id);
662 
663 #else /* defined(KERNEL) */
664 
665 /*!
666  * @function exclaves_endpoint_call
667  *
668  * @abstract
669  * Perform RPC to an exclaves endpoint via per-thread exclaves IPC buffer.
670  *
671  * @param port
672  * Reserved, must be IPC_PORT_NULL for now.
673  *
674  * @param endpoint_id
675  * Identifier of exclaves endpoint to send RPC to.
676  *
677  * @param tag
678  * In-out parameter for exclaves IPC tag.
679  *
680  * @param error
681  * Out parameter for exclaves IPC error.
682  *
683  * @result
684  * KERN_SUCCESS or mach error code.
685  */
686 kern_return_t
687 exclaves_endpoint_call(ipc_port_t port, exclaves_id_t endpoint_id,
688     exclaves_tag_t *tag, exclaves_error_t *error);
689 
690 /*!
691  * @function exclaves_allocate_ipc_buffer
692  *
693  * @abstract
694  * Increment the current thread's IPC buffer usecount. If the usecount was 0
695  * pre-increment, allocate a new per-thread exclaves IPC buffer and
696  * scheduling context.
697  *
698  * @param ipc_buffer
699  * Out parameter filled in with address of IPC buffer. Can be NULL.
700  *
701  * @result
702  * KERN_SUCCESS or mach error code.
703  */
704 kern_return_t
705 exclaves_allocate_ipc_buffer(void **ipc_buffer);
706 
707 /*!
708  * @function exclaves_free_ipc_buffer
709  *
710  * @abstract
711  * Decrement the current thread's IPC buffer usecount. If the usecount is 0
712  * post-decrement, free the per-thread exclaves IPC buffer and scheduling
713  * context. Asserts if the usecount pre-decrement was 0.
714  *
715  * @result
716  * KERN_SUCCESS or mach error code.
717  */
718 kern_return_t
719 exclaves_free_ipc_buffer(void);
720 
721 /*!
722  * @function exclaves_get_ipc_buffer
723  *
724  * @abstract
725  * Return per-thread exclaves IPC buffer. Does not increment the current
726  * thread's IPC buffer use count.
727  *
728  * @result
729  * If allocated, pointer to per-thread exclaves IPC buffer, NULL otherwise.
730  */
731 OS_CONST
732 void*
733 exclaves_get_ipc_buffer(void);
734 
735 /* For use by Tightbeam kernel runtime only */
736 
737 typedef uint64_t exclaves_badge_t;
738 
739 /*!
740  * @typedef exclaves_upcall_handler_t
741  *
742  * @abstract
743  * RPC message handler for upcalls from exclaves via per-thread exclaves IPC
744  * buffer.
745  *
746  * @param context
747  * Opaque context pointer specified at handler registration.
748  *
749  * @param tag
750  * In-out parameter for exclaves IPC tag.
751  *
752  * @param badge
753  * Badge value identifying upcall RPC message.
754  *
755  * @result
756  * KERN_SUCCESS or mach error code.
757  */
758 typedef kern_return_t
759 (*exclaves_upcall_handler_t)(void *context, exclaves_tag_t *tag,
760     exclaves_badge_t badge);
761 
762 /*!
763  * @function exclaves_register_upcall_handler
764  *
765  * @abstract
766  * One-time registration of exclaves upcall RPC handler for specified upcall ID.
767  * Must be called during Exclaves boot sequence, will assert otherwise.
768  *
769  * @param upcall_id
770  * Identifier of upcall to configure.
771  *
772  * @param upcall_context
773  * Opaque context pointer to pass to upcall RPC handler.
774  *
775  * @param upcall_handler
776  * Pointer to upcall RPC handler.
777  *
778  * @result
779  * KERN_SUCCESS or mach error code.
780  */
781 kern_return_t
782 exclaves_register_upcall_handler(exclaves_id_t upcall_id, void *upcall_context,
783     exclaves_upcall_handler_t upcall_handler);
784 
785 struct XrtHosted_Callbacks;
786 
787 /*!
788  * @function xrt_hosted_register_callbacks
789  *
790  * @abstract
791  * Exclaves XRT hosted kext interface.
792  *
793  * @param callbacks
794  * Pointer to callback function table.
795  */
796 void
797 exclaves_register_xrt_hosted_callbacks(struct XrtHosted_Callbacks *callbacks);
798 
799 /*!
800  * @enum exclaves_sensor_type_t
801  *
802  * @brief
803  * Identifier for an exclaves sensor
804  */
805 OS_ENUM(exclaves_sensor_type, uint32_t,
806     EXCLAVES_SENSOR_CAM = 1,
807     EXCLAVES_SENSOR_MIC = 2,
808     EXCLAVES_SENSOR_CAM_ALT_FACEID = 3,
809     /* update max if more sensors added */
810     EXCLAVES_SENSOR_MAX = 3,
811     );
812 
813 /*!
814  * @function exclaves_sensor_start
815  *
816  * @abstract
817  * Start accessing a sensor and cause any indicators to display.
818  *
819  * If multiple clients start the same sensor, the sensor will only
820  * actually start on the first client.
821  *
822  * @param sensor_type
823  * type of sensor to operate on.
824  *
825  * @param flags to pass to the implementation. Must be 0 for now.
826  *
827  * @param sensor_status
828  * Out parameter filled with the sensor status.
829  *
830  * @result
831  * KERN_SUCCESS or mach system call error code.
832  */
833 kern_return_t
834 exclaves_sensor_start(exclaves_sensor_type_t sensor_type, uint64_t flags,
835     exclaves_sensor_status_t *sensor_status);
836 
837 /*!
838  * @function exclaves_sensor_stop
839  *
840  * @abstract
841  * Stop accessing a sensor and cause any indicators to stop displaying access.
842  *
843  * If multiple clients are accessing the sensor, sensor access will
844  * continue to display until all clients have called this function.
845  *
846  * @param sensor_type
847  * type of sensor to operate on.
848  *
849  * @param flags to pass to the implementation. Must be 0 for now.
850  *
851  * @param sensor_status
852  * Out parameter filled with the sensor status.
853  *
854  * @result
855  * KERN_SUCCESS or mach system call error code.
856  */
857 kern_return_t
858 exclaves_sensor_stop(exclaves_sensor_type_t sensor_type, uint64_t flags,
859     exclaves_sensor_status_t *sensor_status);
860 /*!
861  * @function exclaves_sensor_status
862  *
863  * @abstract
864  * Get the status of access to a sensor
865  *
866  * @param sensor_type
867  * type of sensor to operate on.
868  *
869  * @param sensor_status
870  * Out parameter filled with the sensor status.
871  *
872  * @param flags to pass to the implementation. Must be 0 for now.
873  *
874  * @result
875  * KERN_SUCCESS or mach system call error code.
876  */
877 kern_return_t
878 exclaves_sensor_status(exclaves_sensor_type_t sensor_type, uint64_t flags,
879     exclaves_sensor_status_t *sensor_status);
880 
881 /*!
882  * @function exclaves_display_healthcheck_rate
883  *
884  * @abstract
885  * Update the rate of the display healthcheck based on the specified
886  * display update rate
887  *
888  * @param ns
889  * The rate in nanoseconds.
890  * Note: This value may be be rounded to the nearest rate supported and not used
891  * as-is.
892  *
893  * @result
894  * KERN_SUCCESS or mach system call error code.
895  */
896 kern_return_t
897 exclaves_display_healthcheck_rate(uint64_t ns);
898 
899 #endif /* defined(KERNEL) */
900 
901 #if defined(MACH_KERNEL_PRIVATE)
902 
903 /* -------------------------------------------------------------------------- */
904 
905 /* Internal kernel interface */
906 
907 extern kern_return_t
908 exclaves_thread_terminate(thread_t thread);
909 
910 extern bool
911 exclaves_booted(void);
912 
913 extern size_t
914 exclaves_ipc_buffer_count(void);
915 
916 OS_ENUM(exclaves_clock_type, uint8_t,
917     EXCLAVES_CLOCK_ABSOLUTE = 0,
918     EXCLAVES_CLOCK_CONTINUOUS = 1,
919     );
920 
921 extern void
922 exclaves_update_timebase(exclaves_clock_type_t type, uint64_t offset);
923 
924 typedef struct {
925 	void *ipcb;
926 	unsigned long scid;
927 	uint64_t usecnt;
928 } exclaves_ctx_t;
929 
930 #endif /* defined(MACH_KERNEL_PRIVATE) */
931 
932 /* -------------------------------------------------------------------------- */
933 
934 /* Private interface between Libsyscall and xnu */
935 
936 OS_ENUM(exclaves_ctl_op, uint8_t,
937     EXCLAVES_CTL_OP_ENDPOINT_CALL = 1,
938     EXCLAVES_CTL_OP_NAMED_BUFFER_CREATE = 2,
939     EXCLAVES_CTL_OP_NAMED_BUFFER_COPYIN = 3,
940     EXCLAVES_CTL_OP_NAMED_BUFFER_COPYOUT = 4,
941     EXCLAVES_CTL_OP_BOOT = 5,
942     EXCLAVES_CTL_OP_LAUNCH_CONCLAVE = 6,
943     EXCLAVES_CTL_OP_LOOKUP_SERVICES = 7,
944     EXCLAVES_CTL_OP_AUDIO_BUFFER_CREATE = 8,
945     EXCLAVES_CTL_OP_AUDIO_BUFFER_COPYOUT = 9,
946     EXCLAVES_CTL_OP_SENSOR_CREATE = 10,
947     EXCLAVES_CTL_OP_SENSOR_START = 11,
948     EXCLAVES_CTL_OP_SENSOR_STOP = 12,
949     EXCLAVES_CTL_OP_SENSOR_STATUS = 13,
950     EXCLAVES_CTL_OP_NOTIFICATION_RESOURCE_LOOKUP = 14,
951     EXCLAVES_CTL_OP_LAST,
952     );
953 #define EXCLAVES_CTL_FLAGS_MASK (0xfffffful)
954 #define EXCLAVES_CTL_OP_AND_FLAGS(op, flags) \
955 	((uint32_t)EXCLAVES_CTL_OP_##op << 24 | \
956 	((uint32_t)(flags) & EXCLAVES_CTL_FLAGS_MASK))
957 #define EXCLAVES_CTL_OP(op_and_flags) \
958 	((uint8_t)((op_and_flags) >> 24))
959 #define EXCLAVES_CTL_FLAGS(op_and_flags) \
960 	((uint32_t)(op_and_flags) & EXCLAVES_CTL_FLAGS_MASK)
961 
962 /*!
963  * @struct exclaves_resource_user
964  *
965  * @brief
966  * User representation of exclave resource
967  */
968 typedef struct exclaves_resource_user {
969 	char                  r_name[MAXCONCLAVENAME];
970 	uint64_t              r_type;
971 	exclaves_id_t         r_id;
972 	mach_port_name_t      r_port;
973 } exclaves_resouce_user_t;
974 
975 #if !defined(KERNEL)
976 
977 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
978 OS_NOT_TAIL_CALLED
979 kern_return_t
980 _exclaves_ctl_trap(mach_port_name_t name, uint32_t operation_and_flags,
981     exclaves_id_t identifier, mach_vm_address_t buffer, mach_vm_size_t size,
982     mach_vm_size_t size2, mach_vm_size_t offset);
983 
984 #endif /* !defined(KERNEL) */
985 
986 /* -------------------------------------------------------------------------- */
987 
988 /* Sysctl interface */
989 
990 #if defined(KERNEL)
991 
992 /*!
993  * @function exclaves_get_status
994  *
995  * @abstract
996  * Return the current running status of exclaves. This function will block until
997  * exclaves has booted, failed to boot, or are known to be not available.
998  *
999  * @result
1000  * The status of exclaves.
1001  */
1002 exclaves_status_t
1003 exclaves_get_status(void);
1004 
1005 #endif /* defined(KERNEL) */
1006 
1007 #if defined(XNU_KERNEL_PRIVATE)
1008 
1009 /*!
1010  * @function exclaves_get_boot_stage
1011  *
1012  * @abstract
1013  * Return the current boot stage of exclaves. This function will not block.
1014  * In general this shouldn't be used (other than for the sysctl).
1015  * exclaves_boot_wait() is mostly what is wanted.
1016  *
1017  * @result
1018  * The boot stage of exclaves.
1019  */
1020 exclaves_boot_stage_t
1021 exclaves_get_boot_stage(void);
1022 
1023 /*!
1024  * @function exclaves_boot_supported
1025  *
1026  * @abstract
1027  * Determine if exclaves are supported. This is a basic check essentially equal
1028  * to checking whether the current kernel was compiled with CONFIG_EXCLAVES and
1029  * whether or not SPTM has disabled cL4.
1030  *
1031  * @result
1032  * True if supported, false otherwise.
1033  */
1034 bool
1035 exclaves_boot_supported(void);
1036 
1037 /*!
1038  * @function exclaves_boot_wait
1039  *
1040  * @abstract
1041  * Wait until the specified boot stage has been reached.
1042  *
1043  * @result
1044  * KERN_SUCCESS when the boot stage has been reached, KERN_NOT_SUPPORTED if
1045  * exclaves are not supported.
1046  */
1047 /* BEGIN IGNORE CODESTYLE */
1048 kern_return_t
1049 exclaves_boot_wait(exclaves_boot_stage_t);
1050 /* END IGNORE CODESTYLE */
1051 
1052 /*
1053  * Identifies exclaves privilege checks.
1054  */
1055 __options_closed_decl(exclaves_priv_t, unsigned int, {
1056 	EXCLAVES_PRIV_CONCLAVE_HOST  = 0x1,  /* Can host conclaves. */
1057 	EXCLAVES_PRIV_CONCLAVE_SPAWN = 0x2,  /* Can spawn conclaves. */
1058 	EXCLAVES_PRIV_KERNEL_DOMAIN  = 0x4,  /* Access to kernel resources. */
1059 	EXCLAVES_PRIV_BOOT           = 0x8,  /* Can boot exclaves. */
1060 });
1061 
1062 /*
1063  * Check to see if the specified task has a privilege.
1064  */
1065 extern bool
1066 exclaves_has_priv(task_t task, exclaves_priv_t priv);
1067 
1068 /*
1069  * Check to see if the specified vnode has a privilege.
1070  * Vnode argument is untyped as it's not available to osfmk.
1071  */
1072 extern bool
1073 exclaves_has_priv_vnode(void *vnode, int64_t off, exclaves_priv_t priv);
1074 
1075 /* Return index of last xnu frame before secure world. Valid frame index is
1076  * always in range <0, nframes-1>. When frame is not found, return nframes
1077  * value. */
1078 uint32_t exclaves_stack_offset(const uintptr_t *out_addr, size_t nframes,
1079     bool slid_addresses);
1080 
1081 /* Check whether Exclave inspection got initialized */
1082 extern bool exclaves_inspection_is_initialized(void);
1083 
1084 #endif /* defined(XNU_KERNEL_PRIVATE) */
1085 
1086 __END_DECLS
1087 
1088 #endif /* defined(PRIVATE) */
1089 
1090 #endif /* _MACH_EXCLAVES_H */
1091