kselftest/arm64: SVE signal handling tests
cover kselftest/arm64: SVE signal handling tests
Currently we have no real tests for SVE signal handling (though the stress test does trigger the code paths as it regularly sends signals to the test processes). Add some basic coverage, this is very much incomplete but it's more coverage than we currently have, a TODO file is included with some omissions that occurred to me.
Mark Brown (6):
kselftest/arm64: signal: Add SVE to the set of features we can check
for
kselftest/arm64: signal: Support signal frames with SVE register data kselftest/arm64: signal: Check SVE signal frame shows expected vector
length
kselftest/arm64: signal: Verify that signals can't change the SVE
vector length
kselftest/arm64: signal: Add test case for SVE register state in
signals
kselftest/arm64: signal: Add a TODO list for signal handling tests
.../testing/selftests/arm64/signal/.gitignore | 1 + .../selftests/arm64/signal/test_signals.h | 2 + .../arm64/signal/test_signals_utils.c | 3 + .../selftests/arm64/signal/testcases/TODO | 2 + .../testcases/fake_sigreturn_sve_change_vl.c | 92 +++++++++++++ .../arm64/signal/testcases/sve_regs.c | 126 ++++++++++++++++++ .../selftests/arm64/signal/testcases/sve_vl.c | 68 ++++++++++ .../arm64/signal/testcases/testcases.c | 34 ++++- 8 files changed, 325 insertions(+), 3 deletions(-) create mode 100644 tools/testing/selftests/arm64/signal/testcases/TODO create mode 100644 tools/testing/selftests/arm64/signal/testcases/fake_sigreturn_sve_change_vl.c create mode 100644 tools/testing/selftests/arm64/signal/testcases/sve_regs.c create mode 100644 tools/testing/selftests/arm64/signal/testcases/sve_vl.c
base-commit: ff1176468d368232b684f75e82563369208bc371
Signature · 7 lines
2.20.1 _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH 1/6 kselftest/arm64: signal: Add SVE to the set of features we can check for
Allow testcases for SVE signal handling to flag the dependency and be skipped on systems without SVE support.
--- tools/testing/selftests/arm64/signal/test_signals.h | 2 ++ tools/testing/selftests/arm64/signal/test_signals_utils.c | 3 +++ 2 files changed, 5 insertions(+)
tools/testing/selftests/arm64/signal/test_signals.h +2 -0
@@ -33,10 +33,12 @@*/ enum {FSSBS_BIT , +FSVE_BIT ,FMAX_END };#define FEAT_SSBS (1UL << FSSBS_BIT) +#define FEAT_SVE (1UL << FSVE_BIT)/* * A descriptor used to describe and configure a test case.
tools/testing/selftests/arm64/signal/test_signals_utils.c +3 -0
@@ -26,6 +26,7 @@ static int sig_copyctx = SIGTRAP;static char const *const feats_names[FMAX_END ] = {" SSBS " , +" SVE " , };#define MAX_FEATS_SZ 128
@@ -263,6 +264,8 @@ int test_init(struct tdescr *td)*/ if (getauxval (AT_HWCAP ) &HWCAP_SSBS ) td->feats_supported |=FEAT_SSBS ; +if (getauxval (AT_HWCAP ) &HWCAP_SVE ) + td->feats_supported |=FEAT_SVE ;if (feats_ok (td)) fprintf(stderr, "Required Features: [%s] supported\n",
Signature · 7 lines
2.20.1 _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH 2/6 kselftest/arm64: signal: Support signal frames with SVE register data
In reply to Mark BrownA signal frame with SVE may validly either be a bare struct sve_context or a struct sve_context followed by vector length dependent register data. Support either in the generic helpers for the signal tests, and while we're at it validate the SVE vector length reported.
--- .../arm64/signal/testcases/testcases.c | 34 +++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-)
tools/testing/selftests/arm64/signal/testcases/testcases.c +31 -3
@@ -50,12 +50,38 @@ bool validate_extra_context(struct extra_context *extra, char **err)return true; } +bool validate_sve_context (struct sve_context *sve,char **err) +{ +/* Size will be rounded up to a multiple of 16 bytes */ +size_t regs_size + = ((SVE_SIG_CONTEXT_SIZE (sve_vq_from_vl (sve->vl)) +15 ) /16 ) *16 ; + +if (!sve || !err) +return false; + +/* Either a bare sve_context or a sve_context followed by regs data */ +if ((sve->head.size !=sizeof (struct sve_context )) && + (sve->head.size != regs_size)) { + *err ="bad size for SVE context" ; +return false; + } + +if (!sve_vl_valid (sve->vl)) { + *err ="SVE VL invalid" ; + +return false; + } + +return true; +} +bool validate_reserved (ucontext_t *uc,size_t resv_sz,char **err) {bool terminated = false;size_t offs =0 ;int flags =0 ;struct extra_context *extra =NULL ; +struct sve_context *sve =NULL ;struct _aarch64_ctx *head = (struct _aarch64_ctx *)uc->uc_mcontext.__reserved;
@@ -90,9 +116,8 @@ bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)case SVE_MAGIC :if (flags &SVE_CTX ) *err ="Multiple SVE_MAGIC" ; -else if (head->size != -sizeof (struct sve_context )) - *err ="Bad size for sve_context" ; +/* Size is validated in validate_sve_context() */ + sve = (struct sve_context *)head; flags |=SVE_CTX ;break ;case EXTRA_MAGIC :
@@ -137,6 +162,9 @@ bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)if (flags &EXTRA_CTX )if (!validate_extra_context (extra, err))return false; +if (flags &SVE_CTX ) +if (!validate_sve_context (sve, err)) +return false; head =GET_RESV_NEXT_HEAD (head); }
Signature · 7 lines
2.20.1 _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH 3/6 kselftest/arm64: signal: Check SVE signal frame shows expected vector length
In reply to Mark BrownAs a basic check that the SVE signal frame is being set up correctly verify that the vector length in the signal frame is the vector length that the process has.
--- .../testing/selftests/arm64/signal/.gitignore | 1 + .../selftests/arm64/signal/testcases/sve_vl.c | 68 +++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 tools/testing/selftests/arm64/signal/testcases/sve_vl.c
tools/testing/selftests/arm64/signal/.gitignore +1 -0
@@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only mangle_* fake_sigreturn_* +sve_* !*.[ch]
tools/testing/selftests/arm64/signal/testcases/sve_vl.c new file +68 -0
68 lines not on this page · raw message
Signature · 7 lines
2.20.1 _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH 4/6 kselftest/arm64: signal: Verify that signals can't change the SVE vector length
In reply to Mark BrownWe do not support changing the SVE vector length as part of signal return, verify that this is the case if the system supports multiple vector lengths.
--- .../testcases/fake_sigreturn_sve_change_vl.c | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 tools/testing/selftests/arm64/signal/testcases/fake_sigreturn_sve_change_vl.c
tools/testing/selftests/arm64/signal/testcases/fake_sigreturn_sve_change_vl.c new file +92 -0
@@ -0,0 +1,92 @@ +// SPDX-License-Identifier: GPL-2.0 +/* +* Copyright (C) 2021 ARM Limited +* +* Attempt to change the SVE vector length in a signal hander, this is not +* supported and is expected to segfault. +*/ + +#include <signal.h> +#include <ucontext.h> +#include <sys/prctl.h> + +#include "test_signals_utils.h" +#include "testcases.h" + +struct fake_sigframe sf; +static unsigned int vls[SVE_VQ_MAX ]; +unsigned int nvls =0 ; + +static bool sve_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_SVE_SET_VL , vq *16 ); +if (vl ==-1 ) +return false; + + vl &=PR_SVE_VL_LEN_MASK ; + +/* Skip missing VLs */ + vq =sve_vq_from_vl (vl); + + vls[nvls++] = vl; + } + +/* We need at least two VLs */ +if (nvls <2 ) { +fprintf (stderr,"Only %d VL supported\n" , nvls); +return false; + } + +return true; +} + +static int fake_sigreturn_sve_change_vl (struct tdescr *td, +siginfo_t *si,ucontext_t *uc) +{ +size_t resv_sz, offset; +struct _aarch64_ctx *head =GET_SF_RESV_HEAD (sf); +struct sve_context *sve; + +/* Get a signal context with a SVE frame in it */ +if (!get_current_context (td, &sf.uc)) +return 1 ; + + resv_sz =GET_SF_RESV_SIZE (sf); + head =get_header (head,SVE_MAGIC , resv_sz, &offset); +if (!head) { +fprintf (stderr,"No SVE context\n" ); +return 1 ; + } + +if (head->size !=sizeof (struct sve_context )) { +fprintf (stderr,"SVE register state active, skipping\n" ); +return 1 ; + } + + sve = (struct sve_context *)head; + +/* No changes are supported; init left us at minimum VL so go to max */ +fprintf (stderr,"Attempting to change VL from %d to %d\n" , + sve->vl, vls[0 ]); + sve->vl = vls[0 ]; + +fake_sigreturn (&sf,sizeof (sf),0 ); + +return 1 ; +} + +struct tdescr tde = { + .name ="FAKE_SIGRETURN_SVE_CHANGE" , + .descr ="Attempt to change SVE VL" , + .feats_required =FEAT_SVE , + .sig_ok =SIGSEGV , + .timeout =3 , + .init = sve_get_vls, + .run = fake_sigreturn_sve_change_vl, +};
Signature · 7 lines
2.20.1 _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH 5/6 kselftest/arm64: signal: Add test case for SVE register state in signals
In reply to Mark BrownCurrently this doesn't actually verify that the register contents do the right thing, it just verifes that a SVE context with appropriate size appears.
--- .../arm64/signal/testcases/sve_regs.c | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 tools/testing/selftests/arm64/signal/testcases/sve_regs.c
tools/testing/selftests/arm64/signal/testcases/sve_regs.c new file +126 -0
@@ -0,0 +1,126 @@ +// SPDX-License-Identifier: GPL-2.0 +/* +* Copyright (C) 2021 ARM Limited +* +* Verify that the SVE 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" + +struct fake_sigframe sf; +static unsigned int vls[SVE_VQ_MAX ]; +unsigned int nvls =0 ; + +static bool sve_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_SVE_SET_VL , vq *16 ); +if (vl ==-1 ) +return false; + + vl &=PR_SVE_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_sve_regs (void ) +{ +/* RDVL x16, #1 so we should have SVE regs; real data is TODO */ + asmvolatile (".inst 0x04bf5030" : : :"x16" ); +} + +static int do_one_sve_vl (struct tdescr *td,siginfo_t *si,ucontext_t *uc, +unsigned int vl) +{ +size_t resv_sz, offset; +struct _aarch64_ctx *head =GET_SF_RESV_HEAD (sf); +struct sve_context *sve; + +fprintf (stderr,"Testing VL %d\n" , vl); + +if (prctl (PR_SVE_SET_VL , vl) ==-1 ) { +fprintf (stderr,"Failed to set VL\n" ); +return 1 ; + } + +/* +* Get a signal context which should have a SVE frame and registers +* in it. +*/ +setup_sve_regs (); +if (!get_current_context (td, &sf.uc)) +return 1 ; + + resv_sz =GET_SF_RESV_SIZE (sf); + head =get_header (head,SVE_MAGIC , resv_sz, &offset); +if (!head) { +fprintf (stderr,"No SVE context\n" ); +return 1 ; + } + + sve = (struct sve_context *)head; +if (sve->vl != vl) { +fprintf (stderr,"Got VL %d, expected %d\n" , sve->vl, vl); +return 1 ; + } + +/* The actual size validation is done in get_current_context() */ +fprintf (stderr,"Got expected size %u and VL %d\n" , + head->size, sve->vl); + +return 0 ; +} + +static int sve_regs (struct tdescr *td,siginfo_t *si,ucontext_t *uc) +{ +int i; + +for (i =0 ; i < nvls; i++) { +/* +* TODO: the signal test helpers can't currently cope +* with signal frames bigger than struct sigcontext, +* skip VLs that will trigger that. +*/ +if (vls[i] >64 ) +continue ; + +if (do_one_sve_vl (td, si, uc, vls[i])) +return 1 ; + } + + td->pass =1 ; + +return 0 ; +} + +struct tdescr tde = { + .name ="SVE registers" , + .descr ="Check that we get the right SVE registers reported" , + .feats_required =FEAT_SVE , + .timeout =3 , + .init = sve_get_vls, + .run = sve_regs, +};
Signature · 7 lines
2.20.1 _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH 6/6 kselftest/arm64: signal: Add a TODO list for signal handling tests
In reply to Mark BrownNote down a few gaps in our coverage.
--- tools/testing/selftests/arm64/signal/testcases/TODO | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 tools/testing/selftests/arm64/signal/testcases/TODO
tools/testing/selftests/arm64/signal/testcases/TODO new file +2 -0
@@ -0,0 +1,2 @@ +- Validate that register contents are saved and restored as expected. +- Support and validate extra_context.
Signature · 7 lines
2.20.1 _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Catalin Marinas
maintainerQuoted 18 lines · Mark Brown
Currently we have no real tests for SVE signal handling (though the stress test does trigger the code paths as it regularly sends signals to the test processes). Add some basic coverage, this is very much incomplete but it's more coverage than we currently have, a TODO file is included with some omissions that occurred to me.
Mark Brown (6):
kselftest/arm64: signal: Add SVE to the set of features we can check
for
kselftest/arm64: signal: Support signal frames with SVE register data kselftest/arm64: signal: Check SVE signal frame shows expected vector
length
kselftest/arm64: signal: Verify that signals can't change the SVE
vector length
kselftest/arm64: signal: Add test case for SVE register state in
signals
kselftest/arm64: signal: Add a TODO list for signal handling tests
Quoted 1 line
[...]
Applied to arm64 (for-next/kselftest), thanks!
[1/6] kselftest/arm64: signal: Add SVE to the set of features we can check for
https://git.kernel.org/arm64/c/d4e4dc4fab68 [2/6] kselftest/arm64: signal: Support signal frames with SVE register data https://git.kernel.org/arm64/c/ace19b1845a5 [3/6] kselftest/arm64: signal: Check SVE signal frame shows expected vector length https://git.kernel.org/arm64/c/c1f67a19c12e [4/6] kselftest/arm64: signal: Verify that signals can't change the SVE vector length https://git.kernel.org/arm64/c/d25ac50ce8f7 [5/6] kselftest/arm64: signal: Add test case for SVE register state in signals https://git.kernel.org/arm64/c/5262b216f4a9 [6/6] kselftest/arm64: signal: Add a TODO list for signal handling tests https://git.kernel.org/arm64/c/fa5ca80db89e
Signature · 7 lines
Catalin _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel