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