Skip to content

Commit 5262b21

Browse files
brooniectmarinas
authored andcommitted
kselftest/arm64: signal: Add test case for SVE register state in signals
Currently this doesn't actually verify that the register contents do the right thing, it just verifes that a SVE context with appropriate size appears. Signed-off-by: Mark Brown <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Catalin Marinas <[email protected]>
1 parent d25ac50 commit 5262b21

File tree

1 file changed

+126
-0
lines changed
  • tools/testing/selftests/arm64/signal/testcases

1 file changed

+126
-0
lines changed
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* Copyright (C) 2021 ARM Limited
4+
*
5+
* Verify that the SVE register context in signal frames is set up as
6+
* expected.
7+
*/
8+
9+
#include <signal.h>
10+
#include <ucontext.h>
11+
#include <sys/prctl.h>
12+
13+
#include "test_signals_utils.h"
14+
#include "testcases.h"
15+
16+
struct fake_sigframe sf;
17+
static unsigned int vls[SVE_VQ_MAX];
18+
unsigned int nvls = 0;
19+
20+
static bool sve_get_vls(struct tdescr *td)
21+
{
22+
int vq, vl;
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;
31+
32+
vl &= PR_SVE_VL_LEN_MASK;
33+
34+
/* Skip missing VLs */
35+
vq = sve_vq_from_vl(vl);
36+
37+
vls[nvls++] = vl;
38+
}
39+
40+
/* We need at least one VL */
41+
if (nvls < 1) {
42+
fprintf(stderr, "Only %d VL supported\n", nvls);
43+
return false;
44+
}
45+
46+
return true;
47+
}
48+
49+
static void setup_sve_regs(void)
50+
{
51+
/* RDVL x16, #1 so we should have SVE regs; real data is TODO */
52+
asm volatile(".inst 0x04bf5030" : : : "x16" );
53+
}
54+
55+
static int do_one_sve_vl(struct tdescr *td, siginfo_t *si, ucontext_t *uc,
56+
unsigned int vl)
57+
{
58+
size_t resv_sz, offset;
59+
struct _aarch64_ctx *head = GET_SF_RESV_HEAD(sf);
60+
struct sve_context *sve;
61+
62+
fprintf(stderr, "Testing VL %d\n", vl);
63+
64+
if (prctl(PR_SVE_SET_VL, vl) == -1) {
65+
fprintf(stderr, "Failed to set VL\n");
66+
return 1;
67+
}
68+
69+
/*
70+
* Get a signal context which should have a SVE frame and registers
71+
* in it.
72+
*/
73+
setup_sve_regs();
74+
if (!get_current_context(td, &sf.uc))
75+
return 1;
76+
77+
resv_sz = GET_SF_RESV_SIZE(sf);
78+
head = get_header(head, SVE_MAGIC, resv_sz, &offset);
79+
if (!head) {
80+
fprintf(stderr, "No SVE context\n");
81+
return 1;
82+
}
83+
84+
sve = (struct sve_context *)head;
85+
if (sve->vl != vl) {
86+
fprintf(stderr, "Got VL %d, expected %d\n", sve->vl, vl);
87+
return 1;
88+
}
89+
90+
/* The actual size validation is done in get_current_context() */
91+
fprintf(stderr, "Got expected size %u and VL %d\n",
92+
head->size, sve->vl);
93+
94+
return 0;
95+
}
96+
97+
static int sve_regs(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
98+
{
99+
int i;
100+
101+
for (i = 0; i < nvls; i++) {
102+
/*
103+
* TODO: the signal test helpers can't currently cope
104+
* with signal frames bigger than struct sigcontext,
105+
* skip VLs that will trigger that.
106+
*/
107+
if (vls[i] > 64)
108+
continue;
109+
110+
if (do_one_sve_vl(td, si, uc, vls[i]))
111+
return 1;
112+
}
113+
114+
td->pass = 1;
115+
116+
return 0;
117+
}
118+
119+
struct tdescr tde = {
120+
.name = "SVE registers",
121+
.descr = "Check that we get the right SVE registers reported",
122+
.feats_required = FEAT_SVE,
123+
.timeout = 3,
124+
.init = sve_get_vls,
125+
.run = sve_regs,
126+
};

0 commit comments

Comments
 (0)