Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/testing/selftests/arm64/signal/sve_helpers.c
26292 views
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
}
57
58