xref: /aosp_15_r20/trusty/kernel/app/btitest/btitest_arm64.S (revision 344aa361028b423587d4ef3fa52a23d194628137)
1*344aa361SAndroid Build Coastguard Worker/*
2*344aa361SAndroid Build Coastguard Worker * Copyright (c) 2022, Google Inc. All rights reserved
3*344aa361SAndroid Build Coastguard Worker *
4*344aa361SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining
5*344aa361SAndroid Build Coastguard Worker * a copy of this software and associated documentation files
6*344aa361SAndroid Build Coastguard Worker * (the "Software"), to deal in the Software without restriction,
7*344aa361SAndroid Build Coastguard Worker * including without limitation the rights to use, copy, modify, merge,
8*344aa361SAndroid Build Coastguard Worker * publish, distribute, sublicense, and/or sell copies of the Software,
9*344aa361SAndroid Build Coastguard Worker * and to permit persons to whom the Software is furnished to do so,
10*344aa361SAndroid Build Coastguard Worker * subject to the following conditions:
11*344aa361SAndroid Build Coastguard Worker *
12*344aa361SAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be
13*344aa361SAndroid Build Coastguard Worker * included in all copies or substantial portions of the Software.
14*344aa361SAndroid Build Coastguard Worker *
15*344aa361SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16*344aa361SAndroid Build Coastguard Worker * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17*344aa361SAndroid Build Coastguard Worker * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18*344aa361SAndroid Build Coastguard Worker * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19*344aa361SAndroid Build Coastguard Worker * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20*344aa361SAndroid Build Coastguard Worker * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21*344aa361SAndroid Build Coastguard Worker * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22*344aa361SAndroid Build Coastguard Worker */
23*344aa361SAndroid Build Coastguard Worker
24*344aa361SAndroid Build Coastguard Worker#include <asm.h>
25*344aa361SAndroid Build Coastguard Worker#include <arch/asm_macros.h>
26*344aa361SAndroid Build Coastguard Worker#include <err.h>
27*344aa361SAndroid Build Coastguard Worker#include "btitest.h"
28*344aa361SAndroid Build Coastguard Worker
29*344aa361SAndroid Build Coastguard Worker.section .text
30*344aa361SAndroid Build Coastguard Worker
31*344aa361SAndroid Build Coastguard Worker/* Fault handler to return where BTI calls fail.
32*344aa361SAndroid Build Coastguard Worker * On return from the caught Branch Target exception, PSTATE.BTYPE will still
33*344aa361SAndroid Build Coastguard Worker * be set according to the last branch taken.  Therefore we need to land on a
34*344aa361SAndroid Build Coastguard Worker * BTI jc to be compatible with all callers - and avoid another immediate
35*344aa361SAndroid Build Coastguard Worker * Branch Target exception.
36*344aa361SAndroid Build Coastguard Worker */
37*344aa361SAndroid Build Coastguard Worker.Lbtitest_callee_fault:
38*344aa361SAndroid Build Coastguard Worker    bti jc
39*344aa361SAndroid Build Coastguard Worker    mov x0, #ERR_FAULT
40*344aa361SAndroid Build Coastguard Worker    ret
41*344aa361SAndroid Build Coastguard Worker
42*344aa361SAndroid Build Coastguard Worker/**
43*344aa361SAndroid Build Coastguard Worker * int btitest_bl(void) - Use bl to call each of the test functions
44*344aa361SAndroid Build Coastguard Worker *
45*344aa361SAndroid Build Coastguard Worker * This calls each of the test functions using bl and a relative offset,
46*344aa361SAndroid Build Coastguard Worker * which should always be allowed.  The functions are expected to all return 0.
47*344aa361SAndroid Build Coastguard Worker *
48*344aa361SAndroid Build Coastguard Worker * Returns The first non-zero return code, or 0 if all functions pass.
49*344aa361SAndroid Build Coastguard Worker */
50*344aa361SAndroid Build Coastguard WorkerFUNCTION(btitest_bl)
51*344aa361SAndroid Build Coastguard Worker    push lr, xzr
52*344aa361SAndroid Build Coastguard Worker    bl btitest_callee_nop
53*344aa361SAndroid Build Coastguard Worker    cbnz x0, .Lerror
54*344aa361SAndroid Build Coastguard Worker    bl btitest_callee_bti
55*344aa361SAndroid Build Coastguard Worker    cbnz x0, .Lerror
56*344aa361SAndroid Build Coastguard Worker    bl btitest_callee_bti_c
57*344aa361SAndroid Build Coastguard Worker    cbnz x0, .Lerror
58*344aa361SAndroid Build Coastguard Worker    bl btitest_callee_bti_j
59*344aa361SAndroid Build Coastguard Worker    cbnz x0, .Lerror
60*344aa361SAndroid Build Coastguard Worker    bl btitest_callee_bti_jc
61*344aa361SAndroid Build Coastguard Worker    cbnz x0, .Lerror
62*344aa361SAndroid Build Coastguard Worker    bl btitest_callee_paciasp
63*344aa361SAndroid Build Coastguard Worker    cbnz x0, .Lerror
64*344aa361SAndroid Build Coastguard Worker    bl btitest_callee_pacibsp
65*344aa361SAndroid Build Coastguard Worker.Lerror:
66*344aa361SAndroid Build Coastguard Worker    pop lr, xzr
67*344aa361SAndroid Build Coastguard Worker    ret
68*344aa361SAndroid Build Coastguard Worker
69*344aa361SAndroid Build Coastguard Worker/**
70*344aa361SAndroid Build Coastguard Worker * int btitest_blr(int) - Use blr to call the passed function
71*344aa361SAndroid Build Coastguard Worker *
72*344aa361SAndroid Build Coastguard Worker * Returns The called function's return value
73*344aa361SAndroid Build Coastguard Worker */
74*344aa361SAndroid Build Coastguard WorkerFUNCTION(btitest_blr)
75*344aa361SAndroid Build Coastguard Worker    push lr, xzr
76*344aa361SAndroid Build Coastguard Worker    bl get_callee
77*344aa361SAndroid Build Coastguard Worker    blr x0
78*344aa361SAndroid Build Coastguard Worker    pop lr, xzr
79*344aa361SAndroid Build Coastguard Worker    ret
80*344aa361SAndroid Build Coastguard Worker
81*344aa361SAndroid Build Coastguard Worker/**
82*344aa361SAndroid Build Coastguard Worker * int btitest_br(int) - Use br to call the passed function via the x0 register
83*344aa361SAndroid Build Coastguard Worker *
84*344aa361SAndroid Build Coastguard Worker * Returns The called function's return value
85*344aa361SAndroid Build Coastguard Worker */
86*344aa361SAndroid Build Coastguard WorkerFUNCTION(btitest_br)
87*344aa361SAndroid Build Coastguard Worker    push lr, xzr
88*344aa361SAndroid Build Coastguard Worker    bl get_callee
89*344aa361SAndroid Build Coastguard Worker    pop lr, xzr
90*344aa361SAndroid Build Coastguard Worker    br x0
91*344aa361SAndroid Build Coastguard Worker
92*344aa361SAndroid Build Coastguard Worker/**
93*344aa361SAndroid Build Coastguard Worker * int btitest_br_x16(int) - Use br to call the passed function via the x16
94*344aa361SAndroid Build Coastguard Worker *                           register
95*344aa361SAndroid Build Coastguard Worker *
96*344aa361SAndroid Build Coastguard Worker * Returns The called function's return value
97*344aa361SAndroid Build Coastguard Worker */
98*344aa361SAndroid Build Coastguard WorkerFUNCTION(btitest_br_x16)
99*344aa361SAndroid Build Coastguard Worker    push lr, xzr
100*344aa361SAndroid Build Coastguard Worker    bl get_callee
101*344aa361SAndroid Build Coastguard Worker    pop lr, xzr
102*344aa361SAndroid Build Coastguard Worker    mov x16, x0
103*344aa361SAndroid Build Coastguard Worker    br x16
104*344aa361SAndroid Build Coastguard Worker
105*344aa361SAndroid Build Coastguard Worker/**
106*344aa361SAndroid Build Coastguard Worker * int btitest_br_x17(int) - Use br to call the passed function via the x17
107*344aa361SAndroid Build Coastguard Worker *                           register
108*344aa361SAndroid Build Coastguard Worker *
109*344aa361SAndroid Build Coastguard Worker * Returns The called function's return value
110*344aa361SAndroid Build Coastguard Worker */
111*344aa361SAndroid Build Coastguard WorkerFUNCTION(btitest_br_x17)
112*344aa361SAndroid Build Coastguard Worker    push lr, xzr
113*344aa361SAndroid Build Coastguard Worker    bl get_callee
114*344aa361SAndroid Build Coastguard Worker    pop lr, xzr
115*344aa361SAndroid Build Coastguard Worker    mov x17, x0
116*344aa361SAndroid Build Coastguard Worker    br x17
117*344aa361SAndroid Build Coastguard Worker
118*344aa361SAndroid Build Coastguard Worker/**
119*344aa361SAndroid Build Coastguard Worker * int btitest_callee_nop(void) - Function with nop instruction
120*344aa361SAndroid Build Coastguard Worker *
121*344aa361SAndroid Build Coastguard Worker * Returns ERR_FAULT if the BTI check fails.
122*344aa361SAndroid Build Coastguard Worker * Return 0 if the BTI check passes.
123*344aa361SAndroid Build Coastguard Worker */
124*344aa361SAndroid Build Coastguard WorkerLOCAL_FUNCTION(btitest_callee_nop)
125*344aa361SAndroid Build Coastguard Worker    set_fault_handler .Lbtitest_callee_fault
126*344aa361SAndroid Build Coastguard Worker    nop
127*344aa361SAndroid Build Coastguard Worker    mov	x0, #0
128*344aa361SAndroid Build Coastguard Worker    ret
129*344aa361SAndroid Build Coastguard Worker
130*344aa361SAndroid Build Coastguard Worker/**
131*344aa361SAndroid Build Coastguard Worker * int btitest_callee_bti(void) - Function with bti instruction
132*344aa361SAndroid Build Coastguard Worker *
133*344aa361SAndroid Build Coastguard Worker * Returns ERR_FAULT if the BTI check fails.
134*344aa361SAndroid Build Coastguard Worker * Return 0 if the BTI check passes.
135*344aa361SAndroid Build Coastguard Worker */
136*344aa361SAndroid Build Coastguard WorkerLOCAL_FUNCTION(btitest_callee_bti)
137*344aa361SAndroid Build Coastguard Worker    set_fault_handler .Lbtitest_callee_fault
138*344aa361SAndroid Build Coastguard Worker    bti
139*344aa361SAndroid Build Coastguard Worker    mov	x0, #0
140*344aa361SAndroid Build Coastguard Worker    ret
141*344aa361SAndroid Build Coastguard Worker
142*344aa361SAndroid Build Coastguard Worker/**
143*344aa361SAndroid Build Coastguard Worker * int btitest_callee_bti_c(void) - Function with bti c instruction
144*344aa361SAndroid Build Coastguard Worker *
145*344aa361SAndroid Build Coastguard Worker * Returns ERR_FAULT if the BTI check fails.
146*344aa361SAndroid Build Coastguard Worker * Return 0 if the BTI check passes.
147*344aa361SAndroid Build Coastguard Worker */
148*344aa361SAndroid Build Coastguard WorkerLOCAL_FUNCTION(btitest_callee_bti_c)
149*344aa361SAndroid Build Coastguard Worker    set_fault_handler .Lbtitest_callee_fault
150*344aa361SAndroid Build Coastguard Worker    bti c
151*344aa361SAndroid Build Coastguard Worker    mov	x0, #0
152*344aa361SAndroid Build Coastguard Worker    ret
153*344aa361SAndroid Build Coastguard Worker
154*344aa361SAndroid Build Coastguard Worker/**
155*344aa361SAndroid Build Coastguard Worker * int btitest_callee_bti_j(void) - Function with bti j instruction
156*344aa361SAndroid Build Coastguard Worker *
157*344aa361SAndroid Build Coastguard Worker * Returns ERR_FAULT if the BTI check fails.
158*344aa361SAndroid Build Coastguard Worker * Return 0 if the BTI check passes.
159*344aa361SAndroid Build Coastguard Worker */
160*344aa361SAndroid Build Coastguard WorkerLOCAL_FUNCTION(btitest_callee_bti_j)
161*344aa361SAndroid Build Coastguard Worker    set_fault_handler .Lbtitest_callee_fault
162*344aa361SAndroid Build Coastguard Worker    bti j
163*344aa361SAndroid Build Coastguard Worker    mov	x0, #0
164*344aa361SAndroid Build Coastguard Worker    ret
165*344aa361SAndroid Build Coastguard Worker
166*344aa361SAndroid Build Coastguard Worker/**
167*344aa361SAndroid Build Coastguard Worker * int btitest_callee_bti_jc(void) - Function with bti jc instruction
168*344aa361SAndroid Build Coastguard Worker *
169*344aa361SAndroid Build Coastguard Worker * Returns ERR_FAULT if the BTI check fails.
170*344aa361SAndroid Build Coastguard Worker * Return 0 if the BTI check passes.
171*344aa361SAndroid Build Coastguard Worker */
172*344aa361SAndroid Build Coastguard WorkerLOCAL_FUNCTION(btitest_callee_bti_jc)
173*344aa361SAndroid Build Coastguard Worker    set_fault_handler .Lbtitest_callee_fault
174*344aa361SAndroid Build Coastguard Worker    bti jc
175*344aa361SAndroid Build Coastguard Worker    mov	x0, #0
176*344aa361SAndroid Build Coastguard Worker    ret
177*344aa361SAndroid Build Coastguard Worker
178*344aa361SAndroid Build Coastguard Worker/**
179*344aa361SAndroid Build Coastguard Worker * int btitest_callee_paciasp(void) - Function with paciasp instruction
180*344aa361SAndroid Build Coastguard Worker *
181*344aa361SAndroid Build Coastguard Worker * Returns ERR_FAULT if the BTI check fails.
182*344aa361SAndroid Build Coastguard Worker * Return 0 if the BTI check passes.
183*344aa361SAndroid Build Coastguard Worker */
184*344aa361SAndroid Build Coastguard WorkerLOCAL_FUNCTION(btitest_callee_paciasp)
185*344aa361SAndroid Build Coastguard Worker    set_fault_handler .Lbtitest_callee_fault
186*344aa361SAndroid Build Coastguard Worker    paciasp
187*344aa361SAndroid Build Coastguard Worker    mov	x0, #0
188*344aa361SAndroid Build Coastguard Worker    autiasp
189*344aa361SAndroid Build Coastguard Worker    ret
190*344aa361SAndroid Build Coastguard Worker
191*344aa361SAndroid Build Coastguard Worker/**
192*344aa361SAndroid Build Coastguard Worker * int btitest_callee_pacibsp(void) - Function with pacibsp instruction
193*344aa361SAndroid Build Coastguard Worker *
194*344aa361SAndroid Build Coastguard Worker * Returns ERR_FAULT if the BTI check fails.
195*344aa361SAndroid Build Coastguard Worker * Return 0 if the BTI check passes.
196*344aa361SAndroid Build Coastguard Worker */
197*344aa361SAndroid Build Coastguard WorkerLOCAL_FUNCTION(btitest_callee_pacibsp)
198*344aa361SAndroid Build Coastguard Worker    set_fault_handler .Lbtitest_callee_fault
199*344aa361SAndroid Build Coastguard Worker    pacibsp
200*344aa361SAndroid Build Coastguard Worker    mov	x0, #0
201*344aa361SAndroid Build Coastguard Worker    autibsp
202*344aa361SAndroid Build Coastguard Worker    ret
203*344aa361SAndroid Build Coastguard Worker
204*344aa361SAndroid Build Coastguard Worker/**
205*344aa361SAndroid Build Coastguard Worker * int btitest_callee_error(void) - Error function which always fails
206*344aa361SAndroid Build Coastguard Worker *
207*344aa361SAndroid Build Coastguard Worker * This is valid as any jump target.
208*344aa361SAndroid Build Coastguard Worker *
209*344aa361SAndroid Build Coastguard Worker * Returns ERR_INVALID_ARGS unconditionally.
210*344aa361SAndroid Build Coastguard Worker */
211*344aa361SAndroid Build Coastguard WorkerLOCAL_FUNCTION(btitest_callee_error)
212*344aa361SAndroid Build Coastguard Worker    bti jc
213*344aa361SAndroid Build Coastguard Worker    mov	x0, #ERR_INVALID_ARGS
214*344aa361SAndroid Build Coastguard Worker    ret
215*344aa361SAndroid Build Coastguard Worker
216*344aa361SAndroid Build Coastguard Worker/**
217*344aa361SAndroid Build Coastguard Worker * get_callee(int) - Get the address of the callee function.
218*344aa361SAndroid Build Coastguard Worker *
219*344aa361SAndroid Build Coastguard Worker * Converts the passed function index into the function address.
220*344aa361SAndroid Build Coastguard Worker * This is done here to avoid using the C compiler to get function addresses -
221*344aa361SAndroid Build Coastguard Worker * the compiler may insert veneers or indirection under some situations (e.g.
222*344aa361SAndroid Build Coastguard Worker * for CFI) and break the specific landing pad instructions needed to test BTI.
223*344aa361SAndroid Build Coastguard Worker *
224*344aa361SAndroid Build Coastguard Worker * Return 0 if the index is not recognised, otherwise the function address.
225*344aa361SAndroid Build Coastguard Worker */
226*344aa361SAndroid Build Coastguard WorkerLOCAL_FUNCTION(get_callee)
227*344aa361SAndroid Build Coastguard Worker    cmp w0, #BTITEST_CALLEE_NOP
228*344aa361SAndroid Build Coastguard Worker    bne .Ltry_bti
229*344aa361SAndroid Build Coastguard Worker    adr x0, btitest_callee_nop
230*344aa361SAndroid Build Coastguard Worker    ret
231*344aa361SAndroid Build Coastguard Worker.Ltry_bti:
232*344aa361SAndroid Build Coastguard Worker    cmp w0, #BTITEST_CALLEE_BTI
233*344aa361SAndroid Build Coastguard Worker    bne .Ltry_bti_c
234*344aa361SAndroid Build Coastguard Worker    adr x0, btitest_callee_bti
235*344aa361SAndroid Build Coastguard Worker    ret
236*344aa361SAndroid Build Coastguard Worker.Ltry_bti_c:
237*344aa361SAndroid Build Coastguard Worker    cmp w0, #BTITEST_CALLEE_BTI_C
238*344aa361SAndroid Build Coastguard Worker    bne .Ltry_bti_j
239*344aa361SAndroid Build Coastguard Worker    adr x0, btitest_callee_bti_c
240*344aa361SAndroid Build Coastguard Worker    ret
241*344aa361SAndroid Build Coastguard Worker.Ltry_bti_j:
242*344aa361SAndroid Build Coastguard Worker    cmp w0, #BTITEST_CALLEE_BTI_J
243*344aa361SAndroid Build Coastguard Worker    bne .Ltry_bti_jc
244*344aa361SAndroid Build Coastguard Worker    adr x0, btitest_callee_bti_j
245*344aa361SAndroid Build Coastguard Worker    ret
246*344aa361SAndroid Build Coastguard Worker.Ltry_bti_jc:
247*344aa361SAndroid Build Coastguard Worker    cmp w0, #BTITEST_CALLEE_BTI_JC
248*344aa361SAndroid Build Coastguard Worker    bne .Ltry_paciasp
249*344aa361SAndroid Build Coastguard Worker    adr x0, btitest_callee_bti_jc
250*344aa361SAndroid Build Coastguard Worker    ret
251*344aa361SAndroid Build Coastguard Worker.Ltry_paciasp:
252*344aa361SAndroid Build Coastguard Worker    cmp w0, #BTITEST_CALLEE_PACIASP
253*344aa361SAndroid Build Coastguard Worker    bne .Ltry_pacibsp
254*344aa361SAndroid Build Coastguard Worker    adr x0, btitest_callee_paciasp
255*344aa361SAndroid Build Coastguard Worker    ret
256*344aa361SAndroid Build Coastguard Worker.Ltry_pacibsp:
257*344aa361SAndroid Build Coastguard Worker    cmp w0, #BTITEST_CALLEE_PACIBSP
258*344aa361SAndroid Build Coastguard Worker    bne .Lunknown
259*344aa361SAndroid Build Coastguard Worker    adr x0, btitest_callee_pacibsp
260*344aa361SAndroid Build Coastguard Worker    ret
261*344aa361SAndroid Build Coastguard Worker.Lunknown:
262*344aa361SAndroid Build Coastguard Worker    /* Return error function which unconditionally fails any test */
263*344aa361SAndroid Build Coastguard Worker    adr x0, btitest_callee_error
264*344aa361SAndroid Build Coastguard Worker    ret
265