File Index
Files and directories
Sign in
FILE

sve_helpers.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/arm64/signal/sve_helpers.c C
 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
13unsigned int vls[SVE_VQ_MAX];
14unsigned int nvls;
15
16int 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}
~/ Read-only file preview.