1 /* 2 * SVE ioctls tests 3 * 4 * Test the SVE width setting ioctls work and provide a base for 5 * testing the gdbstub. 6 * 7 * Copyright (c) 2019 Linaro Ltd 8 * 9 * SPDX-License-Identifier: GPL-2.0-or-later 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 31 static 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 : /* no outputs kept */ 54 : /* no inputs */ 55 : "memory", "z0"); 56 } 57 printf("PASS\n"); 58 return 0; 59 } 60 61 int main(int argc, char **argv) 62 { 63 /* we also need to probe for the ioctl support */ 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