1#!/usr/bin/python3
2# Set Scalable Vector Length test helper
3# Copyright (C) 2021 Free Software Foundation, Inc.
4# This file is part of the GNU C Library.
5#
6# The GNU C Library is free software; you can redistribute it and/or
7# modify it under the terms of the GNU Lesser General Public
8# License as published by the Free Software Foundation; either
9# version 2.1 of the License, or (at your option) any later version.
10#
11# The GNU C Library is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14# Lesser General Public License for more details.
15#
16# You should have received a copy of the GNU Lesser General Public
17# License along with the GNU C Library; if not, see
18# <https://www.gnu.org/licenses/>.
19"""Set Scalable Vector Length test helper.
20
21Set Scalable Vector Length for child process.
22
23examples:
24
25~/build$ make check subdirs=string \
26test-wrapper='~/glibc/sysdeps/unix/sysv/linux/aarch64/vltest.py 16'
27
28~/build$ ~/glibc/sysdeps/unix/sysv/linux/aarch64/vltest.py 16 \
29make test t=string/test-memcpy
30
31~/build$ ~/glibc/sysdeps/unix/sysv/linux/aarch64/vltest.py 32 \
32./debugglibc.sh string/test-memmove
33
34~/build$ ~/glibc/sysdeps/unix/sysv/linux/aarch64/vltest.py 64 \
35./testrun.sh string/test-memset
36"""
37import argparse
38from ctypes import cdll, CDLL
39import os
40import sys
41
42EXIT_SUCCESS = 0
43EXIT_FAILURE = 1
44EXIT_UNSUPPORTED = 77
45
46AT_HWCAP = 16
47HWCAP_SVE = (1 << 22)
48
49PR_SVE_GET_VL = 51
50PR_SVE_SET_VL = 50
51PR_SVE_SET_VL_ONEXEC = (1 << 18)
52PR_SVE_VL_INHERIT = (1 << 17)
53PR_SVE_VL_LEN_MASK = 0xffff
54
55def main(args):
56    libc = CDLL("libc.so.6")
57    if not libc.getauxval(AT_HWCAP) & HWCAP_SVE:
58        print("CPU doesn't support SVE")
59        sys.exit(EXIT_UNSUPPORTED)
60
61    libc.prctl(PR_SVE_SET_VL,
62               args.vl[0] | PR_SVE_SET_VL_ONEXEC | PR_SVE_VL_INHERIT)
63    os.execvp(args.args[0], args.args)
64    print("exec system call failure")
65    sys.exit(EXIT_FAILURE)
66
67if __name__ == '__main__':
68    parser = argparse.ArgumentParser(description=
69            "Set Scalable Vector Length test helper",
70            formatter_class=argparse.ArgumentDefaultsHelpFormatter)
71
72    # positional argument
73    parser.add_argument("vl", nargs=1, type=int,
74                        choices=range(16, 257, 16),
75                        help=('vector length '\
76                              'which is multiples of 16 from 16 to 256'))
77    # remainDer arguments
78    parser.add_argument('args', nargs=argparse.REMAINDER,
79                        help=('args '\
80                              'which is passed to child process'))
81    args = parser.parse_args()
82    main(args)
83