/* * Test execution of DC CVADP instruction. * * Copyright (c) 2023 Zhuojia Shen * SPDX-License-Identifier: GPL-2.0-or-later */ #include #include #include #include #include #include #ifndef HWCAP2_DCPODP #define HWCAP2_DCPODP (1 << 0) #endif bool should_fail = false; static void signal_handler(int sig, siginfo_t *si, void *data) { ucontext_t *uc = (ucontext_t *)data; if (should_fail) { uc->uc_mcontext.pc += 4; } else { exit(EXIT_FAILURE); } } static int do_dc_cvadp(void) { struct sigaction sa = { .sa_flags = SA_SIGINFO, .sa_sigaction = signal_handler, }; sigemptyset(&sa.sa_mask); if (sigaction(SIGSEGV, &sa, NULL) < 0) { perror("sigaction"); return EXIT_FAILURE; } asm volatile("dc cvadp, %0\n\t" :: "r"(&sa)); should_fail = true; asm volatile("dc cvadp, %0\n\t" :: "r"(NULL)); should_fail = false; return EXIT_SUCCESS; } int main(void) { if (getauxval(AT_HWCAP2) & HWCAP2_DCPODP) { return do_dc_cvadp(); } else { printf("SKIP: no HWCAP2_DCPODP on this system\n"); return EXIT_SUCCESS; } }