/*
* Copyright ( C ) 2022 The Android Open Source Project
*
* Licensed under the Apache License , Version 2 . 0 ( the " License " ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an " AS IS " BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
*/
#define TLOG_TAG "pacbench"
#include <arch/ops.h>
#include <inttypes.h>
#include <stdint.h>
#include <trusty_benchmark.h>
#include <uapi/err.h>
/* Runs over which to collect statistics */
#define RUNS 100 u
/* Benchmark run duration */
#define LOOPS 1000000 u
#define INSTRUCTIONS_PER_LOOP 16 u
/* Extended loop count for faster functions */
#define EXTRA_LOOPS 10000000 u
#define PACKBENCH_STR_REP2(s) s s
#define PACKBENCH_STR_REP4(s) PACKBENCH_STR_REP2(s) PACKBENCH_STR_REP2(s)
#define PACKBENCH_STR_REP8(s) PACKBENCH_STR_REP4(s) PACKBENCH_STR_REP4(s)
#define PACKBENCH_STR_REP16(s) PACKBENCH_STR_REP8(s) PACKBENCH_STR_REP8(s)
BENCH_SETUP(pac) {
return NO_ERROR;
}
BENCH_TEARDOWN(pac) {}
#ifdef KERNEL_PAC_ENABLED
/*
* Test PACIA instruction .
* If PAC is supported and enabled in the kernel , this key should be valid and
* the instruction functional , though this benchmark does not test the
* instruction - see pactest instead .
*/
BENCH_ALL_CPU(pac, pacia, RUNS) {
uint64_t val = 0 ;
for (uint64_t i = 0 ; i < LOOPS; i++) {
__asm__ volatile (".arch_extension pauth\n\t" PACKBENCH_STR_REP16(
"PACIA %0, %1\n\t" )
: "+r" (val)
: "r" (i));
}
return NO_ERROR;
}
BENCH_RESULT(pac, pacia, ps_per_pacia) {
return (bench_get_duration_ns() * 1000 u) / (LOOPS * INSTRUCTIONS_PER_LOOP);
}
BENCH_RESULT(pac, pacia, us_total) {
return bench_get_duration_ns() / 1000 u;
}
BENCH_RESULT(pac, pacia, instructions) {
return LOOPS * INSTRUCTIONS_PER_LOOP;
}
/*
* Test PACIA & AUTIA instruction .
* If PAC is supported and enabled in the kernel , this key should be valid and
* the instruction functional .
* Note we cannot test AUTIA alone since it may generate an exception if it
* fails .
*/
BENCH_ALL_CPU(pac, pacautia, RUNS) {
uint64_t val = 0 ;
for (uint64_t i = 0 ; i < LOOPS; i++) {
__asm__ volatile (".arch_extension pauth\n\t" PACKBENCH_STR_REP16(
"PACIA %0, %1\n\tAUTIA %0, %1\n\t" )
: "+r" (val)
: "r" (i));
}
return NO_ERROR;
}
BENCH_RESULT(pac, pacautia, ps_per_pacautia) {
return (bench_get_duration_ns() * 1000 u) / (LOOPS * INSTRUCTIONS_PER_LOOP);
}
BENCH_RESULT(pac, pacautia, us_total) {
return bench_get_duration_ns() / 1000 u;
}
BENCH_RESULT(pac, pacautia, instructions) {
return LOOPS * INSTRUCTIONS_PER_LOOP;
}
/*
* Test PACIB instruction .
* If PAC is supported and enabled in the kernel , this key should be valid and
* the instruction functional , though this benchmark does not test the
* instruction - see pactest instead .
*/
BENCH_ALL_CPU(pac, pacib, RUNS) {
uint64_t val = 0 ;
for (uint64_t i = 0 ; i < LOOPS; i++) {
__asm__ volatile (".arch_extension pauth\n\t" PACKBENCH_STR_REP16(
"PACIB %0, %1\n\t" )
: "+r" (val)
: "r" (i));
}
return NO_ERROR;
}
BENCH_RESULT(pac, pacib, ps_per_pacib) {
return (bench_get_duration_ns() * 1000 u) / (LOOPS * INSTRUCTIONS_PER_LOOP);
}
BENCH_RESULT(pac, pacib, us_total) {
return bench_get_duration_ns() / 1000 u;
}
BENCH_RESULT(pac, pacib, instructions) {
return LOOPS * INSTRUCTIONS_PER_LOOP;
}
/*
* Test PACIAB & AUTIB instruction .
* Even if PAC is supported by the hardware , Trusty doesn ' t use or enable this
* key .
*/
BENCH_ALL_CPU(pac, pacautib, RUNS) {
uint64_t val = 0 ;
for (uint64_t i = 0 ; i < LOOPS; i++) {
__asm__ volatile (".arch_extension pauth\n\t" PACKBENCH_STR_REP16(
"PACIB %0, %1\n\tAUTIB %0, %1\n\t" )
: "+r" (val)
: "r" (i));
}
return NO_ERROR;
}
BENCH_RESULT(pac, pacautib, ps_per_pacautib) {
return (bench_get_duration_ns() * 1000 u) / (LOOPS * INSTRUCTIONS_PER_LOOP);
}
BENCH_RESULT(pac, pacautib, us_total) {
return bench_get_duration_ns() / 1000 u;
}
BENCH_RESULT(pac, pacautib, instructions) {
return LOOPS * INSTRUCTIONS_PER_LOOP;
}
#endif
/*
* Simple arithmetic instruction test .
*/
BENCH_ALL_CPU(pac, add, RUNS) {
uint64_t val = 0 ;
for (uint64_t i = 0 ; i < EXTRA_LOOPS; i++) {
__asm__ volatile (PACKBENCH_STR_REP16(PACBENCH_ADD_INSTR)
: "+r" (val)
: "r" (i));
}
return NO_ERROR;
}
BENCH_RESULT(pac, add, ps_per_add) {
return (bench_get_duration_ns() * 1000 u) /
(EXTRA_LOOPS * INSTRUCTIONS_PER_LOOP);
}
BENCH_RESULT(pac, add, us_total) {
return bench_get_duration_ns() / 1000 u;
}
BENCH_RESULT(pac, add, instructions) {
return EXTRA_LOOPS * INSTRUCTIONS_PER_LOOP;
}
/*
* NOP instruction test .
*/
BENCH_ALL_CPU(pac, nop, RUNS) {
for (uint64_t i = 0 ; i < EXTRA_LOOPS; i++) {
__asm__ volatile (PACKBENCH_STR_REP16(PACBENCH_NOP_INSTR));
}
return NO_ERROR;
}
BENCH_RESULT(pac, nop, ps_per_nop) {
return (bench_get_duration_ns() * 1000 u) /
(EXTRA_LOOPS * INSTRUCTIONS_PER_LOOP);
}
BENCH_RESULT(pac, nop, us_total) {
return bench_get_duration_ns() / 1000 u;
}
BENCH_RESULT(pac, nop, instructions) {
return EXTRA_LOOPS * INSTRUCTIONS_PER_LOOP;
}
PORT_TEST(pac, "com.android.kernel.pacbench" )
Messung V0.5 in Prozent C=90 H=93 G=91
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-06-27)
¤
*© Formatika GbR, Deutschland