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