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