While discussing the SME signal handling support I realised that we were not verifying that SVE_SIG_FLAG_SM is set for streaming SVE, and not explicitly covering the case where we are both in streaming mode and have ZA enabled. Add coverage of these cases, I didn't find any problems running these new tests.
To: Catalin Marinas catalin.marinas@arm.com To: Will Deacon will@kernel.org To: Shuah Khan shuah@kernel.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-kselftest@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Mark Brown broonie@kernel.org
--- Mark Brown (2): kselftest/arm64: Verify that SSVE signal context has SVE_SIG_FLAG_SM set kselftest/arm64: Verify simultaneous SSVE and ZA context generation
.../selftests/arm64/signal/testcases/ssve_regs.c | 5 + .../arm64/signal/testcases/ssve_za_regs.c | 162 +++++++++++++++++++++ 2 files changed, 167 insertions(+) --- base-commit: b7bfaa761d760e72a969d116517eaa12e404c262 change-id: 20230117-arm64-test-ssve-za-7128c0ce8dc9
Best regards,
Streaming mode SVE signal context should have SVE_SIG_FLAG_SM set but we were not actually validating this. Add a check.
Signed-off-by: Mark Brown broonie@kernel.org --- tools/testing/selftests/arm64/signal/testcases/ssve_regs.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/tools/testing/selftests/arm64/signal/testcases/ssve_regs.c b/tools/testing/selftests/arm64/signal/testcases/ssve_regs.c index d0a178945b1a..cd738265cdcd 100644 --- a/tools/testing/selftests/arm64/signal/testcases/ssve_regs.c +++ b/tools/testing/selftests/arm64/signal/testcases/ssve_regs.c @@ -92,6 +92,11 @@ static int do_one_sme_vl(struct tdescr *td, siginfo_t *si, ucontext_t *uc, return 1; }
+ if (!(ssve->flags & SVE_SIG_FLAG_SM)) { + fprintf(stderr, "SVE_SIG_FLAG_SM not set in SVE record\n"); + return 1; + } + /* The actual size validation is done in get_current_context() */ fprintf(stderr, "Got expected size %u and VL %d\n", head->size, ssve->vl);
Add a test that generates SSVE and ZA context in a single signal frame to ensure that nothing is going wrong in that case for any reason.
Signed-off-by: Mark Brown broonie@kernel.org --- .../arm64/signal/testcases/ssve_za_regs.c | 162 +++++++++++++++++++++ 1 file changed, 162 insertions(+)
diff --git a/tools/testing/selftests/arm64/signal/testcases/ssve_za_regs.c b/tools/testing/selftests/arm64/signal/testcases/ssve_za_regs.c new file mode 100644 index 000000000000..954a21f6121a --- /dev/null +++ b/tools/testing/selftests/arm64/signal/testcases/ssve_za_regs.c @@ -0,0 +1,162 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2021 ARM Limited + * + * Verify that both the streaming SVE and ZA register context in + * signal frames is set up as expected when enabled simultaneously. + */ + +#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 SVE_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 void setup_regs(void) +{ + /* smstart sm; real data is TODO */ + asm volatile(".inst 0xd503437f" : : : ); + + /* smstart za; real data is TODO */ + 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) +{ + size_t offset; + struct _aarch64_ctx *head = GET_BUF_RESV_HEAD(context); + struct _aarch64_ctx *regs; + struct sve_context *ssve; + struct za_context *za; + int ret; + + fprintf(stderr, "Testing VL %d\n", vl); + + ret = prctl(PR_SME_SET_VL, vl); + if (ret != vl) { + fprintf(stderr, "Failed to set VL, got %d\n", ret); + return 1; + } + + /* + * Get a signal context which should have the SVE and ZA + * frames in it. + */ + setup_regs(); + if (!get_current_context(td, &context.uc, sizeof(context))) + return 1; + + regs = get_header(head, SVE_MAGIC, GET_BUF_RESV_SIZE(context), + &offset); + if (!regs) { + fprintf(stderr, "No SVE context\n"); + return 1; + } + + ssve = (struct sve_context *)regs; + if (ssve->vl != vl) { + fprintf(stderr, "Got SSVE VL %d, expected %d\n", ssve->vl, vl); + return 1; + } + + if (!(ssve->flags & SVE_SIG_FLAG_SM)) { + fprintf(stderr, "SVE_SIG_FLAG_SM not set in SVE record\n"); + return 1; + } + + fprintf(stderr, "Got expected SSVE size %u and VL %d\n", + regs->size, ssve->vl); + + regs = get_header(head, ZA_MAGIC, GET_BUF_RESV_SIZE(context), + &offset); + if (!regs) { + fprintf(stderr, "No ZA context\n"); + return 1; + } + + za = (struct za_context *)regs; + if (za->vl != vl) { + fprintf(stderr, "Got ZA VL %d, expected %d\n", za->vl, vl); + return 1; + } + + fprintf(stderr, "Got expected ZA size %u and VL %d\n", + regs->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; +} + +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 = "Streaming SVE registers", + .descr = "Check that we get the right Streaming SVE registers reported", + /* + * We shouldn't require FA64 but things like memset() used in the + * helpers might use unsupported instructions so for now disable + * the test unless we've got the full instruction set. + */ + .feats_required = FEAT_SME | FEAT_SME_FA64, + .timeout = 3, + .init = sme_get_vls, + .run = sme_regs, +};
On Fri, 20 Jan 2023 12:04:08 +0000, Mark Brown wrote:
While discussing the SME signal handling support I realised that we were not verifying that SVE_SIG_FLAG_SM is set for streaming SVE, and not explicitly covering the case where we are both in streaming mode and have ZA enabled. Add coverage of these cases, I didn't find any problems running these new tests.
[...]
Applied to arm64 (for-next/kselftest), thanks!
[1/2] kselftest/arm64: Verify that SSVE signal context has SVE_SIG_FLAG_SM set https://git.kernel.org/arm64/c/f76cb73a2d7c [2/2] kselftest/arm64: Verify simultaneous SSVE and ZA context generation https://git.kernel.org/arm64/c/bc69da5ff087
linux-kselftest-mirror@lists.linaro.org