Validate successful and trapped executions of GCSPUSHM, GCSPOPM. Signed-off-by: Richard Henderson <richard.hender...@linaro.org> --- tests/tcg/aarch64/gcspushm.c | 77 +++++++++++++++++++++++++++++++ tests/tcg/aarch64/Makefile.target | 2 +- 2 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 tests/tcg/aarch64/gcspushm.c
diff --git a/tests/tcg/aarch64/gcspushm.c b/tests/tcg/aarch64/gcspushm.c new file mode 100644 index 0000000000..0c7cc09065 --- /dev/null +++ b/tests/tcg/aarch64/gcspushm.c @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gcs.h" + + +#define GCSPUSHM "sys #3, c7, c7, #0, %[push]" +#define GCSPOPM "sysl %[pop], #3, c7, c7, #1" + +static volatile uint64_t test_pc; + +static void test_sigsegv(int sig, siginfo_t *info, void *vuc) +{ + ucontext_t *uc = vuc; + + assert(uc->uc_mcontext.pc == test_pc); + assert(info->si_code == SEGV_CPERR); + /* TODO: Dig for ESR and verify syndrome. */ + uc->uc_mcontext.pc += 4; +} + +static void test_sigill(int sig, siginfo_t *info, void *vuc) +{ + ucontext_t *uc = vuc; + + assert(uc->uc_mcontext.pc == test_pc); + assert(info->si_code == ILL_ILLOPC); + uc->uc_mcontext.pc += 4; +} + +int main() +{ + struct sigaction sa = { .sa_flags = SA_SIGINFO }; + uint64_t tmp, old, new; + + enable_gcs(PR_SHADOW_STACK_PUSH); + + /* Valid value -- low 2 bits clear */ + old = 0xdeadbeeffeedcaec; + asm volatile(GCSPUSHM "\n\t" GCSPOPM + : [pop] "=r" (new) + : [push] "r" (old)); + assert(old == new); + + sa.sa_sigaction = test_sigsegv; + if (sigaction(SIGSEGV, &sa, NULL) < 0) { + perror("sigaction"); + exit(1); + } + + /* Invalid value -- SIGSEGV via EC_GCS */ + asm volatile("adr %[tmp], 0f\n\t" + "str %[tmp], %[test]\n\t" + GCSPUSHM "\n" + "0:" GCSPOPM + : [tmp] "=&r" (tmp), + [test] "=m" (test_pc), + [pop] "=r" (new) + : [push] "r" (1)); + + enable_gcs(0); + + sa.sa_sigaction = test_sigill; + if (sigaction(SIGILL, &sa, NULL) < 0) { + perror("sigaction"); + exit(1); + } + + /* Pushm is disabled -- SIGILL via EC_SYSTEMREGISTERTRAP */ + asm volatile("adr %[tmp], 0f\n\t" + "str %[tmp], %[test]\n" + "0:\t" GCSPUSHM + : [tmp] "=&r" (tmp), + [test] "=m" (test_pc) + : [push] "r" (1)); + + exit(0); +} diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target index 0347a36e8d..c6f401c317 100644 --- a/tests/tcg/aarch64/Makefile.target +++ b/tests/tcg/aarch64/Makefile.target @@ -76,7 +76,7 @@ $(SME_TESTS): CFLAGS += $(CROSS_AS_HAS_ARMV9_SME) endif # GCS Tests -GCS_TESTS += gcsstr +GCS_TESTS += gcsstr gcspushm AARCH64_TESTS += $(GCS_TESTS) $(GCS_TESTS): gcs.h -- 2.43.0