File tree Expand file tree Collapse file tree 10 files changed +132
-181
lines changed
tools/testing/selftests/arm64/signal Expand file tree Collapse file tree 10 files changed +132
-181
lines changed Original file line number Diff line number Diff line change @@ -23,7 +23,7 @@ $(TEST_GEN_PROGS): $(PROGS)
2323# Common test-unit targets to build common-layout test-cases executables
2424# Needs secondary expansion to properly include the testcase c-file in pre-reqs
2525COMMON_SOURCES := test_signals.c test_signals_utils.c testcases/testcases.c \
26- signals.S
26+ signals.S sve_helpers.c
2727COMMON_HEADERS := test_signals.h test_signals_utils.h testcases/testcases.h
2828
2929.SECONDEXPANSION :
Original file line number Diff line number Diff line change 1+ // SPDX-License-Identifier: GPL-2.0
2+ /*
3+ * Copyright (C) 2024 ARM Limited
4+ *
5+ * Common helper functions for SVE and SME functionality.
6+ */
7+
8+ #include <stdbool.h>
9+ #include <kselftest.h>
10+ #include <asm/sigcontext.h>
11+ #include <sys/prctl.h>
12+
13+ unsigned int vls [SVE_VQ_MAX ];
14+ unsigned int nvls ;
15+
16+ int sve_fill_vls (bool use_sme , int min_vls )
17+ {
18+ int vq , vl ;
19+ int pr_set_vl = use_sme ? PR_SME_SET_VL : PR_SVE_SET_VL ;
20+ int len_mask = use_sme ? PR_SME_VL_LEN_MASK : PR_SVE_VL_LEN_MASK ;
21+
22+ /*
23+ * Enumerate up to SVE_VQ_MAX vector lengths
24+ */
25+ for (vq = SVE_VQ_MAX ; vq > 0 ; -- vq ) {
26+ vl = prctl (pr_set_vl , vq * 16 );
27+ if (vl == -1 )
28+ return KSFT_FAIL ;
29+
30+ vl &= len_mask ;
31+
32+ /*
33+ * Unlike SVE, SME does not require the minimum vector length
34+ * to be implemented, or the VLs to be consecutive, so any call
35+ * to the prctl might return the single implemented VL, which
36+ * might be larger than 16. So to avoid this loop never
37+ * terminating, bail out here when we find a higher VL than
38+ * we asked for.
39+ * See the ARM ARM, DDI 0487K.a, B1.4.2: I_QQRNR and I_NWYBP.
40+ */
41+ if (vq < sve_vq_from_vl (vl ))
42+ break ;
43+
44+ /* Skip missing VLs */
45+ vq = sve_vq_from_vl (vl );
46+
47+ vls [nvls ++ ] = vl ;
48+ }
49+
50+ if (nvls < min_vls ) {
51+ fprintf (stderr , "Only %d VL supported\n" , nvls );
52+ return KSFT_SKIP ;
53+ }
54+
55+ return KSFT_PASS ;
56+ }
Original file line number Diff line number Diff line change 1+ /* SPDX-License-Identifier: GPL-2.0 */
2+ /*
3+ * Copyright (C) 2024 ARM Limited
4+ *
5+ * Common helper functions for SVE and SME functionality.
6+ */
7+
8+ #ifndef __SVE_HELPERS_H__
9+ #define __SVE_HELPERS_H__
10+
11+ #include <stdbool.h>
12+
13+ #define VLS_USE_SVE false
14+ #define VLS_USE_SME true
15+
16+ extern unsigned int vls [];
17+ extern unsigned int nvls ;
18+
19+ int sve_fill_vls (bool use_sme , int min_vls );
20+
21+ #endif
Original file line number Diff line number Diff line change 66 * handler, this is not supported and is expected to segfault.
77 */
88
9+ #include <kselftest.h>
910#include <signal.h>
1011#include <ucontext.h>
1112#include <sys/prctl.h>
1213
1314#include "test_signals_utils.h"
15+ #include "sve_helpers.h"
1416#include "testcases.h"
1517
1618struct fake_sigframe sf ;
17- static unsigned int vls [SVE_VQ_MAX ];
18- unsigned int nvls = 0 ;
1919
2020static bool sme_get_vls (struct tdescr * td )
2121{
22- int vq , vl ;
22+ int res = sve_fill_vls ( VLS_USE_SME , 2 ) ;
2323
24- /*
25- * Enumerate up to SVE_VQ_MAX vector lengths
26- */
27- for (vq = SVE_VQ_MAX ; vq > 0 ; -- vq ) {
28- vl = prctl (PR_SVE_SET_VL , vq * 16 );
29- if (vl == -1 )
30- return false;
24+ if (!res )
25+ return true;
3126
32- vl &= PR_SME_VL_LEN_MASK ;
27+ if (res == KSFT_SKIP )
28+ td -> result = KSFT_SKIP ;
3329
34- /* Skip missing VLs */
35- vq = sve_vq_from_vl (vl );
36-
37- vls [nvls ++ ] = vl ;
38- }
39-
40- /* We need at least two VLs */
41- if (nvls < 2 ) {
42- fprintf (stderr , "Only %d VL supported\n" , nvls );
43- return false;
44- }
45-
46- return true;
30+ return false;
4731}
4832
4933static int fake_sigreturn_ssve_change_vl (struct tdescr * td ,
Original file line number Diff line number Diff line change 1212#include <sys/prctl.h>
1313
1414#include "test_signals_utils.h"
15+ #include "sve_helpers.h"
1516#include "testcases.h"
1617
1718struct fake_sigframe sf ;
18- static unsigned int vls [SVE_VQ_MAX ];
19- unsigned int nvls = 0 ;
2019
2120static bool sve_get_vls (struct tdescr * td )
2221{
23- int vq , vl ;
22+ int res = sve_fill_vls ( VLS_USE_SVE , 2 ) ;
2423
25- /*
26- * Enumerate up to SVE_VQ_MAX vector lengths
27- */
28- for (vq = SVE_VQ_MAX ; vq > 0 ; -- vq ) {
29- vl = prctl (PR_SVE_SET_VL , vq * 16 );
30- if (vl == -1 )
31- return false;
24+ if (!res )
25+ return true;
3226
33- vl &= PR_SVE_VL_LEN_MASK ;
34-
35- /* Skip missing VLs */
36- vq = sve_vq_from_vl (vl );
37-
38- vls [nvls ++ ] = vl ;
39- }
40-
41- /* We need at least two VLs */
42- if (nvls < 2 ) {
43- fprintf (stderr , "Only %d VL supported\n" , nvls );
27+ if (res == KSFT_SKIP )
4428 td -> result = KSFT_SKIP ;
45- return false;
46- }
4729
48- return true ;
30+ return false ;
4931}
5032
5133static int fake_sigreturn_sve_change_vl (struct tdescr * td ,
Original file line number Diff line number Diff line change 66 * set up as expected.
77 */
88
9+ #include <kselftest.h>
910#include <signal.h>
1011#include <ucontext.h>
1112#include <sys/prctl.h>
1213
1314#include "test_signals_utils.h"
15+ #include "sve_helpers.h"
1416#include "testcases.h"
1517
1618static union {
1719 ucontext_t uc ;
1820 char buf [1024 * 64 ];
1921} context ;
20- static unsigned int vls [SVE_VQ_MAX ];
21- unsigned int nvls = 0 ;
2222
2323static bool sme_get_vls (struct tdescr * td )
2424{
25- int vq , vl ;
25+ int res = sve_fill_vls ( VLS_USE_SME , 1 ) ;
2626
27- /*
28- * Enumerate up to SVE_VQ_MAX vector lengths
29- */
30- for (vq = SVE_VQ_MAX ; vq > 0 ; -- vq ) {
31- vl = prctl (PR_SME_SET_VL , vq * 16 );
32- if (vl == -1 )
33- return false;
34-
35- vl &= PR_SME_VL_LEN_MASK ;
36-
37- /* Did we find the lowest supported VL? */
38- if (vq < sve_vq_from_vl (vl ))
39- break ;
27+ if (!res )
28+ return true;
4029
41- /* Skip missing VLs */
42- vq = sve_vq_from_vl (vl );
43-
44- vls [nvls ++ ] = vl ;
45- }
46-
47- /* We need at least one VL */
48- if (nvls < 1 ) {
49- fprintf (stderr , "Only %d VL supported\n" , nvls );
50- return false;
51- }
30+ if (res == KSFT_SKIP )
31+ td -> result = KSFT_SKIP ;
5232
53- return true ;
33+ return false ;
5434}
5535
5636static void setup_ssve_regs (void )
Original file line number Diff line number Diff line change 66 * signal frames is set up as expected when enabled simultaneously.
77 */
88
9+ #include <kselftest.h>
910#include <signal.h>
1011#include <ucontext.h>
1112#include <sys/prctl.h>
1213
1314#include "test_signals_utils.h"
15+ #include "sve_helpers.h"
1416#include "testcases.h"
1517
1618static union {
1719 ucontext_t uc ;
1820 char buf [1024 * 128 ];
1921} context ;
20- static unsigned int vls [SVE_VQ_MAX ];
21- unsigned int nvls = 0 ;
2222
2323static bool sme_get_vls (struct tdescr * td )
2424{
25- int vq , vl ;
25+ int res = sve_fill_vls ( VLS_USE_SME , 1 ) ;
2626
27- /*
28- * Enumerate up to SVE_VQ_MAX vector lengths
29- */
30- for (vq = SVE_VQ_MAX ; vq > 0 ; -- vq ) {
31- vl = prctl (PR_SME_SET_VL , vq * 16 );
32- if (vl == -1 )
33- return false;
34-
35- vl &= PR_SME_VL_LEN_MASK ;
36-
37- /* Did we find the lowest supported VL? */
38- if (vq < sve_vq_from_vl (vl ))
39- break ;
27+ if (!res )
28+ return true;
4029
41- /* Skip missing VLs */
42- vq = sve_vq_from_vl (vl );
43-
44- vls [nvls ++ ] = vl ;
45- }
46-
47- /* We need at least one VL */
48- if (nvls < 1 ) {
49- fprintf (stderr , "Only %d VL supported\n" , nvls );
50- return false;
51- }
30+ if (res == KSFT_SKIP )
31+ td -> result = KSFT_SKIP ;
5232
53- return true ;
33+ return false ;
5434}
5535
5636static void setup_regs (void )
Original file line number Diff line number Diff line change 66 * expected.
77 */
88
9+ #include <kselftest.h>
910#include <signal.h>
1011#include <ucontext.h>
1112#include <sys/prctl.h>
1213
1314#include "test_signals_utils.h"
15+ #include "sve_helpers.h"
1416#include "testcases.h"
1517
1618static union {
1719 ucontext_t uc ;
1820 char buf [1024 * 64 ];
1921} context ;
20- static unsigned int vls [SVE_VQ_MAX ];
21- unsigned int nvls = 0 ;
2222
2323static bool sve_get_vls (struct tdescr * td )
2424{
25- int vq , vl ;
25+ int res = sve_fill_vls ( VLS_USE_SVE , 1 ) ;
2626
27- /*
28- * Enumerate up to SVE_VQ_MAX vector lengths
29- */
30- for (vq = SVE_VQ_MAX ; vq > 0 ; -- vq ) {
31- vl = prctl (PR_SVE_SET_VL , vq * 16 );
32- if (vl == -1 )
33- return false;
34-
35- vl &= PR_SVE_VL_LEN_MASK ;
36-
37- /* Skip missing VLs */
38- vq = sve_vq_from_vl (vl );
27+ if (!res )
28+ return true;
3929
40- vls [nvls ++ ] = vl ;
41- }
42-
43- /* We need at least one VL */
44- if (nvls < 1 ) {
45- fprintf (stderr , "Only %d VL supported\n" , nvls );
46- return false;
47- }
30+ if (res == KSFT_SKIP )
31+ td -> result = KSFT_SKIP ;
4832
49- return true ;
33+ return false ;
5034}
5135
5236static void setup_sve_regs (void )
You can’t perform that action at this time.
0 commit comments