1
2
3
4
5
6
7
8
9
10
11#include <sys/prctl.h>
12#include <asm/hwcap.h>
13#include <stdio.h>
14#include <sys/auxv.h>
15#include <stdint.h>
16#include <stdlib.h>
17
18#ifndef HWCAP_CPUID
19#define HWCAP_CPUID (1 << 11)
20#endif
21
22#define SVE_MAX_QUADS (2048 / 128)
23#define BYTES_PER_QUAD (128 / 8)
24
25#define get_cpu_reg(id) ({ \
26 unsigned long __val; \
27 asm("mrs %0, "#id : "=r" (__val)); \
28 __val; \
29 })
30
31static int do_sve_ioctl_test(void)
32{
33 int i, res, init_vq;
34
35 res = prctl(PR_SVE_GET_VL, 0, 0, 0, 0);
36 if (res < 0) {
37 printf("FAILED to PR_SVE_GET_VL (%d)", res);
38 return -1;
39 }
40 init_vq = res & PR_SVE_VL_LEN_MASK;
41
42 for (i = init_vq; i > 15; i /= 2) {
43 printf("Checking PR_SVE_SET_VL=%d\n", i);
44 res = prctl(PR_SVE_SET_VL, i, 0, 0, 0, 0);
45 if (res < 0) {
46 printf("FAILED to PR_SVE_SET_VL (%d)", res);
47 return -1;
48 }
49 asm("index z0.b, #0, #1\n"
50 ".global __sve_ld_done\n"
51 "__sve_ld_done:\n"
52 "mov z0.b, #0\n"
53 :
54 :
55 : "memory", "z0");
56 }
57 printf("PASS\n");
58 return 0;
59}
60
61int main(int argc, char **argv)
62{
63
64 if (getauxval(AT_HWCAP) & HWCAP_SVE) {
65 return do_sve_ioctl_test();
66 } else {
67 printf("SKIP: no HWCAP_SVE on this system\n");
68 return 0;
69 }
70}
71