Skip to content

Commit 2ef52ca

Browse files
committed
Merge branch 'for-next/selftests' into for-next/core
* for-next/selftests: kselftest/arm64: Fix build warnings for ptrace kselftest/arm64: Actually test SME vector length changes via sigreturn kselftest/arm64: signal: fix/refactor SVE vector length enumeration
2 parents 982a847 + d736d4f commit 2ef52ca

File tree

11 files changed

+141
-190
lines changed

11 files changed

+141
-190
lines changed

tools/testing/selftests/arm64/abi/ptrace.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,10 +163,10 @@ static void test_hw_debug(pid_t child, int type, const char *type_name)
163163
static int do_child(void)
164164
{
165165
if (ptrace(PTRACE_TRACEME, -1, NULL, NULL))
166-
ksft_exit_fail_msg("PTRACE_TRACEME", strerror(errno));
166+
ksft_exit_fail_perror("PTRACE_TRACEME");
167167

168168
if (raise(SIGSTOP))
169-
ksft_exit_fail_msg("raise(SIGSTOP)", strerror(errno));
169+
ksft_exit_fail_perror("raise(SIGSTOP)");
170170

171171
return EXIT_SUCCESS;
172172
}

tools/testing/selftests/arm64/signal/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff 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
2525
COMMON_SOURCES := test_signals.c test_signals_utils.c testcases/testcases.c \
26-
signals.S
26+
signals.S sve_helpers.c
2727
COMMON_HEADERS := test_signals.h test_signals_utils.h testcases/testcases.h
2828

2929
.SECONDEXPANSION:
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
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+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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

tools/testing/selftests/arm64/signal/testcases/fake_sigreturn_sme_change_vl.c

Lines changed: 15 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,75 +6,59 @@
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

1618
struct fake_sigframe sf;
17-
static unsigned int vls[SVE_VQ_MAX];
18-
unsigned int nvls = 0;
1919

2020
static 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

4933
static int fake_sigreturn_ssve_change_vl(struct tdescr *td,
5034
siginfo_t *si, ucontext_t *uc)
5135
{
5236
size_t resv_sz, offset;
5337
struct _aarch64_ctx *head = GET_SF_RESV_HEAD(sf);
54-
struct sve_context *sve;
38+
struct za_context *za;
5539

5640
/* Get a signal context with a SME ZA frame in it */
5741
if (!get_current_context(td, &sf.uc, sizeof(sf.uc)))
5842
return 1;
5943

6044
resv_sz = GET_SF_RESV_SIZE(sf);
61-
head = get_header(head, SVE_MAGIC, resv_sz, &offset);
45+
head = get_header(head, ZA_MAGIC, resv_sz, &offset);
6246
if (!head) {
63-
fprintf(stderr, "No SVE context\n");
47+
fprintf(stderr, "No ZA context\n");
6448
return 1;
6549
}
6650

67-
if (head->size != sizeof(struct sve_context)) {
51+
if (head->size != sizeof(struct za_context)) {
6852
fprintf(stderr, "Register data present, aborting\n");
6953
return 1;
7054
}
7155

72-
sve = (struct sve_context *)head;
56+
za = (struct za_context *)head;
7357

7458
/* No changes are supported; init left us at minimum VL so go to max */
7559
fprintf(stderr, "Attempting to change VL from %d to %d\n",
76-
sve->vl, vls[0]);
77-
sve->vl = vls[0];
60+
za->vl, vls[0]);
61+
za->vl = vls[0];
7862

7963
fake_sigreturn(&sf, sizeof(sf), 0);
8064

tools/testing/selftests/arm64/signal/testcases/fake_sigreturn_sve_change_vl.c

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,40 +12,22 @@
1212
#include <sys/prctl.h>
1313

1414
#include "test_signals_utils.h"
15+
#include "sve_helpers.h"
1516
#include "testcases.h"
1617

1718
struct fake_sigframe sf;
18-
static unsigned int vls[SVE_VQ_MAX];
19-
unsigned int nvls = 0;
2019

2120
static 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

5133
static int fake_sigreturn_sve_change_vl(struct tdescr *td,

tools/testing/selftests/arm64/signal/testcases/ssve_regs.c

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,51 +6,31 @@
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

1618
static 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

2323
static 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

5636
static void setup_ssve_regs(void)

tools/testing/selftests/arm64/signal/testcases/ssve_za_regs.c

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,51 +6,31 @@
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

1618
static 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

2323
static 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

5636
static void setup_regs(void)

0 commit comments

Comments
 (0)