xref: /xnu-12377.41.6/osfmk/mach/exclaves.h (revision bbb1b6f9e71b8cdde6e5cd6f4841f207dee3d828)
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      * Framebank initialization.
138      * If relaxed and framebank initialization fails, set exclavekit boot to failed and continue on without
139      * panicking. All conclave related functionality will fail.
140      */
141     EXCLAVES_R_FRAMEBANK   = 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      * Support for Always On Exclaves.
172      */
173     EXCLAVES_R_AOE          = 0x800,
174 
175     /*
176      * ExclaveKit initialization.
177      * If relaxed, skip exclavekit initialization and continue on without
178      * panicking. All conclave related functionality will fail.
179      */
180     EXCLAVES_R_EXCLAVEKIT   = 0x1000,
181 
182     );
183 
184 #if !defined(KERNEL)
185 
186 /*!
187  * @function exclaves_endpoint_call
188  *
189  * @abstract
190  * Perform RPC to an exclaves endpoint.
191  *
192  * @param port
193  * Reserved, must be MACH_PORT_NULL for now.
194  *
195  * @param endpoint_id
196  * Identifier of exclaves endpoint to send RPC to.
197  *
198  * @param msg_buffer
199  * Pointer to exclaves IPC buffer.
200  *
201  * @param size
202  * Size of specified exclaves IPC buffer.
203  *
204  * @param tag
205  * In-out parameter for exclaves IPC tag.
206  *
207  * @param error
208  * Out parameter for exclaves IPC error.
209  *
210  * @result
211  * KERN_SUCCESS or mach system call error code.
212  */
213 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
214 kern_return_t
215 exclaves_endpoint_call(mach_port_t port, exclaves_id_t endpoint_id,
216     mach_vm_address_t msg_buffer, mach_vm_size_t size, exclaves_tag_t *tag,
217     exclaves_error_t *error);
218 
219 /*!
220  * @function exclaves_outbound_buffer_create
221  *
222  * @abstract
223  * Setup access by xnu to a pre-defined exclaves outbound memory buffer and
224  * return a mach port for it. The buffer can only be read from.
225  *
226  * @param port
227  * Reserved, must be MACH_PORT_NULL for now.
228  *
229  * @param buffer_name
230  * String name of buffer to operate on.
231  *
232  * @param size
233  * Size of requested outbound buffer.
234  *
235  * @param outbound_buffer_port
236  * Out parameter filled in with mach port name for the newly created outbound
237  * buffer object, must be mach_port_deallocate()d to tear down the access to
238  * the outbound buffer.
239  *
240  * @result
241  * KERN_SUCCESS or mach system call error code.
242  */
243 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
244 kern_return_t
245 exclaves_outbound_buffer_create(mach_port_t port, const char *buffer_name,
246     mach_vm_size_t size, mach_port_t *outbound_buffer_port);
247 
248 /*!
249  * @function exclaves_outbound_buffer_copyout
250  *
251  * @abstract
252  * Copy out to specified userspace buffer from previously setup exclaves
253  * outbound memory buffer.
254  *
255  * Two size/offsets are provided to faciliate fast copy that wraps around a ring
256  * buffer that could be placed arbitrarily in the outbound memory region.
257  *
258  * @param outbound_buffer_port
259  * A outbound buffer port name returned from exclaves_outbound_buffer_create()
260  *
261  * @param dst_buffer
262  * Pointer to userspace buffer to copy out from outbound buffer.
263  *
264  * @param size1
265  * Number of bytes to copy (<= size of specified userspace buffer).
266  *
267  * @param offset1
268  * Offset in outbound memory buffer to start copy at.
269  *
270  * @param size2
271  * Number of bytes to copy (<= size of specified userspace buffer). Can be 0,
272  * in which case the 2nd range is not copied.
273  *
274  * @param offset2
275  * Offset in outbound memory buffer to start copy at.
276  *
277  * @result
278  * KERN_SUCCESS or mach system call error code.
279  */
280 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
281 kern_return_t
282 exclaves_outbound_buffer_copyout(mach_port_t outbound_buffer_port,
283     mach_vm_address_t dst_buffer, mach_vm_size_t size1, mach_vm_size_t offset1,
284     mach_vm_size_t size2, mach_vm_size_t offset2);
285 
286 /*!
287  * @function exclaves_inbound_buffer_create
288  *
289  * @abstract
290  * Setup access by xnu to a pre-defined exclaves inbound memory buffer and
291  * return a mach port for it. The buffer can be both read from and written to.
292  *
293  * @param port
294  * Reserved, must be MACH_PORT_NULL for now.
295  *
296  * @param buffer_name
297  * String name of buffer to operate on.
298  *
299  * @param size
300  * Size of requested inbound buffer.
301  *
302  * @param inbound_buffer_port
303  * Out parameter filled in with mach port name for the newly created inbound
304  * buffer object, must be mach_port_deallocate()d to tear down the access to
305  * the inbound buffer.
306  *
307  * @result
308  * KERN_SUCCESS or mach system call error code.
309  */
310 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
311 kern_return_t
312 exclaves_inbound_buffer_create(mach_port_t port, const char *buffer_name,
313     mach_vm_size_t size, mach_port_t *inbound_buffer_port);
314 
315 /*!
316  * @function exclaves_inbound_buffer_copyin
317  *
318  * @abstract
319  * Copy from specified userspace buffer into previously setup inbound exclaves
320  * inbound memory buffer.
321  *
322  * Two size/offsets are provided to faciliate fast copy that wraps around a ring
323  * buffer that could be placed arbitrarily in the inbound memory region.
324  *
325  * @param inbound_buffer_port
326  * An inbound buffer port name returned from exclaves_inbound_buffer_create()
327  *
328  * @param src_buffer
329  * Pointer to userspace buffer to copy into inbound buffer.
330  *
331  * @param size1
332  * Number of bytes to copy (<= size of specified userspace buffer).
333  *
334  * @param offset1
335  * Offset in inbound memory buffer to start copy at.
336  *
337  * @param size2
338  * Number of bytes to copy (<= size of specified userspace buffer). Can be 0,
339  * in which case the 2nd range is not copied.
340  *
341  * @param offset2
342  * Offset in inbound memory buffer to start copy at.
343  *
344  * @result
345  * KERN_SUCCESS or mach system call error code. Some buffers are read-only and
346  * calls to exclaves_inbound_buffer_copyin() will result in
347  * KERN_PROTECTION_FAILURE.
348  */
349 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
350 kern_return_t
351 exclaves_inbound_buffer_copyin(mach_port_t inbound_buffer_port,
352     mach_vm_address_t src_buffer, mach_vm_size_t size1, mach_vm_size_t offset1,
353     mach_vm_size_t size2, mach_vm_size_t offset2);
354 
355 /*!
356  * @function exclaves_named_buffer_create
357  *
358  * @abstract
359  * Setup access by xnu to a pre-defined named exclaves shared memory buffer
360  * and return a mach port for it.
361  *
362  * @param port
363  * Reserved, must be MACH_PORT_NULL for now.
364  *
365  * @param buffer_id
366  * Identifier of named buffer to operate on.
367  *
368  * @param size
369  * Size of requested named buffer.
370  *
371  * @param named_buffer_port
372  * Out parameter filled in with mach port name for the newly created named
373  * buffer object, must be mach_port_deallocate()d to tear down the access to
374  * the named buffer.
375  *
376  * @result
377  * KERN_SUCCESS or mach system call error code.
378  */
379 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
380 kern_return_t
381 exclaves_named_buffer_create(mach_port_t port, exclaves_id_t buffer_id,
382     mach_vm_size_t size, mach_port_t* named_buffer_port);
383 
384 /*!
385  * @function exclaves_named_buffer_copyin
386  *
387  * @abstract
388  * Copy from specified userspace buffer into previously setup named exclaves
389  * shared memory buffer.
390  *
391  * @param named_buffer_port
392  * A named buffer port name returned from exclaves_named_buffer_create()
393  *
394  * @param src_buffer
395  * Pointer to userspace buffer to copy into named buffer.
396  *
397  * @param size
398  * Number of bytes to copy (<= size of specified userspace buffer).
399  *
400  * @param offset
401  * Offset in shared memory buffer to start copy at.
402  *
403  * @result
404  * KERN_SUCCESS or mach system call error code.
405  */
406 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
407 kern_return_t
408 exclaves_named_buffer_copyin(mach_port_t named_buffer_port,
409     mach_vm_address_t src_buffer, mach_vm_size_t size, mach_vm_size_t offset);
410 
411 /*!
412  * @function exclaves_named_buffer_copyout
413  *
414  * @abstract
415  * Copy out to specified userspace buffer from previously setup named exclaves
416  * shared memory buffer.
417  *
418  * @param named_buffer_port
419  * A named buffer port name returned from exclaves_named_buffer_create()
420  *
421  * @param dst_buffer
422  * Pointer to userspace buffer to copy out from named buffer.
423  *
424  * @param size
425  * Number of bytes to copy (<= size of specified userspace buffer).
426  *
427  * @param offset
428  * Offset in shared memory buffer to start copy at.
429  *
430  * @result
431  * KERN_SUCCESS or mach system call error code.
432  */
433 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
434 kern_return_t
435 exclaves_named_buffer_copyout(mach_port_t named_buffer_port,
436     mach_vm_address_t dst_buffer, mach_vm_size_t size, mach_vm_size_t offset);
437 
438 /*!
439  * @function exclaves_boot
440  *
441  * @abstract
442  * Perform exclaves boot.
443  *
444  * @param port
445  * Reserved, must be MACH_PORT_NULL for now.
446  *
447  * @param boot_stage
448  * Stage of boot requested
449  *
450  * @result
451  * KERN_SUCCESS or mach system call error code.
452  */
453 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
454 kern_return_t
455 exclaves_boot(mach_port_t port, exclaves_boot_stage_t boot_stage);
456 
457 /*!
458  * @function exclaves_audio_buffer_create
459  *
460  * @abstract
461  * Setup access by xnu to a pre-defined named exclaves audio shared memory
462  * buffer and return a mach port for it.
463  *
464  * @param port
465  * Reserved, must be MACH_PORT_NULL for now.
466  *
467  * @param buffer_name
468  * String name of buffer to operate on.
469  *
470  * @param size
471  * Size of requested named buffer.
472  *
473  * @param audio_buffer_port
474  * Out parameter filled in with mach port name for the newly created named
475  * buffer object, must be mach_port_deallocate()d to tear down the access to
476  * the named buffer.
477  *
478  * Audio buffers are distiguished from general named buffers as shared memory
479  * is arbitrated by the EIC.
480  *
481  * @result
482  * KERN_SUCCESS or mach system call error code.
483  */
484 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
485 kern_return_t
486 exclaves_audio_buffer_create(mach_port_t port, const char * buffer_name,
487     mach_vm_size_t size, mach_port_t *audio_buffer_port);
488 
489 /*!
490  * @function exclaves_audio_buffer_copyout
491  *
492  * @abstract
493  * Copy out to specified userspace buffer from previously setup named exclaves
494  * audio shared memory buffer.
495  *
496  * Audio buffers are arbitrated via the EIC and copies will return 0's when
497  * access to the sensor is not granted.
498  *
499  * Two size/offsets are provided to faciliate fast copy that wraps around a
500  * ring buffer that could be placed arbitrarily in the shared memory region.
501  *
502  * @param audio_buffer_port
503  * A named buffer port name returned from exclaves_audio_buffer_create()
504  *
505  * @param dst_buffer
506  * Pointer to userspace buffer to copy out from named buffer.
507  *
508  * @param size1
509  * Number of bytes to copy (<= size of specified userspace buffer).
510  *
511  * @param offset1
512  * Offset in shared memory buffer to start copy at.
513  *
514  * @param size2
515  * Number of bytes to copy (<= size of specified userspace buffer). Can be 0,
516  * in which case the 2nd range is not copied.
517  *
518  * @param offset2
519  * Offset in shared memory buffer to start copy at.
520  *
521  * @result
522  * KERN_SUCCESS or mach system call error code.
523  */
524 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
525 kern_return_t
526 exclaves_audio_buffer_copyout(mach_port_t audio_buffer_port,
527     mach_vm_address_t dst_buffer, mach_vm_size_t size1, mach_vm_size_t offset1,
528     mach_vm_size_t size2, mach_vm_size_t offset2);
529 
530 
531 /*!
532  * @function exclaves_audio_buffer_copyout_with_status
533  *
534  * @abstract
535  * Identical to exclaves_audio_buffer_copyout but also provides a means to get
536  * the sensor status.
537  *
538  * Audio buffers are arbitrated via the EIC and copies will return 0's when
539  * access to the sensor is not granted.
540  *
541  * Two size/offsets are provided to faciliate fast copy that wraps around a
542  * ring buffer that could be placed arbitrarily in the shared memory region.
543  *
544  * @param audio_buffer_port
545  * A named buffer port name returned from exclaves_audio_buffer_create()
546  *
547  * @param dst_buffer
548  * Pointer to userspace buffer to copy out from named buffer.
549  *
550  * @param size1
551  * Number of bytes to copy (<= size of specified userspace buffer).
552  *
553  * @param offset1
554  * Offset in shared memory buffer to start copy at.
555  *
556  * @param size2
557  * Number of bytes to copy (<= size of specified userspace buffer). Can be 0,
558  * in which case the 2nd range is not copied.
559  *
560  * @param offset2
561  * Offset in shared memory buffer to start copy at.
562  *
563  * @param status
564  * Out parameter filled in with the sensor status if the copyout succeeds.
565  *
566  * @result
567  * KERN_SUCCESS or mach system call error code.
568  */
569 SPI_AVAILABLE(macos(15.2), ios(18.2), tvos(18.2), watchos(11.2))
570 kern_return_t
571 exclaves_audio_buffer_copyout_with_status(mach_port_t audio_buffer_port,
572     mach_vm_address_t dst_buffer, mach_vm_size_t size1, mach_vm_size_t offset1,
573     mach_vm_size_t size2, mach_vm_size_t offset2,
574     exclaves_sensor_status_t *status);
575 
576 /*!
577  * @function exclaves_sensor_create
578  *
579  * @abstract
580  * Setup access by xnu to a pre-defined named sensor
581  *
582  * @param port
583  * Reserved, must be MACH_PORT_NULL for now.
584  *
585  * @param sensor_name
586  * String name of sensor to operate on.
587  *
588  * @param sensor_port
589  * Out parameter filled in with mach port name for the newly created
590  * sensor object, must be mach_port_deallocate()d to tear down the access to
591  * the sensor.
592  *
593  * @result
594  * KERN_SUCCESS or mach system call error code.
595  */
596 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
597 kern_return_t
598 exclaves_sensor_create(mach_port_t port, const char *sensor_name, mach_port_t *sensor_port);
599 
600 /*!
601  * @function exclaves_sensor_start
602  *
603  * @abstract
604  * Start accessing a sensor and cause any indicators to display.
605  *
606  * If multiple clients start the same sensor, the sensor will only
607  * actually start on the first client.
608  *
609  * @param sensor_port
610  * A sensor buffer port name returned from exclaves_sensor_create()
611  * for the sensor.
612  *
613  * @param flags to pass to the implementation. Must be 0 for now.
614  *
615  * @param sensor_status
616  * Out parameter filled with the sensor status.
617  *
618  * @result
619  * KERN_SUCCESS or mach system call error code.
620  */
621 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
622 kern_return_t
623 exclaves_sensor_start(mach_port_t sensor_port, uint64_t flags,
624     exclaves_sensor_status_t *sensor_status);
625 
626 /*!
627  * @function exclaves_sensor_stop
628  *
629  * @abstract
630  * Stop accessing a sensor and cause any indicators to stop displaying access.
631  *
632  * If multiple clients are accessing the sensor, sensor access will
633  * continue to display until all clients have called this function.
634  *
635  * @param sensor_port
636  * A sensor buffer port name returned from exclaves_sensor_create()
637  * for the sensor.
638  *
639  * @param flags to pass to the implementation. Must be 0 for now.
640  *
641  * @param sensor_status
642  * Out parameter filled with the sensor status.
643  *
644  * @result
645  * KERN_SUCCESS or mach system call error code.
646  */
647 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
648 kern_return_t
649 exclaves_sensor_stop(mach_port_t sensor_port, uint64_t flags,
650     exclaves_sensor_status_t *sensor_status);
651 
652 /*!
653  * @function exclaves_sensor_status
654  *
655  * @abstract
656  * Get the status of access to a sensor
657  *
658  * @param sensor_port
659  * A sensor buffer port name returned from exclaves_sensor_create()
660  * for the sensor.
661  *
662  * @param flags to pass to the implementation. Must be 0 for now.
663  *
664  * @param sensor_status
665  * Out parameter filled with the sensor status.
666  *
667  * @result
668  * KERN_SUCCESS or mach system call error code.
669  */
670 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
671 kern_return_t
672 exclaves_sensor_status(mach_port_t sensor_port, uint64_t flags,
673     exclaves_sensor_status_t *sensor_status);
674 
675 /*!
676  * @function exclaves_indicator_min_on_time
677  *
678  * @abstract
679  * Get time remaining until minimum on time is satisfied for all sensor types.
680  * The return value for each indicator type is a future clock tick on the Global time base
681  * if the minimum on time is not satisfied, and 0 otherwise.
682  *
683  * @param port Reserved, must be MACH_PORT_NULL for now.
684  * @param flags Reserved, must be 0 for now.
685  * @param camera_indicator Out parameter filled with remaining camera indicator time to meet minimum on time
686  * @param mic_indicator Out parameter filled with remaining microphone indicator time to meet minimum on time
687  * @param faceid Out parameter filled with remaining Face ID indicator time to meet minimum on time
688  *
689  * @result
690  * KERN_SUCCESS or mach system call error code.
691  */
692 
693 SPI_AVAILABLE(macos(15.5), ios(18.5), tvos(18.5), watchos(11.5), visionos(2.5))
694 kern_return_t
695 exclaves_indicator_min_on_time(mach_port_t port, uint64_t flags,
696     uint64_t *camera_indicator, uint64_t *mic_indicator, uint64_t *faceid);
697 
698 /*!
699  * @function exclaves_launch_conclave
700  *
701  * @abstract
702  * Launch conclave.
703  *
704  * @param port
705  * Reserved, must be MACH_PORT_NULL for now.
706  *
707  * @param arg1
708  * Reserved, must be NULL for now.
709  *
710  * @param arg2
711  * Reserved, must be 0 for now.
712  *
713  * @result
714  * KERN_SUCCESS or mach system call error code.
715  */
716 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
717 kern_return_t
718 exclaves_launch_conclave(mach_port_t port, void *arg1,
719     uint64_t arg2);
720 
721 /*!
722  * @function exclaves_lookup_service
723  *
724  * @abstract
725  * Lookup Conclave Resource.
726  *
727  * @param port
728  * Reserved, must be MACH_PORT_NULL for now.
729  *
730  * @param name
731  * Name of exclave resource to lookup
732  *
733  * @param resource_id
734  * Out param for resource id
735  *
736  * @result
737  * KERN_SUCCESS or mach system call error code.
738  */
739 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
740 kern_return_t
741 exclaves_lookup_service(mach_port_t port, const char *name, exclaves_id_t *resource_id);
742 
743 /*!
744  * @function exclaves_notification_create
745  *
746  * @abstract
747  * Finds the exclave notification resource with the specified name and
748  * makes it available for use by the calling task.
749  *
750  * @param port
751  * Reserved, must be MACH_PORT_NULL for now.
752  *
753  * @param name
754  * Notification identifier.
755  *
756  * @param notification_id
757  * Out parameter filled in with the notification ID
758  *
759  * @result
760  * KERN_SUCCESS or mach system call error code.
761  */
762 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
763 kern_return_t
764 exclaves_notification_create(mach_port_t port, const char *name, uint64_t *notification_id);
765 
766 /*!
767  * @function exclaves_aoe_setup
768  *
769  * @abstract
770  * Discover the number of threads this always-on conclave supports.
771  *
772  * @param port
773  * Reserved, must be MACH_PORT_NULL for now.
774  *
775  * @param num_message
776  * Returns the number of message threads
777  *
778  * @param num_worker
779  * Returns the number of worker threads
780  *
781  * @result
782  * KERN_SUCCESS or mach system call error code.
783  */
784 SPI_AVAILABLE(macos(16.0), ios(19.0), tvos(19.0), watchos(12.0), xros(3.0))
785 kern_return_t
786 exclaves_aoe_setup(mach_port_t port, uint8_t *num_message, uint8_t *num_worker);
787 
788 /*!
789  * @function exclaves_aoe_work_loop
790  *
791  * @abstract
792  * Enter the always-on exclaves worker run loop. This function never returns.
793  *
794  * @param port
795  * Reserved, must be MACH_PORT_NULL for now.
796  *
797  * @result
798  * KERN_SUCCESS or mach system call error code.
799  */
800 SPI_AVAILABLE(macos(16.0), ios(19.0), tvos(19.0), watchos(12.0), xros(3.0))
801 kern_return_t
802 exclaves_aoe_work_loop(mach_port_t port);
803 
804 /*!
805  * @function exclaves_aoe_message_loop
806  *
807  * @abstract
808  * Enter the always-on exclaves message loop. This function never returns.
809  *
810  * @param port
811  * Reserved, must be MACH_PORT_NULL for now.
812  *
813  * @result
814  * KERN_SUCCESS or mach system call error code.
815  */
816 SPI_AVAILABLE(macos(16.0), ios(19.0), tvos(19.0), watchos(12.0), xros(3.0))
817 kern_return_t
818 exclaves_aoe_message_loop(mach_port_t port);
819 
820 #else /* defined(KERNEL) */
821 
822 /*!
823  * @function exclaves_endpoint_call
824  *
825  * @abstract
826  * Perform RPC to an exclaves endpoint via per-thread exclaves IPC buffer.
827  *
828  * @param port
829  * Reserved, must be IPC_PORT_NULL for now.
830  *
831  * @param endpoint_id
832  * Identifier of exclaves endpoint to send RPC to.
833  *
834  * @param tag
835  * In-out parameter for exclaves IPC tag.
836  *
837  * @param error
838  * Out parameter for exclaves IPC error.
839  *
840  * @result
841  * KERN_SUCCESS or mach error code.
842  */
843 kern_return_t
844 exclaves_endpoint_call(ipc_port_t port, exclaves_id_t endpoint_id,
845     exclaves_tag_t *tag, exclaves_error_t *error);
846 
847 /*!
848  * @function exclaves_allocate_ipc_buffer
849  *
850  * @abstract
851  * Increment the current thread's IPC buffer usecount. If the usecount was 0
852  * pre-increment, allocate a new per-thread exclaves IPC buffer and
853  * scheduling context.
854  *
855  * @param ipc_buffer
856  * Out parameter filled in with address of IPC buffer. Can be NULL.
857  *
858  * @result
859  * KERN_SUCCESS or mach error code.
860  */
861 kern_return_t
862 exclaves_allocate_ipc_buffer(void **ipc_buffer);
863 
864 /*!
865  * @function exclaves_free_ipc_buffer
866  *
867  * @abstract
868  * Decrement the current thread's IPC buffer usecount. If the usecount is 0
869  * post-decrement, free the per-thread exclaves IPC buffer and scheduling
870  * context. Asserts if the usecount pre-decrement was 0.
871  *
872  * @result
873  * KERN_SUCCESS or mach error code.
874  */
875 kern_return_t
876 exclaves_free_ipc_buffer(void);
877 
878 /*!
879  * @function exclaves_get_ipc_buffer
880  *
881  * @abstract
882  * Return per-thread exclaves IPC buffer. Does not increment the current
883  * thread's IPC buffer use count.
884  *
885  * @result
886  * If allocated, pointer to per-thread exclaves IPC buffer, NULL otherwise.
887  */
888 OS_CONST
889 void*
890 exclaves_get_ipc_buffer(void);
891 
892 /* For use by Tightbeam kernel runtime only */
893 
894 typedef uint64_t exclaves_badge_t;
895 
896 /*!
897  * @typedef exclaves_upcall_handler_t
898  *
899  * @abstract
900  * RPC message handler for upcalls from exclaves via per-thread exclaves IPC
901  * buffer.
902  *
903  * @param context
904  * Opaque context pointer specified at handler registration.
905  *
906  * @param tag
907  * In-out parameter for exclaves IPC tag.
908  *
909  * @param badge
910  * Badge value identifying upcall RPC message.
911  *
912  * @result
913  * KERN_SUCCESS or mach error code.
914  */
915 typedef kern_return_t
916 (*exclaves_upcall_handler_t)(void *context, exclaves_tag_t *tag,
917     exclaves_badge_t badge);
918 
919 /*!
920  * @function exclaves_register_upcall_handler
921  *
922  * @abstract
923  * One-time registration of exclaves upcall RPC handler for specified upcall ID.
924  * Must be called during Exclaves boot sequence, will assert otherwise.
925  *
926  * @param upcall_id
927  * Identifier of upcall to configure.
928  *
929  * @param upcall_context
930  * Opaque context pointer to pass to upcall RPC handler.
931  *
932  * @param upcall_handler
933  * Pointer to upcall RPC handler.
934  *
935  * @result
936  * KERN_SUCCESS or mach error code.
937  */
938 kern_return_t
939 exclaves_register_upcall_handler(exclaves_id_t upcall_id, void *upcall_context,
940     exclaves_upcall_handler_t upcall_handler);
941 
942 struct XrtHosted_Callbacks;
943 
944 /*!
945  * @function xrt_hosted_register_callbacks
946  *
947  * @abstract
948  * Exclaves XRT hosted kext interface.
949  *
950  * @param callbacks
951  * Pointer to callback function table.
952  */
953 void
954 exclaves_register_xrt_hosted_callbacks(struct XrtHosted_Callbacks *callbacks);
955 
956 /*!
957  * @enum exclaves_sensor_type_t
958  *
959  * @brief
960  * Identifier for an exclaves sensor
961  */
962 OS_ENUM(exclaves_sensor_type, uint32_t,
963     EXCLAVES_SENSOR_CAM = 1,
964     EXCLAVES_SENSOR_MIC = 2,
965     EXCLAVES_SENSOR_CAM_ALT_FACEID = 3,
966     EXCLAVES_SENSOR_CAM_ALT_FACEID_DELAYED = 4,
967     EXCLAVES_SENSOR_TEST = 5,
968     EXCLAVES_SENSOR_TEST_MIL = 6,
969     EXCLAVES_SENSOR_TEST_CIL = 7,
970     /* update max if more sensors added */
971     EXCLAVES_SENSOR_MAX = 7,
972     );
973 
974 /*!
975  * @function exclaves_sensor_start
976  *
977  * @abstract
978  * Start accessing a sensor and cause any indicators to display.
979  *
980  * If multiple clients start the same sensor, the sensor will only
981  * actually start on the first client.
982  *
983  * @param sensor_type
984  * type of sensor to operate on.
985  *
986  * @param flags to pass to the implementation. Must be 0 for now.
987  *
988  * @param sensor_status
989  * Out parameter filled with the sensor status.
990  *
991  * @result
992  * KERN_SUCCESS or mach system call error code.
993  */
994 kern_return_t
995 exclaves_sensor_start(exclaves_sensor_type_t sensor_type, uint64_t flags,
996     exclaves_sensor_status_t *sensor_status);
997 
998 /*!
999  * @function exclaves_sensor_stop
1000  *
1001  * @abstract
1002  * Stop accessing a sensor and cause any indicators to stop displaying access.
1003  *
1004  * If multiple clients are accessing the sensor, sensor access will
1005  * continue to display until all clients have called this function.
1006  *
1007  * @param sensor_type
1008  * type of sensor to operate on.
1009  *
1010  * @param flags to pass to the implementation. Must be 0 for now.
1011  *
1012  * @param sensor_status
1013  * Out parameter filled with the sensor status.
1014  *
1015  * @result
1016  * KERN_SUCCESS or mach system call error code.
1017  */
1018 kern_return_t
1019 exclaves_sensor_stop(exclaves_sensor_type_t sensor_type, uint64_t flags,
1020     exclaves_sensor_status_t *sensor_status);
1021 
1022 /*!
1023  * @function exclaves_sensor_status
1024  *
1025  * @abstract
1026  * Get the status of access to a sensor
1027  *
1028  * @param sensor_type
1029  * type of sensor to operate on.
1030  *
1031  * @param sensor_status
1032  * Out parameter filled with the sensor status.
1033  *
1034  * @param flags to pass to the implementation. Must be 0 for now.
1035  *
1036  * @result
1037  * KERN_SUCCESS or mach system call error code.
1038  */
1039 kern_return_t
1040 exclaves_sensor_status(exclaves_sensor_type_t sensor_type, uint64_t flags,
1041     exclaves_sensor_status_t *sensor_status);
1042 
1043 /*!
1044  * @function exclaves_sensor_tick_rate
1045  *
1046  * @abstract
1047  * Set the fire rate of the timer that ticks the EIC periodically.
1048  * This should only be called by the brightness stack to adjust the rate at which
1049  * LED indicators can get new brightness values.
1050  *
1051  * @param rate_hz
1052  * Timer rate in Hz.
1053  *
1054  * @result
1055  * KERN_SUCCESS or mach system call error code.
1056  */
1057 kern_return_t
1058 exclaves_sensor_tick_rate(uint64_t rate_hz);
1059 
1060 /*!
1061  * @function exclaves_display_healthcheck_rate
1062  *
1063  * @abstract
1064  * Deprecated, no longer does anything.
1065  *
1066  * @param ns
1067  * Unused.
1068  *
1069  * @result
1070  * KERN_SUCCESS.
1071  */
1072 /* __kpi_deprecated("Inoperative noop, can remove") */
1073 kern_return_t
1074 exclaves_display_healthcheck_rate(uint64_t ns);
1075 
1076 #endif /* defined(KERNEL) */
1077 
1078 #if defined(MACH_KERNEL_PRIVATE)
1079 
1080 /* -------------------------------------------------------------------------- */
1081 
1082 /* Internal kernel interface */
1083 
1084 /*!
1085  * @function exclaves_indicator_metrics_report
1086  *
1087  * @abstract
1088  * Get ExclaveIndicatorController metrics and report them to CoreAnalytics
1089  */
1090 extern void
1091 exclaves_indicator_metrics_report(void);
1092 
1093 extern kern_return_t
1094 exclaves_thread_terminate(thread_t thread);
1095 
1096 extern bool
1097 exclaves_booted(void);
1098 
1099 extern size_t
1100 exclaves_ipc_buffer_count(void);
1101 
1102 OS_ENUM(exclaves_clock_type, uint8_t,
1103     EXCLAVES_CLOCK_ABSOLUTE = 0,
1104     EXCLAVES_CLOCK_CONTINUOUS = 1,
1105     );
1106 
1107 extern void
1108 exclaves_update_timebase(exclaves_clock_type_t type, uint64_t offset);
1109 
1110 typedef struct {
1111 	void *ipcb;
1112 	unsigned long scid;
1113 	uint64_t usecnt;
1114 } exclaves_ctx_t;
1115 
1116 #endif /* defined(MACH_KERNEL_PRIVATE) */
1117 
1118 /* -------------------------------------------------------------------------- */
1119 
1120 /* Private interface between Libsyscall and xnu */
1121 
1122 OS_ENUM(exclaves_ctl_op, uint8_t,
1123     EXCLAVES_CTL_OP_ENDPOINT_CALL = 1,
1124     EXCLAVES_CTL_OP_NAMED_BUFFER_CREATE = 2,
1125     EXCLAVES_CTL_OP_NAMED_BUFFER_COPYIN = 3,
1126     EXCLAVES_CTL_OP_NAMED_BUFFER_COPYOUT = 4,
1127     EXCLAVES_CTL_OP_BOOT = 5,
1128     EXCLAVES_CTL_OP_LAUNCH_CONCLAVE = 6,
1129     EXCLAVES_CTL_OP_LOOKUP_SERVICES = 7,
1130     EXCLAVES_CTL_OP_AUDIO_BUFFER_CREATE = 8,
1131     EXCLAVES_CTL_OP_AUDIO_BUFFER_COPYOUT = 9,
1132     EXCLAVES_CTL_OP_SENSOR_CREATE = 10,
1133     EXCLAVES_CTL_OP_SENSOR_START = 11,
1134     EXCLAVES_CTL_OP_SENSOR_STOP = 12,
1135     EXCLAVES_CTL_OP_SENSOR_STATUS = 13,
1136     EXCLAVES_CTL_OP_NOTIFICATION_RESOURCE_LOOKUP = 14,
1137     EXCLAVES_CTL_OP_AOE_SETUP = 15,
1138     EXCLAVES_CTL_OP_AOE_MESSAGE_LOOP = 16,
1139     EXCLAVES_CTL_OP_AOE_WORK_LOOP = 17,
1140     EXCLAVES_CTL_OP_SENSOR_MIN_ON_TIME = 18,
1141     EXCLAVES_CTL_OP_LAST,
1142     );
1143 #define EXCLAVES_CTL_FLAGS_MASK (0xfffffful)
1144 #define EXCLAVES_CTL_OP_AND_FLAGS(op, flags) \
1145 	((uint32_t)EXCLAVES_CTL_OP_##op << 24 | \
1146 	((uint32_t)(flags) & EXCLAVES_CTL_FLAGS_MASK))
1147 #define EXCLAVES_CTL_OP(op_and_flags) \
1148 	((uint8_t)((op_and_flags) >> 24))
1149 #define EXCLAVES_CTL_FLAGS(op_and_flags) \
1150 	((uint32_t)(op_and_flags) & EXCLAVES_CTL_FLAGS_MASK)
1151 
1152 /*!
1153  * @struct exclaves_resource_user
1154  *
1155  * @brief
1156  * User representation of exclave resource
1157  */
1158 typedef struct exclaves_resource_user {
1159 	char                  r_name[MAXCONCLAVENAME];
1160 	uint64_t              r_type;
1161 	exclaves_id_t         r_id;
1162 	mach_port_name_t      r_port;
1163 } exclaves_resouce_user_t;
1164 
1165 /*!
1166  * @struct exclaves_indicator_deadline
1167  *
1168  * @brief
1169  * This struct will contain the amount of time remaining before
1170  * minimum on time is met for various sensors
1171  */
1172 typedef struct exclaves_indicator_deadlines {
1173 	uint64_t version;
1174 	uint64_t camera_indicator;
1175 	uint64_t mic_indicator;
1176 	uint64_t faceid_indicator;
1177 } exclaves_indicator_deadlines_t;
1178 
1179 #if !defined(KERNEL)
1180 
1181 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
1182 OS_NOT_TAIL_CALLED
1183 kern_return_t
1184 _exclaves_ctl_trap(mach_port_name_t name, uint32_t operation_and_flags,
1185     exclaves_id_t identifier, mach_vm_address_t buffer, mach_vm_size_t size,
1186     mach_vm_size_t size2, mach_vm_size_t offset, mach_vm_address_t status);
1187 
1188 #endif /* !defined(KERNEL) */
1189 
1190 /* -------------------------------------------------------------------------- */
1191 
1192 /* Sysctl interface */
1193 
1194 #if defined(KERNEL)
1195 
1196 /*!
1197  * @function exclaves_get_status
1198  *
1199  * @abstract
1200  * Return the current running status of exclaves. This function will block until
1201  * exclaves has booted, failed to boot, or are known to be not available.
1202  *
1203  * @result
1204  * The status of exclaves.
1205  */
1206 exclaves_status_t
1207 exclaves_get_status(void);
1208 
1209 #endif /* defined(KERNEL) */
1210 
1211 #if defined(XNU_KERNEL_PRIVATE)
1212 
1213 /*!
1214  * @function exclaves_get_boot_stage
1215  *
1216  * @abstract
1217  * Return the current boot stage of exclaves. This function will not block.
1218  * In general this shouldn't be used (other than for the sysctl).
1219  * exclaves_boot_wait() is mostly what is wanted.
1220  *
1221  * @result
1222  * The boot stage of exclaves.
1223  */
1224 exclaves_boot_stage_t
1225 exclaves_get_boot_stage(void);
1226 
1227 /*!
1228  * @function exclaves_boot_supported
1229  *
1230  * @abstract
1231  * Determine if exclaves are supported. This is a basic check essentially equal
1232  * to checking whether the current kernel was compiled with CONFIG_EXCLAVES and
1233  * whether or not SPTM has disabled cL4.
1234  *
1235  * @result
1236  * True if supported, false otherwise.
1237  */
1238 bool
1239 exclaves_boot_supported(void);
1240 
1241 /*!
1242  * @function exclaves_boot_wait
1243  *
1244  * @abstract
1245  * Wait until the specified boot stage has been reached.
1246  *
1247  * @result
1248  * KERN_SUCCESS when the boot stage has been reached, KERN_NOT_SUPPORTED if
1249  * exclaves are not supported.
1250  */
1251 /* BEGIN IGNORE CODESTYLE */
1252 kern_return_t
1253 exclaves_boot_wait(exclaves_boot_stage_t);
1254 /* END IGNORE CODESTYLE */
1255 
1256 /*
1257  * Identifies exclaves privilege checks.
1258  */
1259 __options_closed_decl(exclaves_priv_t, unsigned int, {
1260 	EXCLAVES_PRIV_CONCLAVE_HOST  = 0x1,  /* Can host conclaves. */
1261 	EXCLAVES_PRIV_CONCLAVE_SPAWN = 0x2,  /* Can spawn conclaves. */
1262 	EXCLAVES_PRIV_KERNEL_DOMAIN  = 0x4,  /* Access to kernel resources. */
1263 	EXCLAVES_PRIV_BOOT           = 0x8,  /* Can boot exclaves. */
1264 	EXCLAVES_PRIV_INDICATOR_MIN_ON_TIME = 0x10 /* Can access sensor minimum on time*/
1265 });
1266 
1267 /*
1268  * Check to see if the specified task has a privilege.
1269  */
1270 extern bool
1271 exclaves_has_priv(task_t task, exclaves_priv_t priv);
1272 
1273 /*
1274  * Check to see if the specified vnode has a privilege.
1275  * Vnode argument is untyped as it's not available to osfmk.
1276  */
1277 extern bool
1278 exclaves_has_priv_vnode(void *vnode, int64_t off, exclaves_priv_t priv);
1279 
1280 /* Return index of last xnu frame before secure world. Valid frame index is
1281  * always in range <0, nframes-1>. When frame is not found, return nframes
1282  * value. */
1283 uint32_t exclaves_stack_offset(const uintptr_t *out_addr, size_t nframes,
1284     bool slid_addresses);
1285 
1286 /* Check whether Exclave inspection got initialized */
1287 extern bool exclaves_inspection_is_initialized(void);
1288 
1289 /* Send a watchdog panic request to the exclaves scheduler */
1290 extern kern_return_t exclaves_scheduler_request_watchdog_panic(void);
1291 
1292 #endif /* defined(XNU_KERNEL_PRIVATE) */
1293 
1294 __END_DECLS
1295 
1296 #endif /* defined(PRIVATE) */
1297 
1298 #endif /* _MACH_EXCLAVES_H */
1299