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 37 __BEGIN_DECLS 38 39 typedef uint64_t exclaves_id_t; 40 typedef uint64_t exclaves_tag_t; 41 typedef uint64_t exclaves_error_t; 42 43 #if !defined(KERNEL) 44 45 /*! 46 * @function exclaves_endpoint_call 47 * 48 * @abstract 49 * Perform RPC to an exclaves endpoint. 50 * 51 * @param port 52 * Reserved, must be MACH_PORT_NULL for now. 53 * 54 * @param endpoint_id 55 * Identifier of exclaves endpoint to send RPC to. 56 * 57 * @param msg_buffer 58 * Pointer to exclaves IPC buffer. 59 * 60 * @param size 61 * Size of specified exclaves IPC buffer. 62 * 63 * @param tag 64 * In-out parameter for exclaves IPC tag. 65 * 66 * @param error 67 * Out parameter for exclaves IPC error. 68 * 69 * @result 70 * KERN_SUCCESS or mach system call error code. 71 */ 72 kern_return_t 73 exclaves_endpoint_call(mach_port_t port, exclaves_id_t endpoint_id, 74 mach_vm_address_t msg_buffer, mach_vm_size_t size, exclaves_tag_t *tag, 75 exclaves_error_t *error); 76 77 /*! 78 * @function exclaves_named_buffer_create 79 * 80 * @abstract 81 * Setup access by xnu to a pre-defined named exclaves shared memory buffer 82 * and return a mach port for it. 83 * 84 * @param port 85 * Reserved, must be MACH_PORT_NULL for now. 86 * 87 * @param buffer_id 88 * Identifier of named buffer to operate on. 89 * 90 * @param size 91 * Size of requested named buffer. 92 * 93 * @param named_buffer_port 94 * Out parameter filled in with mach port name for the newly created named 95 * buffer object, must be mach_port_deallocate()d to tear down the access to 96 * the named buffer. 97 * 98 * @result 99 * KERN_SUCCESS or mach system call error code. 100 */ 101 kern_return_t 102 exclaves_named_buffer_create(mach_port_t port, exclaves_id_t buffer_id, 103 mach_vm_size_t size, mach_port_t* named_buffer_port); 104 105 /*! 106 * @function exclaves_named_buffer_copyin 107 * 108 * @abstract 109 * Copy from specified userspace buffer into previously setup named exclaves 110 * shared memory buffer. 111 * 112 * @param named_buffer_port 113 * A named buffer port name returned from exclaves_named_buffer_create() 114 * 115 * @param src_buffer 116 * Pointer to userspace buffer to copy into named buffer. 117 * 118 * @param size 119 * Number of bytes to copy (<= size of specified userspace buffer). 120 * 121 * @param offset 122 * Offset in shared memory buffer to start copy at. 123 * 124 * @result 125 * KERN_SUCCESS or mach system call error code. 126 */ 127 kern_return_t 128 exclaves_named_buffer_copyin(mach_port_t named_buffer_port, 129 mach_vm_address_t src_buffer, mach_vm_size_t size, mach_vm_size_t offset); 130 131 /*! 132 * @function exclaves_named_buffer_copyout 133 * 134 * @abstract 135 * Copy out to specified userspace buffer from previously setup named exclaves 136 * shared memory buffer. 137 * 138 * @param named_buffer_port 139 * A named buffer port name returned from exclaves_named_buffer_create() 140 * 141 * @param dst_buffer 142 * Pointer to userspace buffer to copy out from named buffer. 143 * 144 * @param size 145 * Number of bytes to copy (<= size of specified userspace buffer). 146 * 147 * @param offset 148 * Offset in shared memory buffer to start copy at. 149 * 150 * @result 151 * KERN_SUCCESS or mach system call error code. 152 */ 153 kern_return_t 154 exclaves_named_buffer_copyout(mach_port_t named_buffer_port, 155 mach_vm_address_t dst_buffer, mach_vm_size_t size, mach_vm_size_t offset); 156 157 /*! 158 * @function exclaves_boot 159 * 160 * @abstract 161 * Perform exclaves boot. 162 * 163 * @param port 164 * Reserved, must be MACH_PORT_NULL for now. 165 * 166 * @param flags 167 * Reserved, must be 0 for now. 168 * 169 * @result 170 * KERN_SUCCESS or mach system call error code. 171 */ 172 kern_return_t 173 exclaves_boot(mach_port_t port, uint64_t flags); 174 175 #else /* defined(KERNEL) */ 176 177 /*! 178 * @function exclaves_endpoint_call 179 * 180 * @abstract 181 * Perform RPC to an exclaves endpoint via per-thread exclaves IPC buffer. 182 * 183 * @param port 184 * Reserved, must be IPC_PORT_NULL for now. 185 * 186 * @param endpoint_id 187 * Identifier of exclaves endpoint to send RPC to. 188 * 189 * @param tag 190 * In-out parameter for exclaves IPC tag. 191 * 192 * @param error 193 * Out parameter for exclaves IPC error. 194 * 195 * @result 196 * KERN_SUCCESS or mach error code. 197 */ 198 kern_return_t 199 exclaves_endpoint_call(ipc_port_t port, exclaves_id_t endpoint_id, 200 exclaves_tag_t *tag, exclaves_error_t *error); 201 202 /*! 203 * @function exclaves_allocate_ipc_buffer 204 * 205 * @abstract 206 * If necessary, allocate per-thread exclaves IPC buffer. 207 * 208 * @param ipc_buffer 209 * Out parameter filled in with address of IPC buffer. Can be NULL. 210 * 211 * @result 212 * KERN_SUCCESS or mach error code. 213 */ 214 kern_return_t 215 exclaves_allocate_ipc_buffer(void **ipc_buffer); 216 217 /*! 218 * @function exclaves_free_ipc_buffer 219 * 220 * @abstract 221 * If necessary, free per-thread exclaves IPC buffer. 222 * 223 * @result 224 * KERN_SUCCESS or mach error code. 225 */ 226 kern_return_t 227 exclaves_free_ipc_buffer(void); 228 229 /*! 230 * @function exclaves_get_ipc_buffer 231 * 232 * @abstract 233 * Return per-thread exclaves IPC buffer. 234 * 235 * @result 236 * If allocated, pointer to per-thread exclaves IPC buffer, NULL otherwise. 237 */ 238 OS_CONST 239 void* 240 exclaves_get_ipc_buffer(void); 241 242 /* For use by Tightbeam kernel runtime only */ 243 244 typedef uint64_t exclaves_badge_t; 245 246 /*! 247 * @typedef exclaves_upcall_handler_t 248 * 249 * @abstract 250 * RPC message handler for upcalls from exclaves via per-thread exclaves IPC 251 * buffer. 252 * 253 * @param context 254 * Opaque context pointer specified at handler registration. 255 * 256 * @param tag 257 * In-out parameter for exclaves IPC tag. 258 * 259 * @param badge 260 * Badge value identifying upcall RPC message. 261 * 262 * @result 263 * KERN_SUCCESS or mach error code. 264 */ 265 typedef kern_return_t 266 (*exclaves_upcall_handler_t)(void *context, exclaves_tag_t *tag, 267 exclaves_badge_t badge); 268 269 /*! 270 * @function exclaves_register_upcall_handler 271 * 272 * @abstract 273 * One-time registration of exclaves upcall RPC handler for specified upcall ID. 274 * Must be called during Exclaves boot sequence, will assert otherwise. 275 * 276 * @param upcall_id 277 * Identifier of upcall to configure. 278 * 279 * @param upcall_context 280 * Opaque context pointer to pass to upcall RPC handler. 281 * 282 * @param upcall_handler 283 * Pointer to upcall RPC handler. 284 * 285 * @result 286 * KERN_SUCCESS or mach error code. 287 */ 288 kern_return_t 289 exclaves_register_upcall_handler(exclaves_id_t upcall_id, void *upcall_context, 290 exclaves_upcall_handler_t upcall_handler); 291 292 struct XrtHosted_Callbacks; 293 294 /*! 295 * @function xrt_hosted_register_callbacks 296 * 297 * @abstract 298 * Exclaves XRT hosted kext interface. 299 * 300 * @param callbacks 301 * Pointer to callback function table. 302 */ 303 void 304 exclaves_register_xrt_hosted_callbacks(struct XrtHosted_Callbacks *callbacks); 305 306 #endif /* defined(KERNEL) */ 307 308 #if defined(MACH_KERNEL_PRIVATE) 309 310 /* -------------------------------------------------------------------------- */ 311 312 /* Internal kernel interface */ 313 314 kern_return_t 315 exclaves_thread_terminate(thread_t thread); 316 317 kern_return_t 318 exclaves_boot(ipc_port_t port, uint64_t flags); 319 320 #endif /* defined(MACH_KERNEL_PRIVATE) */ 321 322 /* -------------------------------------------------------------------------- */ 323 324 /* Private interface between Libsyscall and xnu */ 325 326 OS_ENUM(exclaves_ctl_op, uint8_t, 327 EXCLAVES_CTL_OP_ENDPOINT_CALL = 1, 328 EXCLAVES_CTL_OP_NAMED_BUFFER_CREATE = 2, 329 EXCLAVES_CTL_OP_NAMED_BUFFER_COPYIN = 3, 330 EXCLAVES_CTL_OP_NAMED_BUFFER_COPYOUT = 4, 331 EXCLAVES_CTL_OP_BOOT = 5, 332 EXCLAVES_CTL_OP_LAST, 333 ); 334 #define EXCLAVES_CTL_FLAGS_MASK (0xfffffful) 335 #define EXCLAVES_CTL_OP_AND_FLAGS(op, flags) \ 336 ((uint32_t)EXCLAVES_CTL_OP_##op << 24 | \ 337 ((uint32_t)(flags) & EXCLAVES_CTL_FLAGS_MASK)) 338 #define EXCLAVES_CTL_OP(op_and_flags) \ 339 ((uint8_t)((op_and_flags) >> 24)) 340 #define EXCLAVES_CTL_FLAGS(op_and_flags) \ 341 ((uint32_t)(op_and_flags) & EXCLAVES_CTL_FLAGS_MASK) 342 343 #if !defined(KERNEL) 344 345 OS_NOT_TAIL_CALLED 346 kern_return_t 347 _exclaves_ctl_trap(mach_port_name_t name, uint32_t operation_and_flags, 348 exclaves_id_t identifier, mach_vm_address_t buffer, mach_vm_size_t size); 349 350 #endif /* !defined(KERNEL) */ 351 352 /* -------------------------------------------------------------------------- */ 353 354 /* Sysctl interface */ 355 356 OS_ENUM(exclaves_status, uint8_t, 357 EXCLAVES_STATUS_NOT_STARTED = 0x00, 358 EXCLAVES_STATUS_AVAILABLE = 0x01, 359 EXCLAVES_STATUS_FAILED = 0xFE, 360 EXCLAVES_STATUS_NOT_SUPPORTED = 0xFF, 361 ); 362 363 #if defined(KERNEL) 364 365 /*! 366 * @function exclaves_get_status 367 * 368 * @abstract 369 * Return the current running status of exclaves. 370 * 371 * @result 372 * The status of exclaves. 373 */ 374 exclaves_status_t 375 exclaves_get_status(void); 376 377 #endif /* defined(KERNEL) */ 378 379 __END_DECLS 380 381 #endif /* defined(PRIVATE) */ 382 383 #endif /* _MACH_EXCLAVES_H */ 384