These patches improve the coverage of ZA signal contexts a bit, adding some validation that the actual data is correct and covering the case where ZA is not enabled.
v2: - Rebase onto v6.0-rc3.
Mark Brown (2): kselftest/arm64: Tighten up validation of ZA signal context kselftest/arm64: Add a test for signal frames with ZA disabled
.../arm64/signal/testcases/za_no_regs.c | 119 ++++++++++++++++++ .../arm64/signal/testcases/za_regs.c | 16 ++- 2 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/arm64/signal/testcases/za_no_regs.c
base-commit: b90cb1053190353cc30f0fef0ef1f378ccc063c5
Currently we accept any size for the ZA signal context that the shared code will accept which means we don't verify that any data is present. Since we have enabled ZA we know that there must be data so strengthen the check to only accept a signal frame with data, and while we're at it since we enabled ZA but did not set any data we know that ZA must contain zeros, confirm that.
Signed-off-by: Mark Brown broonie@kernel.org --- .../selftests/arm64/signal/testcases/za_regs.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/arm64/signal/testcases/za_regs.c b/tools/testing/selftests/arm64/signal/testcases/za_regs.c index b94e4f99fcac..2514cb7de525 100644 --- a/tools/testing/selftests/arm64/signal/testcases/za_regs.c +++ b/tools/testing/selftests/arm64/signal/testcases/za_regs.c @@ -52,6 +52,8 @@ static void setup_za_regs(void) asm volatile(".inst 0xd503457f" : : : ); }
+static char zeros[ZA_SIG_REGS_SIZE(SVE_VQ_MAX)]; + static int do_one_sme_vl(struct tdescr *td, siginfo_t *si, ucontext_t *uc, unsigned int vl) { @@ -87,10 +89,22 @@ static int do_one_sme_vl(struct tdescr *td, siginfo_t *si, ucontext_t *uc, return 1; }
- /* The actual size validation is done in get_current_context() */ + if (head->size != ZA_SIG_CONTEXT_SIZE(sve_vq_from_vl(vl))) { + fprintf(stderr, "ZA context size %u, expected %lu\n", + head->size, ZA_SIG_CONTEXT_SIZE(sve_vq_from_vl(vl))); + return 1; + } + fprintf(stderr, "Got expected size %u and VL %d\n", head->size, za->vl);
+ /* We didn't load any data into ZA so it should be all zeros */ + if (memcmp(zeros, (char *)za + ZA_SIG_REGS_OFFSET, + ZA_SIG_REGS_SIZE(sve_vq_from_vl(za->vl))) != 0) { + fprintf(stderr, "ZA data invalid\n"); + return 1; + } + return 0; }
When ZA is disabled there should be no register data in the ZA signal frame, add a test case which confirms that this is the case.
Signed-off-by: Mark Brown broonie@kernel.org --- .../arm64/signal/testcases/za_no_regs.c | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 tools/testing/selftests/arm64/signal/testcases/za_no_regs.c
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, +};
On Mon, 29 Aug 2022 16:57:26 +0100, Mark Brown wrote:
These patches improve the coverage of ZA signal contexts a bit, adding some validation that the actual data is correct and covering the case where ZA is not enabled.
v2:
- Rebase onto v6.0-rc3.
[...]
Applied to arm64 (for-next/kselftest), thanks!
[1/2] kselftest/arm64: Tighten up validation of ZA signal context https://git.kernel.org/arm64/c/f02b69a6e4d1 [2/2] kselftest/arm64: Add a test for signal frames with ZA disabled https://git.kernel.org/arm64/c/4bcfa65860b2
linux-kselftest-mirror@lists.linaro.org