xref: /aosp_15_r20/trusty/kernel/app/pacbench/pacbench.c (revision 344aa361028b423587d4ef3fa52a23d194628137)
1*344aa361SAndroid Build Coastguard Worker /*
2*344aa361SAndroid Build Coastguard Worker  * Copyright (C) 2022 The Android Open Source Project
3*344aa361SAndroid Build Coastguard Worker  *
4*344aa361SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*344aa361SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*344aa361SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*344aa361SAndroid Build Coastguard Worker  *
8*344aa361SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*344aa361SAndroid Build Coastguard Worker  *
10*344aa361SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*344aa361SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*344aa361SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*344aa361SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*344aa361SAndroid Build Coastguard Worker  * limitations under the License.
15*344aa361SAndroid Build Coastguard Worker  */
16*344aa361SAndroid Build Coastguard Worker 
17*344aa361SAndroid Build Coastguard Worker #define TLOG_TAG "pacbench"
18*344aa361SAndroid Build Coastguard Worker 
19*344aa361SAndroid Build Coastguard Worker #include <arch/ops.h>
20*344aa361SAndroid Build Coastguard Worker #include <inttypes.h>
21*344aa361SAndroid Build Coastguard Worker #include <stdint.h>
22*344aa361SAndroid Build Coastguard Worker #include <trusty_benchmark.h>
23*344aa361SAndroid Build Coastguard Worker #include <uapi/err.h>
24*344aa361SAndroid Build Coastguard Worker 
25*344aa361SAndroid Build Coastguard Worker /* Runs over which to collect statistics */
26*344aa361SAndroid Build Coastguard Worker #define RUNS 100u
27*344aa361SAndroid Build Coastguard Worker 
28*344aa361SAndroid Build Coastguard Worker /* Benchmark run duration */
29*344aa361SAndroid Build Coastguard Worker #define LOOPS 1000000u
30*344aa361SAndroid Build Coastguard Worker #define INSTRUCTIONS_PER_LOOP 16u
31*344aa361SAndroid Build Coastguard Worker 
32*344aa361SAndroid Build Coastguard Worker /* Extended loop count for faster functions */
33*344aa361SAndroid Build Coastguard Worker #define EXTRA_LOOPS 10000000u
34*344aa361SAndroid Build Coastguard Worker 
35*344aa361SAndroid Build Coastguard Worker #define PACKBENCH_STR_REP2(s) s s
36*344aa361SAndroid Build Coastguard Worker #define PACKBENCH_STR_REP4(s) PACKBENCH_STR_REP2(s) PACKBENCH_STR_REP2(s)
37*344aa361SAndroid Build Coastguard Worker #define PACKBENCH_STR_REP8(s) PACKBENCH_STR_REP4(s) PACKBENCH_STR_REP4(s)
38*344aa361SAndroid Build Coastguard Worker #define PACKBENCH_STR_REP16(s) PACKBENCH_STR_REP8(s) PACKBENCH_STR_REP8(s)
39*344aa361SAndroid Build Coastguard Worker 
BENCH_SETUP(pac)40*344aa361SAndroid Build Coastguard Worker BENCH_SETUP(pac) {
41*344aa361SAndroid Build Coastguard Worker     return NO_ERROR;
42*344aa361SAndroid Build Coastguard Worker }
43*344aa361SAndroid Build Coastguard Worker 
BENCH_TEARDOWN(pac)44*344aa361SAndroid Build Coastguard Worker BENCH_TEARDOWN(pac) {}
45*344aa361SAndroid Build Coastguard Worker 
46*344aa361SAndroid Build Coastguard Worker #ifdef KERNEL_PAC_ENABLED
47*344aa361SAndroid Build Coastguard Worker /*
48*344aa361SAndroid Build Coastguard Worker  * Test PACIA instruction.
49*344aa361SAndroid Build Coastguard Worker  * If PAC is supported and enabled in the kernel, this key should be valid and
50*344aa361SAndroid Build Coastguard Worker  * the instruction functional, though this benchmark does not test the
51*344aa361SAndroid Build Coastguard Worker  * instruction - see pactest instead.
52*344aa361SAndroid Build Coastguard Worker  */
BENCH_ALL_CPU(pac,pacia,RUNS)53*344aa361SAndroid Build Coastguard Worker BENCH_ALL_CPU(pac, pacia, RUNS) {
54*344aa361SAndroid Build Coastguard Worker     uint64_t val = 0;
55*344aa361SAndroid Build Coastguard Worker 
56*344aa361SAndroid Build Coastguard Worker     for (uint64_t i = 0; i < LOOPS; i++) {
57*344aa361SAndroid Build Coastguard Worker         __asm__ volatile(".arch_extension pauth\n\t" PACKBENCH_STR_REP16(
58*344aa361SAndroid Build Coastguard Worker                                  "PACIA %0, %1\n\t")
59*344aa361SAndroid Build Coastguard Worker                          : "+r"(val)
60*344aa361SAndroid Build Coastguard Worker                          : "r"(i));
61*344aa361SAndroid Build Coastguard Worker     }
62*344aa361SAndroid Build Coastguard Worker 
63*344aa361SAndroid Build Coastguard Worker     return NO_ERROR;
64*344aa361SAndroid Build Coastguard Worker }
65*344aa361SAndroid Build Coastguard Worker 
BENCH_RESULT(pac,pacia,ps_per_pacia)66*344aa361SAndroid Build Coastguard Worker BENCH_RESULT(pac, pacia, ps_per_pacia) {
67*344aa361SAndroid Build Coastguard Worker     return (bench_get_duration_ns() * 1000u) / (LOOPS * INSTRUCTIONS_PER_LOOP);
68*344aa361SAndroid Build Coastguard Worker }
69*344aa361SAndroid Build Coastguard Worker 
BENCH_RESULT(pac,pacia,us_total)70*344aa361SAndroid Build Coastguard Worker BENCH_RESULT(pac, pacia, us_total) {
71*344aa361SAndroid Build Coastguard Worker     return bench_get_duration_ns() / 1000u;
72*344aa361SAndroid Build Coastguard Worker }
73*344aa361SAndroid Build Coastguard Worker 
BENCH_RESULT(pac,pacia,instructions)74*344aa361SAndroid Build Coastguard Worker BENCH_RESULT(pac, pacia, instructions) {
75*344aa361SAndroid Build Coastguard Worker     return LOOPS * INSTRUCTIONS_PER_LOOP;
76*344aa361SAndroid Build Coastguard Worker }
77*344aa361SAndroid Build Coastguard Worker 
78*344aa361SAndroid Build Coastguard Worker /*
79*344aa361SAndroid Build Coastguard Worker  * Test PACIA & AUTIA instruction.
80*344aa361SAndroid Build Coastguard Worker  * If PAC is supported and enabled in the kernel, this key should be valid and
81*344aa361SAndroid Build Coastguard Worker  * the instruction functional.
82*344aa361SAndroid Build Coastguard Worker  * Note we cannot test AUTIA alone since it may generate an exception if it
83*344aa361SAndroid Build Coastguard Worker  * fails.
84*344aa361SAndroid Build Coastguard Worker  */
BENCH_ALL_CPU(pac,pacautia,RUNS)85*344aa361SAndroid Build Coastguard Worker BENCH_ALL_CPU(pac, pacautia, RUNS) {
86*344aa361SAndroid Build Coastguard Worker     uint64_t val = 0;
87*344aa361SAndroid Build Coastguard Worker 
88*344aa361SAndroid Build Coastguard Worker     for (uint64_t i = 0; i < LOOPS; i++) {
89*344aa361SAndroid Build Coastguard Worker         __asm__ volatile(".arch_extension pauth\n\t" PACKBENCH_STR_REP16(
90*344aa361SAndroid Build Coastguard Worker                                  "PACIA %0, %1\n\tAUTIA %0, %1\n\t")
91*344aa361SAndroid Build Coastguard Worker                          : "+r"(val)
92*344aa361SAndroid Build Coastguard Worker                          : "r"(i));
93*344aa361SAndroid Build Coastguard Worker     }
94*344aa361SAndroid Build Coastguard Worker 
95*344aa361SAndroid Build Coastguard Worker     return NO_ERROR;
96*344aa361SAndroid Build Coastguard Worker }
97*344aa361SAndroid Build Coastguard Worker 
BENCH_RESULT(pac,pacautia,ps_per_pacautia)98*344aa361SAndroid Build Coastguard Worker BENCH_RESULT(pac, pacautia, ps_per_pacautia) {
99*344aa361SAndroid Build Coastguard Worker     return (bench_get_duration_ns() * 1000u) / (LOOPS * INSTRUCTIONS_PER_LOOP);
100*344aa361SAndroid Build Coastguard Worker }
101*344aa361SAndroid Build Coastguard Worker 
BENCH_RESULT(pac,pacautia,us_total)102*344aa361SAndroid Build Coastguard Worker BENCH_RESULT(pac, pacautia, us_total) {
103*344aa361SAndroid Build Coastguard Worker     return bench_get_duration_ns() / 1000u;
104*344aa361SAndroid Build Coastguard Worker }
105*344aa361SAndroid Build Coastguard Worker 
BENCH_RESULT(pac,pacautia,instructions)106*344aa361SAndroid Build Coastguard Worker BENCH_RESULT(pac, pacautia, instructions) {
107*344aa361SAndroid Build Coastguard Worker     return LOOPS * INSTRUCTIONS_PER_LOOP;
108*344aa361SAndroid Build Coastguard Worker }
109*344aa361SAndroid Build Coastguard Worker 
110*344aa361SAndroid Build Coastguard Worker /*
111*344aa361SAndroid Build Coastguard Worker  * Test PACIB instruction.
112*344aa361SAndroid Build Coastguard Worker  * If PAC is supported and enabled in the kernel, this key should be valid and
113*344aa361SAndroid Build Coastguard Worker  * the instruction functional, though this benchmark does not test the
114*344aa361SAndroid Build Coastguard Worker  * instruction - see pactest instead.
115*344aa361SAndroid Build Coastguard Worker  */
BENCH_ALL_CPU(pac,pacib,RUNS)116*344aa361SAndroid Build Coastguard Worker BENCH_ALL_CPU(pac, pacib, RUNS) {
117*344aa361SAndroid Build Coastguard Worker     uint64_t val = 0;
118*344aa361SAndroid Build Coastguard Worker 
119*344aa361SAndroid Build Coastguard Worker     for (uint64_t i = 0; i < LOOPS; i++) {
120*344aa361SAndroid Build Coastguard Worker         __asm__ volatile(".arch_extension pauth\n\t" PACKBENCH_STR_REP16(
121*344aa361SAndroid Build Coastguard Worker                                  "PACIB %0, %1\n\t")
122*344aa361SAndroid Build Coastguard Worker                          : "+r"(val)
123*344aa361SAndroid Build Coastguard Worker                          : "r"(i));
124*344aa361SAndroid Build Coastguard Worker     }
125*344aa361SAndroid Build Coastguard Worker 
126*344aa361SAndroid Build Coastguard Worker     return NO_ERROR;
127*344aa361SAndroid Build Coastguard Worker }
128*344aa361SAndroid Build Coastguard Worker 
BENCH_RESULT(pac,pacib,ps_per_pacib)129*344aa361SAndroid Build Coastguard Worker BENCH_RESULT(pac, pacib, ps_per_pacib) {
130*344aa361SAndroid Build Coastguard Worker     return (bench_get_duration_ns() * 1000u) / (LOOPS * INSTRUCTIONS_PER_LOOP);
131*344aa361SAndroid Build Coastguard Worker }
132*344aa361SAndroid Build Coastguard Worker 
BENCH_RESULT(pac,pacib,us_total)133*344aa361SAndroid Build Coastguard Worker BENCH_RESULT(pac, pacib, us_total) {
134*344aa361SAndroid Build Coastguard Worker     return bench_get_duration_ns() / 1000u;
135*344aa361SAndroid Build Coastguard Worker }
136*344aa361SAndroid Build Coastguard Worker 
BENCH_RESULT(pac,pacib,instructions)137*344aa361SAndroid Build Coastguard Worker BENCH_RESULT(pac, pacib, instructions) {
138*344aa361SAndroid Build Coastguard Worker     return LOOPS * INSTRUCTIONS_PER_LOOP;
139*344aa361SAndroid Build Coastguard Worker }
140*344aa361SAndroid Build Coastguard Worker 
141*344aa361SAndroid Build Coastguard Worker /*
142*344aa361SAndroid Build Coastguard Worker  * Test PACIAB & AUTIB instruction.
143*344aa361SAndroid Build Coastguard Worker  * Even if PAC is supported by the hardware, Trusty doesn't use or enable this
144*344aa361SAndroid Build Coastguard Worker  * key.
145*344aa361SAndroid Build Coastguard Worker  */
BENCH_ALL_CPU(pac,pacautib,RUNS)146*344aa361SAndroid Build Coastguard Worker BENCH_ALL_CPU(pac, pacautib, RUNS) {
147*344aa361SAndroid Build Coastguard Worker     uint64_t val = 0;
148*344aa361SAndroid Build Coastguard Worker 
149*344aa361SAndroid Build Coastguard Worker     for (uint64_t i = 0; i < LOOPS; i++) {
150*344aa361SAndroid Build Coastguard Worker         __asm__ volatile(".arch_extension pauth\n\t" PACKBENCH_STR_REP16(
151*344aa361SAndroid Build Coastguard Worker                                  "PACIB %0, %1\n\tAUTIB %0, %1\n\t")
152*344aa361SAndroid Build Coastguard Worker                          : "+r"(val)
153*344aa361SAndroid Build Coastguard Worker                          : "r"(i));
154*344aa361SAndroid Build Coastguard Worker     }
155*344aa361SAndroid Build Coastguard Worker 
156*344aa361SAndroid Build Coastguard Worker     return NO_ERROR;
157*344aa361SAndroid Build Coastguard Worker }
158*344aa361SAndroid Build Coastguard Worker 
BENCH_RESULT(pac,pacautib,ps_per_pacautib)159*344aa361SAndroid Build Coastguard Worker BENCH_RESULT(pac, pacautib, ps_per_pacautib) {
160*344aa361SAndroid Build Coastguard Worker     return (bench_get_duration_ns() * 1000u) / (LOOPS * INSTRUCTIONS_PER_LOOP);
161*344aa361SAndroid Build Coastguard Worker }
162*344aa361SAndroid Build Coastguard Worker 
BENCH_RESULT(pac,pacautib,us_total)163*344aa361SAndroid Build Coastguard Worker BENCH_RESULT(pac, pacautib, us_total) {
164*344aa361SAndroid Build Coastguard Worker     return bench_get_duration_ns() / 1000u;
165*344aa361SAndroid Build Coastguard Worker }
166*344aa361SAndroid Build Coastguard Worker 
BENCH_RESULT(pac,pacautib,instructions)167*344aa361SAndroid Build Coastguard Worker BENCH_RESULT(pac, pacautib, instructions) {
168*344aa361SAndroid Build Coastguard Worker     return LOOPS * INSTRUCTIONS_PER_LOOP;
169*344aa361SAndroid Build Coastguard Worker }
170*344aa361SAndroid Build Coastguard Worker #endif
171*344aa361SAndroid Build Coastguard Worker 
172*344aa361SAndroid Build Coastguard Worker /*
173*344aa361SAndroid Build Coastguard Worker  * Simple arithmetic instruction test.
174*344aa361SAndroid Build Coastguard Worker  */
BENCH_ALL_CPU(pac,add,RUNS)175*344aa361SAndroid Build Coastguard Worker BENCH_ALL_CPU(pac, add, RUNS) {
176*344aa361SAndroid Build Coastguard Worker     uint64_t val = 0;
177*344aa361SAndroid Build Coastguard Worker 
178*344aa361SAndroid Build Coastguard Worker     for (uint64_t i = 0; i < EXTRA_LOOPS; i++) {
179*344aa361SAndroid Build Coastguard Worker         __asm__ volatile(PACKBENCH_STR_REP16(PACBENCH_ADD_INSTR)
180*344aa361SAndroid Build Coastguard Worker                          : "+r"(val)
181*344aa361SAndroid Build Coastguard Worker                          : "r"(i));
182*344aa361SAndroid Build Coastguard Worker     }
183*344aa361SAndroid Build Coastguard Worker 
184*344aa361SAndroid Build Coastguard Worker     return NO_ERROR;
185*344aa361SAndroid Build Coastguard Worker }
186*344aa361SAndroid Build Coastguard Worker 
BENCH_RESULT(pac,add,ps_per_add)187*344aa361SAndroid Build Coastguard Worker BENCH_RESULT(pac, add, ps_per_add) {
188*344aa361SAndroid Build Coastguard Worker     return (bench_get_duration_ns() * 1000u) /
189*344aa361SAndroid Build Coastguard Worker            (EXTRA_LOOPS * INSTRUCTIONS_PER_LOOP);
190*344aa361SAndroid Build Coastguard Worker }
191*344aa361SAndroid Build Coastguard Worker 
BENCH_RESULT(pac,add,us_total)192*344aa361SAndroid Build Coastguard Worker BENCH_RESULT(pac, add, us_total) {
193*344aa361SAndroid Build Coastguard Worker     return bench_get_duration_ns() / 1000u;
194*344aa361SAndroid Build Coastguard Worker }
195*344aa361SAndroid Build Coastguard Worker 
BENCH_RESULT(pac,add,instructions)196*344aa361SAndroid Build Coastguard Worker BENCH_RESULT(pac, add, instructions) {
197*344aa361SAndroid Build Coastguard Worker     return EXTRA_LOOPS * INSTRUCTIONS_PER_LOOP;
198*344aa361SAndroid Build Coastguard Worker }
199*344aa361SAndroid Build Coastguard Worker 
200*344aa361SAndroid Build Coastguard Worker /*
201*344aa361SAndroid Build Coastguard Worker  * NOP instruction test.
202*344aa361SAndroid Build Coastguard Worker  */
BENCH_ALL_CPU(pac,nop,RUNS)203*344aa361SAndroid Build Coastguard Worker BENCH_ALL_CPU(pac, nop, RUNS) {
204*344aa361SAndroid Build Coastguard Worker     for (uint64_t i = 0; i < EXTRA_LOOPS; i++) {
205*344aa361SAndroid Build Coastguard Worker         __asm__ volatile(PACKBENCH_STR_REP16(PACBENCH_NOP_INSTR));
206*344aa361SAndroid Build Coastguard Worker     }
207*344aa361SAndroid Build Coastguard Worker 
208*344aa361SAndroid Build Coastguard Worker     return NO_ERROR;
209*344aa361SAndroid Build Coastguard Worker }
210*344aa361SAndroid Build Coastguard Worker 
BENCH_RESULT(pac,nop,ps_per_nop)211*344aa361SAndroid Build Coastguard Worker BENCH_RESULT(pac, nop, ps_per_nop) {
212*344aa361SAndroid Build Coastguard Worker     return (bench_get_duration_ns() * 1000u) /
213*344aa361SAndroid Build Coastguard Worker            (EXTRA_LOOPS * INSTRUCTIONS_PER_LOOP);
214*344aa361SAndroid Build Coastguard Worker }
215*344aa361SAndroid Build Coastguard Worker 
BENCH_RESULT(pac,nop,us_total)216*344aa361SAndroid Build Coastguard Worker BENCH_RESULT(pac, nop, us_total) {
217*344aa361SAndroid Build Coastguard Worker     return bench_get_duration_ns() / 1000u;
218*344aa361SAndroid Build Coastguard Worker }
219*344aa361SAndroid Build Coastguard Worker 
BENCH_RESULT(pac,nop,instructions)220*344aa361SAndroid Build Coastguard Worker BENCH_RESULT(pac, nop, instructions) {
221*344aa361SAndroid Build Coastguard Worker     return EXTRA_LOOPS * INSTRUCTIONS_PER_LOOP;
222*344aa361SAndroid Build Coastguard Worker }
223*344aa361SAndroid Build Coastguard Worker 
224*344aa361SAndroid Build Coastguard Worker PORT_TEST(pac, "com.android.kernel.pacbench")
225