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