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 #include <mach/exclaves.h>
30 #include <mach/mach_traps.h>
31 #include <kern/misc_protos.h>
32 #include <kern/assert.h>
33 #include <kern/startup.h>
34
35
36 /* -------------------------------------------------------------------------- */
37 #pragma mark userspace entry point
38
39 kern_return_t
_exclaves_ctl_trap(struct exclaves_ctl_trap_args * uap)40 _exclaves_ctl_trap(struct exclaves_ctl_trap_args *uap)
41 {
42 #pragma unused(uap)
43 return KERN_NOT_SUPPORTED;
44 }
45
46 /* -------------------------------------------------------------------------- */
47 #pragma mark kernel entry points
48
49 kern_return_t
exclaves_endpoint_call(ipc_port_t port,exclaves_id_t endpoint_id,exclaves_tag_t * tag,exclaves_error_t * error)50 exclaves_endpoint_call(ipc_port_t port, exclaves_id_t endpoint_id,
51 exclaves_tag_t *tag, exclaves_error_t *error)
52 {
53 #pragma unused(port, endpoint_id, tag, error)
54 return KERN_NOT_SUPPORTED;
55 }
56
57 kern_return_t
exclaves_allocate_ipc_buffer(void ** out_ipc_buffer)58 exclaves_allocate_ipc_buffer(void **out_ipc_buffer)
59 {
60 #pragma unused(out_ipc_buffer)
61 return KERN_NOT_SUPPORTED;
62 }
63
64
65 kern_return_t
exclaves_free_ipc_buffer(void)66 exclaves_free_ipc_buffer(void)
67 {
68 return KERN_NOT_SUPPORTED;
69 }
70
71 kern_return_t
exclaves_thread_terminate(__unused thread_t thread)72 exclaves_thread_terminate(__unused thread_t thread)
73 {
74 kern_return_t kr = KERN_SUCCESS;
75
76 #pragma unused(thread)
77
78 return kr;
79 }
80
81 OS_CONST
82 void*
exclaves_get_ipc_buffer(void)83 exclaves_get_ipc_buffer(void)
84 {
85 return NULL;
86 }
87
88 kern_return_t
exclaves_register_upcall_handler(exclaves_id_t upcall_id,void * upcall_context,exclaves_upcall_handler_t upcall_handler)89 exclaves_register_upcall_handler(exclaves_id_t upcall_id, void *upcall_context,
90 exclaves_upcall_handler_t upcall_handler)
91 {
92 #pragma unused(upcall_id, upcall_context, upcall_handler)
93 return KERN_NOT_SUPPORTED;
94 }
95
96
97 kern_return_t
exclaves_boot(__unused ipc_port_t port,uint64_t flags)98 exclaves_boot(__unused ipc_port_t port, uint64_t flags)
99 {
100 assert(flags == 0);
101 #pragma unused(flags)
102 #pragma unused(port)
103 return KERN_NOT_SUPPORTED;
104 }
105
106 exclaves_status_t
exclaves_get_status(void)107 exclaves_get_status(void)
108 {
109 return EXCLAVES_STATUS_NOT_SUPPORTED;
110 }
111
112
113 void
exclaves_register_xrt_hosted_callbacks(struct XrtHosted_Callbacks * callbacks)114 exclaves_register_xrt_hosted_callbacks(struct XrtHosted_Callbacks *callbacks)
115 {
116 #pragma unused(callbacks)
117 }
118
119 /* -------------------------------------------------------------------------- */
120
121 #pragma mark exclaves ipc internals
122
123
124 /* -------------------------------------------------------------------------- */
125
126 #pragma mark tests
127
128
129 #if EXCLAVES_XNU_LOOPBACK_TESTING
130
131 static int
exclaves_loopback_ipc_test(__unused int64_t in,int64_t * out)132 exclaves_loopback_ipc_test(__unused int64_t in, int64_t *out)
133 {
134 printf("%s: SKIPPED\n", __func__);
135 *out = -1;
136
137 return 0;
138 }
139 SYSCTL_TEST_REGISTER(exclaves_loopback_ipc_test, exclaves_loopback_ipc_test);
140
141 static int
exclaves_loopback_tightbeam_test(__unused int64_t in,int64_t * out)142 exclaves_loopback_tightbeam_test(__unused int64_t in, int64_t *out)
143 {
144 #pragma unused(in, out)
145 printf("%s: SKIPPED\n", __func__);
146 *out = -1;
147 return 0;
148 }
149 SYSCTL_TEST_REGISTER(exclaves_loopback_tightbeam_test,
150 exclaves_loopback_tightbeam_test);
151 #endif /* EXCLAVES_XNU_LOOPBACK_TESTING */
152
153 /* Disable test code in release kernel, SYSCTL_TEST_REGISTER is not available */
154 #if DEVELOPMENT || DEBUG
155
156 #define EXCLAVES_ID_HELLO_EXCLAVE_EP \
157 ((exclaves_id_t)EXCLAVES_XNUPROXY_EXCLAVE_HELLOEXCLAVE)
158
159 static int
exclaves_hello_exclave_test(__unused int64_t in,int64_t * out)160 exclaves_hello_exclave_test(__unused int64_t in, int64_t *out)
161 {
162 printf("%s: SKIPPED\n", __func__);
163 *out = -1;
164
165 return 0;
166 }
167 SYSCTL_TEST_REGISTER(exclaves_hello_exclave_test, exclaves_hello_exclave_test);
168
169 #if EXCLAVES_XNU_UPCALL_TESTING
170 static int
exclaves_hello_upcall_test(__unused int64_t in,int64_t * out)171 exclaves_hello_upcall_test(__unused int64_t in, int64_t *out)
172 {
173 printf("%s: SKIPPED\n", __func__);
174 *out = -1;
175
176 return 0;
177 }
178 SYSCTL_TEST_REGISTER(exclaves_hello_upcall_test, exclaves_hello_upcall_test);
179 #endif /* EXCLAVES_XNU_UPCALL_TESTING */
180
181
182
183 #define EXCLAVES_ID_SWIFT_HELLO_EXCLAVE_EP \
184 ((exclaves_id_t)EXCLAVES_XNUPROXY_EXCLAVE_HELLOTIGHTBEAM)
185
186 static int
exclaves_hello_tightbeam(bool upcall,int64_t * out)187 exclaves_hello_tightbeam(bool upcall, int64_t *out)
188 {
189 #pragma unused(upcall, out)
190 printf("%s: SKIPPED\n", __func__);
191 *out = -1;
192 return 0;
193 }
194
195 #define EXCLAVES_HELLO_DRIVER_INTERRUPTS_INDEX 0
196 #define EXCLAVES_HELLO_DRIVER_INTERRUPTS_CHECK_RET(test) if (test) { break; }
197
198 static int
exclaves_hello_driver_interrupts(uint64_t registryID,int64_t * out)199 exclaves_hello_driver_interrupts(uint64_t registryID, int64_t *out)
200 {
201 #pragma unused(registryID)
202 printf("%s: SKIPPED\n", __func__);
203 *out = -1;
204 return 0;
205 }
206
207 static int
exclaves_hello_drivers_test(int64_t in __unused,int64_t * out)208 exclaves_hello_drivers_test(int64_t in __unused, int64_t *out)
209 {
210 printf("%s: SKIPPED\n", __func__);
211 *out = -1;
212 return 0;
213 }
214 SYSCTL_TEST_REGISTER(exclaves_hello_drivers_test,
215 exclaves_hello_drivers_test);
216
217 static int
exclaves_hello_tightbeam_test(__unused int64_t in,int64_t * out)218 exclaves_hello_tightbeam_test(__unused int64_t in, int64_t *out)
219 {
220 return exclaves_hello_tightbeam(false, out);
221 }
222 SYSCTL_TEST_REGISTER(exclaves_hello_tightbeam_test,
223 exclaves_hello_tightbeam_test);
224
225 #if EXCLAVES_XNU_TIGHTBEAM_UPCALL_TESTING
226 static int
exclaves_hello_tightbeam_upcall_test(__unused int64_t in,int64_t * out)227 exclaves_hello_tightbeam_upcall_test(__unused int64_t in, int64_t *out)
228 {
229 return exclaves_hello_tightbeam(true, out);
230 }
231 SYSCTL_TEST_REGISTER(exclaves_hello_tightbeam_upcall_test,
232 exclaves_hello_tightbeam_upcall_test);
233 #endif /* EXCLAVES_XNU_TIGHTBEAM_UPCALL_TESTING */
234
235 static int
exclaves_hello_driver_interrupts_test(int64_t in,int64_t * out)236 exclaves_hello_driver_interrupts_test(int64_t in, int64_t *out)
237 {
238 // in should be AppleExclaveExampleKext's registry ID
239 return exclaves_hello_driver_interrupts((uint64_t)in, out);
240 }
241 SYSCTL_TEST_REGISTER(exclaves_hello_driver_interrupts_test,
242 exclaves_hello_driver_interrupts_test);
243
244
245
246 static TUNABLE(bool, enable_hello_conclaves, "enable_hello_conclaves", false);
247
248 static int
exclaves_hello_conclaves_test(int64_t in,int64_t * out)249 exclaves_hello_conclaves_test(int64_t in, int64_t *out)
250 {
251 #pragma unused(in)
252 printf("%s: SKIPPED\n", __func__);
253 *out = -1;
254 return KERN_SUCCESS;
255 }
256 SYSCTL_TEST_REGISTER(exclaves_hello_conclaves_test,
257 exclaves_hello_conclaves_test);
258
259
260
261 #endif /* DEVELOPMENT || DEBUG */
262