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