xref: /xnu-11215.81.4/osfmk/arm64/platform_tests_asm.s (revision d4514f0bc1d3f944c22d92e68b646ac3fb40d452)
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	/* If we made it here, the test passed. Fix the system up. */
168	mrs		x0, SP_EL0
169	ldr		x1, [x0], #16
170	/* Restore the real SP1 */
171	mov		sp, x1
172	/* Update SP0 to prepare to return */
173	msr		SPSel, #0
174	mov		sp, x0
175	/* Return 1 to indicate success */
176	mov		x0, #1
177	LOAD_CALLEE_REGISTERS
178	ARM64_STACK_EPILOG
179
180/**
181 * arm64_panic_lockdown_test_sp1_exception_in_vector
182 * This test simulates an exception in the SP1 critical region
183 */
184	.globl EXT(arm64_panic_lockdown_test_sp1_exception_in_vector)
185LEXT(arm64_panic_lockdown_test_sp1_exception_in_vector)
186	ARM64_STACK_PROLOG
187	SAVE_CALLEE_REGISTERS
188	/* Trigger an exception inside the vector on SP1 */
189	msr		SPSel, #1
190	b		EXT(el1_sp1_synchronous_raise_exception_in_vector)
191
192	.globl EXT(arm64_panic_lockdown_test_sp1_exception_in_vector_handler)
193LEXT(arm64_panic_lockdown_test_sp1_exception_in_vector_handler)
194	/* Return to SP0 */
195	msr		SPSel, #0
196	/* Return 1 to indicate success */
197	mov		x0, #1
198	LOAD_CALLEE_REGISTERS
199	ARM64_STACK_EPILOG
200
201#endif /* CONFIG_SPTM */
202
203#if BTI_ENFORCED
204	.text
205	.align 2
206	.global EXT(arm64_bti_test_jump_shim)
207LEXT(arm64_bti_test_jump_shim)
208	ARM64_PROLOG
209#if __has_feature(ptrauth_calls)
210	braaz	x0
211#else
212	br		x0
213#endif /* __has_feature(ptrauth_calls) */
214
215	.global EXT(arm64_bti_test_call_shim)
216LEXT(arm64_bti_test_call_shim)
217	ARM64_STACK_PROLOG
218	PUSH_FRAME
219#if __has_feature(ptrauth_calls)
220	blraaz	x0
221#else
222	blr		x0
223#endif /* __has_feature(ptrauth_calls) */
224	POP_FRAME
225	ARM64_STACK_EPILOG
226
227	.globl EXT(arm64_bti_test_func_with_no_landing_pad)
228LEXT(arm64_bti_test_func_with_no_landing_pad)
229	mov		x0, #1
230	ret
231
232	.globl EXT(arm64_bti_test_func_with_call_landing_pad)
233LEXT(arm64_bti_test_func_with_call_landing_pad)
234	bti		c
235	mov		x0, #2
236	ret
237
238	.globl EXT(arm64_bti_test_func_with_jump_landing_pad)
239LEXT(arm64_bti_test_func_with_jump_landing_pad)
240	bti		j
241	mov		x0, #3
242	ret
243
244	.globl EXT(arm64_bti_test_func_with_jump_call_landing_pad)
245LEXT(arm64_bti_test_func_with_jump_call_landing_pad)
246	bti		jc
247	mov		x0, #4
248	ret
249
250#if __has_feature(ptrauth_returns)
251	.globl EXT(arm64_bti_test_func_with_pac_landing_pad)
252LEXT(arm64_bti_test_func_with_pac_landing_pad)
253	pacibsp
254	mov		x0, #5
255	retab
256#endif /* __has_feature(ptrauth_returns) */
257#endif /* BTI_ENFORCED */
258