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)
23
23
# Common test-unit targets to build common-layout test-cases executables
24
24
# Needs secondary expansion to properly include the testcase c-file in pre-reqs
25
25
COMMON_SOURCES := test_signals.c test_signals_utils.c testcases/testcases.c \
26
- signals.S
26
+ signals.S sve_helpers.c
27
27
COMMON_HEADERS := test_signals.h test_signals_utils.h testcases/testcases.h
28
28
29
29
.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 6
6
* handler, this is not supported and is expected to segfault.
7
7
*/
8
8
9
+ #include <kselftest.h>
9
10
#include <signal.h>
10
11
#include <ucontext.h>
11
12
#include <sys/prctl.h>
12
13
13
14
#include "test_signals_utils.h"
15
+ #include "sve_helpers.h"
14
16
#include "testcases.h"
15
17
16
18
struct fake_sigframe sf ;
17
- static unsigned int vls [SVE_VQ_MAX ];
18
- unsigned int nvls = 0 ;
19
19
20
20
static bool sme_get_vls (struct tdescr * td )
21
21
{
22
- int vq , vl ;
22
+ int res = sve_fill_vls ( VLS_USE_SME , 2 ) ;
23
23
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;
31
26
32
- vl &= PR_SME_VL_LEN_MASK ;
27
+ if (res == KSFT_SKIP )
28
+ td -> result = KSFT_SKIP ;
33
29
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;
47
31
}
48
32
49
33
static int fake_sigreturn_ssve_change_vl (struct tdescr * td ,
Original file line number Diff line number Diff line change 12
12
#include <sys/prctl.h>
13
13
14
14
#include "test_signals_utils.h"
15
+ #include "sve_helpers.h"
15
16
#include "testcases.h"
16
17
17
18
struct fake_sigframe sf ;
18
- static unsigned int vls [SVE_VQ_MAX ];
19
- unsigned int nvls = 0 ;
20
19
21
20
static bool sve_get_vls (struct tdescr * td )
22
21
{
23
- int vq , vl ;
22
+ int res = sve_fill_vls ( VLS_USE_SVE , 2 ) ;
24
23
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;
32
26
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 )
44
28
td -> result = KSFT_SKIP ;
45
- return false;
46
- }
47
29
48
- return true ;
30
+ return false ;
49
31
}
50
32
51
33
static int fake_sigreturn_sve_change_vl (struct tdescr * td ,
Original file line number Diff line number Diff line change 6
6
* set up as expected.
7
7
*/
8
8
9
+ #include <kselftest.h>
9
10
#include <signal.h>
10
11
#include <ucontext.h>
11
12
#include <sys/prctl.h>
12
13
13
14
#include "test_signals_utils.h"
15
+ #include "sve_helpers.h"
14
16
#include "testcases.h"
15
17
16
18
static union {
17
19
ucontext_t uc ;
18
20
char buf [1024 * 64 ];
19
21
} context ;
20
- static unsigned int vls [SVE_VQ_MAX ];
21
- unsigned int nvls = 0 ;
22
22
23
23
static bool sme_get_vls (struct tdescr * td )
24
24
{
25
- int vq , vl ;
25
+ int res = sve_fill_vls ( VLS_USE_SME , 1 ) ;
26
26
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;
40
29
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 ;
52
32
53
- return true ;
33
+ return false ;
54
34
}
55
35
56
36
static void setup_ssve_regs (void )
Original file line number Diff line number Diff line change 6
6
* signal frames is set up as expected when enabled simultaneously.
7
7
*/
8
8
9
+ #include <kselftest.h>
9
10
#include <signal.h>
10
11
#include <ucontext.h>
11
12
#include <sys/prctl.h>
12
13
13
14
#include "test_signals_utils.h"
15
+ #include "sve_helpers.h"
14
16
#include "testcases.h"
15
17
16
18
static union {
17
19
ucontext_t uc ;
18
20
char buf [1024 * 128 ];
19
21
} context ;
20
- static unsigned int vls [SVE_VQ_MAX ];
21
- unsigned int nvls = 0 ;
22
22
23
23
static bool sme_get_vls (struct tdescr * td )
24
24
{
25
- int vq , vl ;
25
+ int res = sve_fill_vls ( VLS_USE_SME , 1 ) ;
26
26
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;
40
29
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 ;
52
32
53
- return true ;
33
+ return false ;
54
34
}
55
35
56
36
static void setup_regs (void )
Original file line number Diff line number Diff line change 6
6
* expected.
7
7
*/
8
8
9
+ #include <kselftest.h>
9
10
#include <signal.h>
10
11
#include <ucontext.h>
11
12
#include <sys/prctl.h>
12
13
13
14
#include "test_signals_utils.h"
15
+ #include "sve_helpers.h"
14
16
#include "testcases.h"
15
17
16
18
static union {
17
19
ucontext_t uc ;
18
20
char buf [1024 * 64 ];
19
21
} context ;
20
- static unsigned int vls [SVE_VQ_MAX ];
21
- unsigned int nvls = 0 ;
22
22
23
23
static bool sve_get_vls (struct tdescr * td )
24
24
{
25
- int vq , vl ;
25
+ int res = sve_fill_vls ( VLS_USE_SVE , 1 ) ;
26
26
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;
39
29
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 ;
48
32
49
- return true ;
33
+ return false ;
50
34
}
51
35
52
36
static void setup_sve_regs (void )
You can’t perform that action at this time.
0 commit comments