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