xref: /xnu-11417.121.6/osfmk/arm64/platform_tests_asm.s (revision a1e26a70f38d1d7daa7b49b258e2f8538ad81650)
1/*
2 * Copyright (c) 2018 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 <arm64/asm.h>
30#include <pexpert/arm64/board_config.h>
31
32
33#if CONFIG_SPTM
34	.text
35	.align 2
36	.globl EXT(arm64_panic_lockdown_test_load)
37LEXT(arm64_panic_lockdown_test_load)
38	ARM64_PROLOG
39	ldr		x0, [x0]
40	ret
41
42	.globl EXT(arm64_panic_lockdown_test_gdbtrap)
43LEXT(arm64_panic_lockdown_test_gdbtrap)
44	ARM64_PROLOG
45	.long 0xe7ffdefe
46	ret
47
48#if __has_feature(ptrauth_calls)
49	.globl EXT(arm64_panic_lockdown_test_pac_brk_c470)
50LEXT(arm64_panic_lockdown_test_pac_brk_c470)
51	ARM64_PROLOG
52	brk		0xC470
53	ret
54
55	.globl EXT(arm64_panic_lockdown_test_pac_brk_c471)
56LEXT(arm64_panic_lockdown_test_pac_brk_c471)
57	ARM64_PROLOG
58	brk		0xC471
59	ret
60
61	.globl EXT(arm64_panic_lockdown_test_pac_brk_c472)
62LEXT(arm64_panic_lockdown_test_pac_brk_c472)
63	ARM64_PROLOG
64	brk		0xC472
65	ret
66
67	.globl EXT(arm64_panic_lockdown_test_pac_brk_c473)
68LEXT(arm64_panic_lockdown_test_pac_brk_c473)
69	ARM64_PROLOG
70	brk		0xC473
71	ret
72
73	.globl EXT(arm64_panic_lockdown_test_telemetry_brk_ff00)
74LEXT(arm64_panic_lockdown_test_telemetry_brk_ff00)
75	ARM64_PROLOG
76	brk		0xFF00
77	ret
78
79	.globl EXT(arm64_panic_lockdown_test_br_auth_fail)
80LEXT(arm64_panic_lockdown_test_br_auth_fail)
81	ARM64_PROLOG
82	braaz	x0
83	ret
84
85	.globl EXT(arm64_panic_lockdown_test_ldr_auth_fail)
86LEXT(arm64_panic_lockdown_test_ldr_auth_fail)
87	ARM64_PROLOG
88	ldraa	x0, [x0]
89	ret
90#endif /* ptrauth_calls  */
91
92#if __ARM_ARCH_8_6__
93	.globl EXT(arm64_panic_lockdown_test_fpac)
94LEXT(arm64_panic_lockdown_test_fpac)
95	ARM64_PROLOG
96	autiza	x0
97	ret
98#endif /* __ARM_ARCH_8_6__ */
99
100#if BTI_ENFORCED && CONFIG_BTI_TELEMETRY
101	.globl EXT(arm64_panic_lockdown_test_bti_telemetry)
102LEXT(arm64_panic_lockdown_test_bti_telemetry)
103	ARM64_PROLOG
104	/*
105	 * Trigger a BTI exception on the first instruction *after* the landing pad.
106	 */
1070:
108	nop
109	adr		x0, 0b
110	br		x0
111#endif /* BTI_ENFORCED && CONFIG_BTI_TELEMETRY */
112
113/*
114 * SP1 Panic Lockdown Tests
115 *
116 * These tests are somewhat complex because we're round tripping through an
117 * exception vector which is not intended to return. This means we'll lose a
118 * fair amount of state. The only thing we can really rely on being preserved is
119 * SP_EL0 as we stay on SP1 for the entire vector. As such, we need to save all
120 * callee saved registers here.
121 */
122
123.macro SAVE_CALLEE_REGISTERS
124	stp		x19, x20, [sp, #-(16 * 10)]!
125	stp		x21, x22, [sp, #0x10]
126	stp		x23, x24, [sp, #0x20]
127	stp		x25, x26, [sp, #0x30]
128	stp		x27, x28, [sp, #0x40]
129	stp		x29, x30, [sp, #0x50]
130	stp		q4, q5, [sp, #0x60]
131	stp		q6, q7, [sp, #0x80]
132.endmacro
133
134.macro LOAD_CALLEE_REGISTERS
135	ldp		x21, x22, [sp, #0x10]
136	ldp		x23, x24, [sp, #0x20]
137	ldp		x25, x26, [sp, #0x30]
138	ldp		x27, x28, [sp, #0x40]
139	ldp		x29, x30, [sp, #0x50]
140	ldp		q4, q5, [sp, #0x60]
141	ldp		q6, q7, [sp, #0x80]
142	ldp		x19, x20, [sp], #(16*10)
143.endmacro
144
145/**
146 * arm64_panic_lockdown_test_sp1_invalid_stack
147 *
148 * This test simulates a stack overflow/corruption
149 */
150	.globl EXT(arm64_panic_lockdown_test_sp1_invalid_stack)
151LEXT(arm64_panic_lockdown_test_sp1_invalid_stack)
152	ARM64_STACK_PROLOG
153	SAVE_CALLEE_REGISTERS
154	/* Spill the real SP1 to the stack and trash the old one */
155	msr		SPSel, #1
156	mov		x0, sp
157	mov		x1, #0
158	mov		sp, x1
159	msr		SPSel, #0
160	str		x0, [sp, #-16]!
161	/* Take an exception on SP1 but outside the critical region */
162	msr		SPSel, #1
163	b		EXT(arm64_panic_lockdown_test_pac_brk_c470)
164
165	.global EXT(arm64_panic_lockdown_test_sp1_invalid_stack_handler)
166LEXT(arm64_panic_lockdown_test_sp1_invalid_stack_handler)
167	ARM64_PROLOG
168	/* If we made it here, the test passed. Fix the system up. */
169	mrs		x0, SP_EL0
170	ldr		x1, [x0], #16
171	/* Restore the real SP1 */
172	mov		sp, x1
173	/* Update SP0 to prepare to return */
174	msr		SPSel, #0
175	mov		sp, x0
176	/* Return 1 to indicate success */
177	mov		x0, #1
178	LOAD_CALLEE_REGISTERS
179	ARM64_STACK_EPILOG
180
181/**
182 * arm64_panic_lockdown_test_sp1_exception_in_vector
183 * This test simulates an exception in the SP1 critical region
184 */
185	.globl EXT(arm64_panic_lockdown_test_sp1_exception_in_vector)
186LEXT(arm64_panic_lockdown_test_sp1_exception_in_vector)
187	ARM64_STACK_PROLOG
188	SAVE_CALLEE_REGISTERS
189	/* Trigger an exception inside the vector on SP1 */
190	msr		SPSel, #1
191	b		EXT(el1_sp1_synchronous_raise_exception_in_vector)
192
193	.globl EXT(arm64_panic_lockdown_test_sp1_exception_in_vector_handler)
194LEXT(arm64_panic_lockdown_test_sp1_exception_in_vector_handler)
195	ARM64_PROLOG
196	/* Return to SP0 */
197	msr		SPSel, #0
198	/* Return 1 to indicate success */
199	mov		x0, #1
200	LOAD_CALLEE_REGISTERS
201	ARM64_STACK_EPILOG
202
203#endif /* CONFIG_SPTM */
204
205#if BTI_ENFORCED
206	.text
207	.align 2
208	.global EXT(arm64_bti_test_jump_shim)
209LEXT(arm64_bti_test_jump_shim)
210	ARM64_PROLOG
211#if __has_feature(ptrauth_calls)
212	braaz	x0
213#else
214	br		x0
215#endif /* __has_feature(ptrauth_calls) */
216
217	.global EXT(arm64_bti_test_call_shim)
218LEXT(arm64_bti_test_call_shim)
219	ARM64_STACK_PROLOG
220	PUSH_FRAME
221#if __has_feature(ptrauth_calls)
222	blraaz	x0
223#else
224	blr		x0
225#endif /* __has_feature(ptrauth_calls) */
226	POP_FRAME
227	ARM64_STACK_EPILOG
228
229	.globl EXT(arm64_bti_test_func_with_no_landing_pad)
230LEXT(arm64_bti_test_func_with_no_landing_pad)
231	mov		x0, #1
232	ret
233
234	.globl EXT(arm64_bti_test_func_with_call_landing_pad)
235LEXT(arm64_bti_test_func_with_call_landing_pad)
236	bti		c
237	mov		x0, #2
238	ret
239
240	.globl EXT(arm64_bti_test_func_with_jump_landing_pad)
241LEXT(arm64_bti_test_func_with_jump_landing_pad)
242	bti		j
243	mov		x0, #3
244	ret
245
246	.globl EXT(arm64_bti_test_func_with_jump_call_landing_pad)
247LEXT(arm64_bti_test_func_with_jump_call_landing_pad)
248	bti		jc
249	mov		x0, #4
250	ret
251
252#if __has_feature(ptrauth_returns)
253	.globl EXT(arm64_bti_test_func_with_pac_landing_pad)
254LEXT(arm64_bti_test_func_with_pac_landing_pad)
255	pacibsp
256	mov		x0, #5
257	retab
258#endif /* __has_feature(ptrauth_returns) */
259#endif /* BTI_ENFORCED */
260