xref: /xnu-11417.121.6/osfmk/mach/exclaves.h (revision a1e26a70f38d1d7daa7b49b258e2f8538ad81650)
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_indicator_min_on_time
665  *
666  * @abstract
667  * Get time remaining until minimum on time is satisfied for all sensor types.
668  * The return value for each indicator type is a future clock tick on the Global time base
669  * if the minimum on time is not satisfied, and 0 otherwise.
670  *
671  * @param port Reserved, must be MACH_PORT_NULL for now.
672  * @param flags Reserved, must be 0 for now.
673  * @param camera_indicator Out parameter filled with remaining camera indicator time to meet minimum on time
674  * @param mic_indicator Out parameter filled with remaining microphone indicator time to meet minimum on time
675  * @param faceid Out parameter filled with remaining Face ID indicator time to meet minimum on time
676  *
677  * @result
678  * KERN_SUCCESS or mach system call error code.
679  */
680 
681 SPI_AVAILABLE(macos(15.5), ios(18.5), tvos(18.5), watchos(11.5), visionos(2.5))
682 kern_return_t
683 exclaves_indicator_min_on_time(mach_port_t port, uint64_t flags,
684     uint64_t *camera_indicator, uint64_t *mic_indicator, uint64_t *faceid);
685 
686 /*!
687  * @function exclaves_launch_conclave
688  *
689  * @abstract
690  * Launch conclave.
691  *
692  * @param port
693  * Reserved, must be MACH_PORT_NULL for now.
694  *
695  * @param arg1
696  * Reserved, must be NULL for now.
697  *
698  * @param arg2
699  * Reserved, must be 0 for now.
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_launch_conclave(mach_port_t port, void *arg1,
707     uint64_t arg2);
708 
709 /*!
710  * @function exclaves_lookup_service
711  *
712  * @abstract
713  * Lookup Conclave Resource.
714  *
715  * @param port
716  * Reserved, must be MACH_PORT_NULL for now.
717  *
718  * @param name
719  * Name of exclave resource to lookup
720  *
721  * @param resource_id
722  * Out param for resource 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_lookup_service(mach_port_t port, const char *name, exclaves_id_t *resource_id);
730 
731 /*!
732  * @function exclaves_notification_create
733  *
734  * @abstract
735  * Finds the exclave notification resource with the specified name and
736  * makes it available for use by the calling task.
737  *
738  * @param port
739  * Reserved, must be MACH_PORT_NULL for now.
740  *
741  * @param name
742  * Notification identifier.
743  *
744  * @param notification_id
745  * Out parameter filled in with the notification ID
746  *
747  * @result
748  * KERN_SUCCESS or mach system call error code.
749  */
750 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
751 kern_return_t
752 exclaves_notification_create(mach_port_t port, const char *name, uint64_t *notification_id);
753 
754 #else /* defined(KERNEL) */
755 
756 /*!
757  * @function exclaves_endpoint_call
758  *
759  * @abstract
760  * Perform RPC to an exclaves endpoint via per-thread exclaves IPC buffer.
761  *
762  * @param port
763  * Reserved, must be IPC_PORT_NULL for now.
764  *
765  * @param endpoint_id
766  * Identifier of exclaves endpoint to send RPC to.
767  *
768  * @param tag
769  * In-out parameter for exclaves IPC tag.
770  *
771  * @param error
772  * Out parameter for exclaves IPC error.
773  *
774  * @result
775  * KERN_SUCCESS or mach error code.
776  */
777 kern_return_t
778 exclaves_endpoint_call(ipc_port_t port, exclaves_id_t endpoint_id,
779     exclaves_tag_t *tag, exclaves_error_t *error);
780 
781 /*!
782  * @function exclaves_allocate_ipc_buffer
783  *
784  * @abstract
785  * Increment the current thread's IPC buffer usecount. If the usecount was 0
786  * pre-increment, allocate a new per-thread exclaves IPC buffer and
787  * scheduling context.
788  *
789  * @param ipc_buffer
790  * Out parameter filled in with address of IPC buffer. Can be NULL.
791  *
792  * @result
793  * KERN_SUCCESS or mach error code.
794  */
795 kern_return_t
796 exclaves_allocate_ipc_buffer(void **ipc_buffer);
797 
798 /*!
799  * @function exclaves_free_ipc_buffer
800  *
801  * @abstract
802  * Decrement the current thread's IPC buffer usecount. If the usecount is 0
803  * post-decrement, free the per-thread exclaves IPC buffer and scheduling
804  * context. Asserts if the usecount pre-decrement was 0.
805  *
806  * @result
807  * KERN_SUCCESS or mach error code.
808  */
809 kern_return_t
810 exclaves_free_ipc_buffer(void);
811 
812 /*!
813  * @function exclaves_get_ipc_buffer
814  *
815  * @abstract
816  * Return per-thread exclaves IPC buffer. Does not increment the current
817  * thread's IPC buffer use count.
818  *
819  * @result
820  * If allocated, pointer to per-thread exclaves IPC buffer, NULL otherwise.
821  */
822 OS_CONST
823 void*
824 exclaves_get_ipc_buffer(void);
825 
826 /* For use by Tightbeam kernel runtime only */
827 
828 typedef uint64_t exclaves_badge_t;
829 
830 /*!
831  * @typedef exclaves_upcall_handler_t
832  *
833  * @abstract
834  * RPC message handler for upcalls from exclaves via per-thread exclaves IPC
835  * buffer.
836  *
837  * @param context
838  * Opaque context pointer specified at handler registration.
839  *
840  * @param tag
841  * In-out parameter for exclaves IPC tag.
842  *
843  * @param badge
844  * Badge value identifying upcall RPC message.
845  *
846  * @result
847  * KERN_SUCCESS or mach error code.
848  */
849 typedef kern_return_t
850 (*exclaves_upcall_handler_t)(void *context, exclaves_tag_t *tag,
851     exclaves_badge_t badge);
852 
853 /*!
854  * @function exclaves_register_upcall_handler
855  *
856  * @abstract
857  * One-time registration of exclaves upcall RPC handler for specified upcall ID.
858  * Must be called during Exclaves boot sequence, will assert otherwise.
859  *
860  * @param upcall_id
861  * Identifier of upcall to configure.
862  *
863  * @param upcall_context
864  * Opaque context pointer to pass to upcall RPC handler.
865  *
866  * @param upcall_handler
867  * Pointer to upcall RPC handler.
868  *
869  * @result
870  * KERN_SUCCESS or mach error code.
871  */
872 kern_return_t
873 exclaves_register_upcall_handler(exclaves_id_t upcall_id, void *upcall_context,
874     exclaves_upcall_handler_t upcall_handler);
875 
876 struct XrtHosted_Callbacks;
877 
878 /*!
879  * @function xrt_hosted_register_callbacks
880  *
881  * @abstract
882  * Exclaves XRT hosted kext interface.
883  *
884  * @param callbacks
885  * Pointer to callback function table.
886  */
887 void
888 exclaves_register_xrt_hosted_callbacks(struct XrtHosted_Callbacks *callbacks);
889 
890 /*!
891  * @enum exclaves_sensor_type_t
892  *
893  * @brief
894  * Identifier for an exclaves sensor
895  */
896 OS_ENUM(exclaves_sensor_type, uint32_t,
897     EXCLAVES_SENSOR_CAM = 1,
898     EXCLAVES_SENSOR_MIC = 2,
899     EXCLAVES_SENSOR_CAM_ALT_FACEID = 3,
900     EXCLAVES_SENSOR_CAM_ALT_FACEID_DELAYED = 4,
901     /* update max if more sensors added */
902     EXCLAVES_SENSOR_MAX = 4,
903     );
904 
905 /*!
906  * @function exclaves_sensor_start
907  *
908  * @abstract
909  * Start accessing a sensor and cause any indicators to display.
910  *
911  * If multiple clients start the same sensor, the sensor will only
912  * actually start on the first client.
913  *
914  * @param sensor_type
915  * type of sensor to operate on.
916  *
917  * @param flags to pass to the implementation. Must be 0 for now.
918  *
919  * @param sensor_status
920  * Out parameter filled with the sensor status.
921  *
922  * @result
923  * KERN_SUCCESS or mach system call error code.
924  */
925 kern_return_t
926 exclaves_sensor_start(exclaves_sensor_type_t sensor_type, uint64_t flags,
927     exclaves_sensor_status_t *sensor_status);
928 
929 /*!
930  * @function exclaves_sensor_stop
931  *
932  * @abstract
933  * Stop accessing a sensor and cause any indicators to stop displaying access.
934  *
935  * If multiple clients are accessing the sensor, sensor access will
936  * continue to display until all clients have called this function.
937  *
938  * @param sensor_type
939  * type of sensor to operate on.
940  *
941  * @param flags to pass to the implementation. Must be 0 for now.
942  *
943  * @param sensor_status
944  * Out parameter filled with the sensor status.
945  *
946  * @result
947  * KERN_SUCCESS or mach system call error code.
948  */
949 kern_return_t
950 exclaves_sensor_stop(exclaves_sensor_type_t sensor_type, uint64_t flags,
951     exclaves_sensor_status_t *sensor_status);
952 
953 /*!
954  * @function exclaves_sensor_status
955  *
956  * @abstract
957  * Get the status of access to a sensor
958  *
959  * @param sensor_type
960  * type of sensor to operate on.
961  *
962  * @param sensor_status
963  * Out parameter filled with the sensor status.
964  *
965  * @param flags to pass to the implementation. Must be 0 for now.
966  *
967  * @result
968  * KERN_SUCCESS or mach system call error code.
969  */
970 kern_return_t
971 exclaves_sensor_status(exclaves_sensor_type_t sensor_type, uint64_t flags,
972     exclaves_sensor_status_t *sensor_status);
973 
974 /*!
975  * @function exclaves_sensor_tick_rate
976  *
977  * @abstract
978  * Set the fire rate of the timer that ticks the EIC periodically.
979  * This should only be called by the brightness stack to adjust the rate at which
980  * LED indicators can get new brightness values.
981  *
982  * @param rate_hz
983  * Timer rate in Hz.
984  *
985  * @result
986  * KERN_SUCCESS or mach system call error code.
987  */
988 kern_return_t
989 exclaves_sensor_tick_rate(uint64_t rate_hz);
990 
991 /*!
992  * @function exclaves_display_healthcheck_rate
993  *
994  * @abstract
995  * Deprecated, no longer does anything.
996  *
997  * @param ns
998  * Unused.
999  *
1000  * @result
1001  * KERN_SUCCESS.
1002  */
1003 /* __kpi_deprecated("Inoperative noop, can remove") */
1004 kern_return_t
1005 exclaves_display_healthcheck_rate(uint64_t ns);
1006 
1007 #endif /* defined(KERNEL) */
1008 
1009 #if defined(MACH_KERNEL_PRIVATE)
1010 
1011 /* -------------------------------------------------------------------------- */
1012 
1013 /* Internal kernel interface */
1014 
1015 extern kern_return_t
1016 exclaves_thread_terminate(thread_t thread);
1017 
1018 extern bool
1019 exclaves_booted(void);
1020 
1021 extern size_t
1022 exclaves_ipc_buffer_count(void);
1023 
1024 OS_ENUM(exclaves_clock_type, uint8_t,
1025     EXCLAVES_CLOCK_ABSOLUTE = 0,
1026     EXCLAVES_CLOCK_CONTINUOUS = 1,
1027     );
1028 
1029 extern void
1030 exclaves_update_timebase(exclaves_clock_type_t type, uint64_t offset);
1031 
1032 typedef struct {
1033 	void *ipcb;
1034 	unsigned long scid;
1035 	uint64_t usecnt;
1036 } exclaves_ctx_t;
1037 
1038 #endif /* defined(MACH_KERNEL_PRIVATE) */
1039 
1040 /* -------------------------------------------------------------------------- */
1041 
1042 /* Private interface between Libsyscall and xnu */
1043 
1044 OS_ENUM(exclaves_ctl_op, uint8_t,
1045     EXCLAVES_CTL_OP_ENDPOINT_CALL = 1,
1046     EXCLAVES_CTL_OP_NAMED_BUFFER_CREATE = 2,
1047     EXCLAVES_CTL_OP_NAMED_BUFFER_COPYIN = 3,
1048     EXCLAVES_CTL_OP_NAMED_BUFFER_COPYOUT = 4,
1049     EXCLAVES_CTL_OP_BOOT = 5,
1050     EXCLAVES_CTL_OP_LAUNCH_CONCLAVE = 6,
1051     EXCLAVES_CTL_OP_LOOKUP_SERVICES = 7,
1052     EXCLAVES_CTL_OP_AUDIO_BUFFER_CREATE = 8,
1053     EXCLAVES_CTL_OP_AUDIO_BUFFER_COPYOUT = 9,
1054     EXCLAVES_CTL_OP_SENSOR_CREATE = 10,
1055     EXCLAVES_CTL_OP_SENSOR_START = 11,
1056     EXCLAVES_CTL_OP_SENSOR_STOP = 12,
1057     EXCLAVES_CTL_OP_SENSOR_STATUS = 13,
1058     EXCLAVES_CTL_OP_NOTIFICATION_RESOURCE_LOOKUP = 14,
1059     EXCLAVES_CTL_OP_SENSOR_MIN_ON_TIME = 15,
1060     EXCLAVES_CTL_OP_LAST,
1061     );
1062 #define EXCLAVES_CTL_FLAGS_MASK (0xfffffful)
1063 #define EXCLAVES_CTL_OP_AND_FLAGS(op, flags) \
1064 	((uint32_t)EXCLAVES_CTL_OP_##op << 24 | \
1065 	((uint32_t)(flags) & EXCLAVES_CTL_FLAGS_MASK))
1066 #define EXCLAVES_CTL_OP(op_and_flags) \
1067 	((uint8_t)((op_and_flags) >> 24))
1068 #define EXCLAVES_CTL_FLAGS(op_and_flags) \
1069 	((uint32_t)(op_and_flags) & EXCLAVES_CTL_FLAGS_MASK)
1070 
1071 /*!
1072  * @struct exclaves_resource_user
1073  *
1074  * @brief
1075  * User representation of exclave resource
1076  */
1077 typedef struct exclaves_resource_user {
1078 	char                  r_name[MAXCONCLAVENAME];
1079 	uint64_t              r_type;
1080 	exclaves_id_t         r_id;
1081 	mach_port_name_t      r_port;
1082 } exclaves_resouce_user_t;
1083 
1084 /*!
1085  * @struct exclaves_indicator_deadline
1086  *
1087  * @brief
1088  * This struct will contain the amount of time remaining before
1089  * minimum on time is met for various sensors
1090  */
1091 typedef struct exclaves_indicator_deadlines {
1092 	uint64_t version;
1093 	uint64_t camera_indicator;
1094 	uint64_t mic_indicator;
1095 	uint64_t faceid_indicator;
1096 } exclaves_indicator_deadlines_t;
1097 
1098 #if !defined(KERNEL)
1099 
1100 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
1101 OS_NOT_TAIL_CALLED
1102 kern_return_t
1103 _exclaves_ctl_trap(mach_port_name_t name, uint32_t operation_and_flags,
1104     exclaves_id_t identifier, mach_vm_address_t buffer, mach_vm_size_t size,
1105     mach_vm_size_t size2, mach_vm_size_t offset, mach_vm_address_t status);
1106 
1107 #endif /* !defined(KERNEL) */
1108 
1109 /* -------------------------------------------------------------------------- */
1110 
1111 /* Sysctl interface */
1112 
1113 #if defined(KERNEL)
1114 
1115 /*!
1116  * @function exclaves_get_status
1117  *
1118  * @abstract
1119  * Return the current running status of exclaves. This function will block until
1120  * exclaves has booted, failed to boot, or are known to be not available.
1121  *
1122  * @result
1123  * The status of exclaves.
1124  */
1125 exclaves_status_t
1126 exclaves_get_status(void);
1127 
1128 #endif /* defined(KERNEL) */
1129 
1130 #if defined(XNU_KERNEL_PRIVATE)
1131 
1132 /*!
1133  * @function exclaves_get_boot_stage
1134  *
1135  * @abstract
1136  * Return the current boot stage of exclaves. This function will not block.
1137  * In general this shouldn't be used (other than for the sysctl).
1138  * exclaves_boot_wait() is mostly what is wanted.
1139  *
1140  * @result
1141  * The boot stage of exclaves.
1142  */
1143 exclaves_boot_stage_t
1144 exclaves_get_boot_stage(void);
1145 
1146 /*!
1147  * @function exclaves_boot_supported
1148  *
1149  * @abstract
1150  * Determine if exclaves are supported. This is a basic check essentially equal
1151  * to checking whether the current kernel was compiled with CONFIG_EXCLAVES and
1152  * whether or not SPTM has disabled cL4.
1153  *
1154  * @result
1155  * True if supported, false otherwise.
1156  */
1157 bool
1158 exclaves_boot_supported(void);
1159 
1160 /*!
1161  * @function exclaves_boot_wait
1162  *
1163  * @abstract
1164  * Wait until the specified boot stage has been reached.
1165  *
1166  * @result
1167  * KERN_SUCCESS when the boot stage has been reached, KERN_NOT_SUPPORTED if
1168  * exclaves are not supported.
1169  */
1170 /* BEGIN IGNORE CODESTYLE */
1171 kern_return_t
1172 exclaves_boot_wait(exclaves_boot_stage_t);
1173 /* END IGNORE CODESTYLE */
1174 
1175 /*
1176  * Identifies exclaves privilege checks.
1177  */
1178 __options_closed_decl(exclaves_priv_t, unsigned int, {
1179 	EXCLAVES_PRIV_CONCLAVE_HOST  = 0x1,  /* Can host conclaves. */
1180 	EXCLAVES_PRIV_CONCLAVE_SPAWN = 0x2,  /* Can spawn conclaves. */
1181 	EXCLAVES_PRIV_KERNEL_DOMAIN  = 0x4,  /* Access to kernel resources. */
1182 	EXCLAVES_PRIV_BOOT           = 0x8,  /* Can boot exclaves. */
1183 	EXCLAVES_PRIV_INDICATOR_MIN_ON_TIME = 0x10 /* Can access sensor minimum on time*/
1184 });
1185 
1186 /*
1187  * Check to see if the specified task has a privilege.
1188  */
1189 extern bool
1190 exclaves_has_priv(task_t task, exclaves_priv_t priv);
1191 
1192 /*
1193  * Check to see if the specified vnode has a privilege.
1194  * Vnode argument is untyped as it's not available to osfmk.
1195  */
1196 extern bool
1197 exclaves_has_priv_vnode(void *vnode, int64_t off, exclaves_priv_t priv);
1198 
1199 /* Return index of last xnu frame before secure world. Valid frame index is
1200  * always in range <0, nframes-1>. When frame is not found, return nframes
1201  * value. */
1202 uint32_t exclaves_stack_offset(const uintptr_t *out_addr, size_t nframes,
1203     bool slid_addresses);
1204 
1205 /* Check whether Exclave inspection got initialized */
1206 extern bool exclaves_inspection_is_initialized(void);
1207 
1208 /* Send a watchdog panic request to the exclaves scheduler */
1209 extern kern_return_t exclaves_scheduler_request_watchdog_panic(void);
1210 
1211 #endif /* defined(XNU_KERNEL_PRIVATE) */
1212 
1213 __END_DECLS
1214 
1215 #endif /* defined(PRIVATE) */
1216 
1217 #endif /* _MACH_EXCLAVES_H */
1218