diff options
author | Catalin Marinas <catalin.marinas@arm.com> | 2022-09-30 09:18:11 +0100 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2022-09-30 09:18:11 +0100 |
commit | c397623262fada5df2f92a861000957c36f330c1 (patch) | |
tree | 972dbf9553ac3bccf0789c2ff423cf6e3e298f5d /tools/testing/selftests/arm64/signal/testcases/za_no_regs.c | |
parent | Merge branches 'for-next/doc', 'for-next/sve', 'for-next/sysreg', 'for-next/gettimeofday', 'for-next/stacktrace', 'for-next/atomics', 'for-next/el1-exceptions', 'for-next/a510-erratum-2658417', 'for-next/defconfig', 'for-next/tpidr2_el0' and 'for-next/ftrace', remote-tracking branch 'arm64/for-ne... (diff) | |
parent | kselftest/arm64: Handle EINTR while reading data from children (diff) | |
download | linux-dev-c397623262fada5df2f92a861000957c36f330c1.tar.xz linux-dev-c397623262fada5df2f92a861000957c36f330c1.zip |
Merge branch 'for-next/kselftest' into for-next/core
* for-next/kselftest: (28 commits)
: Kselftest updates for arm64
kselftest/arm64: Handle EINTR while reading data from children
kselftest/arm64: Flag fp-stress as exiting when we begin finishing up
kselftest/arm64: Don't repeat termination handler for fp-stress
kselftest/arm64: Don't enable v8.5 for MTE selftest builds
kselftest/arm64: Fix typo in hwcap check
kselftest/arm64: Add hwcap test for RNG
kselftest/arm64: Add SVE 2 to the tested hwcaps
kselftest/arm64: Add missing newline in hwcap output
kselftest/arm64: Fix spelling misakes of signal names
kselftest/arm64: Enforce actual ABI for SVE syscalls
kselftest/arm64: Correct buffer allocation for SVE Z registers
kselftest/arm64: Include larger SVE and SME VLs in signal tests
kselftest/arm64: Allow larger buffers in get_signal_context()
kselftest/arm64: Preserve any EXTRA_CONTEXT in handle_signal_copyctx()
kselftest/arm64: Validate contents of EXTRA_CONTEXT blocks
kselftest/arm64: Only validate each signal context once
kselftest/arm64: Remove unneeded protype for validate_extra_context()
kselftest/arm64: Fix validation of EXTRA_CONTEXT signal context location
kselftest/arm64: Fix validatation termination record after EXTRA_CONTEXT
kselftest/arm64: Validate signal ucontext in place
...
Diffstat (limited to 'tools/testing/selftests/arm64/signal/testcases/za_no_regs.c')
-rw-r--r-- | tools/testing/selftests/arm64/signal/testcases/za_no_regs.c | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/tools/testing/selftests/arm64/signal/testcases/za_no_regs.c b/tools/testing/selftests/arm64/signal/testcases/za_no_regs.c new file mode 100644 index 000000000000..4d6f94b6178f --- /dev/null +++ b/tools/testing/selftests/arm64/signal/testcases/za_no_regs.c @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2021 ARM Limited + * + * Verify that the ZA register context in signal frames is set up as + * expected. + */ + +#include <signal.h> +#include <ucontext.h> +#include <sys/prctl.h> + +#include "test_signals_utils.h" +#include "testcases.h" + +static union { + ucontext_t uc; + char buf[1024 * 128]; +} context; +static unsigned int vls[SVE_VQ_MAX]; +unsigned int nvls = 0; + +static bool sme_get_vls(struct tdescr *td) +{ + int vq, vl; + + /* + * Enumerate up to SME_VQ_MAX vector lengths + */ + for (vq = SVE_VQ_MAX; vq > 0; --vq) { + vl = prctl(PR_SME_SET_VL, vq * 16); + if (vl == -1) + return false; + + vl &= PR_SME_VL_LEN_MASK; + + /* Skip missing VLs */ + vq = sve_vq_from_vl(vl); + + vls[nvls++] = vl; + } + + /* We need at least one VL */ + if (nvls < 1) { + fprintf(stderr, "Only %d VL supported\n", nvls); + return false; + } + + return true; +} + +static int do_one_sme_vl(struct tdescr *td, siginfo_t *si, ucontext_t *uc, + unsigned int vl) +{ + size_t offset; + struct _aarch64_ctx *head = GET_BUF_RESV_HEAD(context); + struct za_context *za; + + fprintf(stderr, "Testing VL %d\n", vl); + + if (prctl(PR_SME_SET_VL, vl) != vl) { + fprintf(stderr, "Failed to set VL\n"); + return 1; + } + + /* + * Get a signal context which should have a SVE frame and registers + * in it. + */ + if (!get_current_context(td, &context.uc, sizeof(context))) + return 1; + + head = get_header(head, ZA_MAGIC, GET_BUF_RESV_SIZE(context), &offset); + if (!head) { + fprintf(stderr, "No ZA context\n"); + return 1; + } + + za = (struct za_context *)head; + if (za->vl != vl) { + fprintf(stderr, "Got VL %d, expected %d\n", za->vl, vl); + return 1; + } + + if (head->size != ZA_SIG_REGS_OFFSET) { + fprintf(stderr, "Context size %u, expected %lu\n", + head->size, ZA_SIG_REGS_OFFSET); + return 1; + } + + /* The actual size validation is done in get_current_context() */ + fprintf(stderr, "Got expected size %u and VL %d\n", + head->size, za->vl); + + return 0; +} + +static int sme_regs(struct tdescr *td, siginfo_t *si, ucontext_t *uc) +{ + int i; + + for (i = 0; i < nvls; i++) { + if (do_one_sme_vl(td, si, uc, vls[i])) + return 1; + } + + td->pass = 1; + + return 0; +} + +struct tdescr tde = { + .name = "ZA registers - ZA disabled", + .descr = "Check ZA context with ZA disabled", + .feats_required = FEAT_SME, + .timeout = 3, + .init = sme_get_vls, + .run = sme_regs, +}; |