From: Peter Bergner Date: Wed, 3 Sep 2025 19:26:03 +0000 (-0500) Subject: riscv: Add vector registers to __SYSCALL_CLOBBERS X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=47975914fb106b83c42bc0baf6435a0944a23d30;p=thirdparty%2Fglibc.git riscv: Add vector registers to __SYSCALL_CLOBBERS The Linux kernel ABI specifies that the vector registers are not preserved across system calls, but the __SYSCALL_CLOBBERS macro doesn't mention them. This could possibly lead to compilers trying to keep data in the vector registers across the syscall leading to corruption. Add the vector registers to __SYSCALL_CLOBBERS when the vector extension is enabled. If the vector extension is enabled, then require GCC 15 or later and RVV 1.0 or later. Fixes: 36960f0c76 ("RISC-V: Linux Syscall Interface") Signed-off-by: Peter Bergner --- diff --git a/sysdeps/riscv/preconfigure b/sysdeps/riscv/preconfigure index a5de5ccb7d..a96cd0d7f8 100644 --- a/sysdeps/riscv/preconfigure +++ b/sysdeps/riscv/preconfigure @@ -7,6 +7,7 @@ riscv*) flen=`$CC $CFLAGS $CPPFLAGS -E -dM -xc /dev/null | sed -n 's/^#define __riscv_flen \(.*\)/\1/p'` float_abi=`$CC $CFLAGS $CPPFLAGS -E -dM -xc /dev/null | sed -n 's/^#define __riscv_float_abi_\([^ ]*\) .*/\1/p'` atomic=`$CC $CFLAGS $CPPFLAGS -E -dM -xc /dev/null | grep '#define __riscv_atomic' | cut -d' ' -f2` + vector=`$CC $CFLAGS $CPPFLAGS -E -dM -xc /dev/null | sed -n 's/^#define __riscv_v \(.*\)/\1/p'` case "$xlen" in 64 | 32) @@ -55,6 +56,12 @@ riscv*) ;; esac + if test -n "$vector"; then + version=`$CC $CFLAGS $CPPFLAGS -E -dM -xc /dev/null | sed -n 's/^#define __GNUC__ \(.*\)/\1/p'` + test $version -lt 15 && as_fn_error 1 "glibc requires GCC 15 or later for the V extension" "$LINENO" 5 + test $vector -lt "1000000" && as_fn_error 1 "glibc requires at least RVV 1.0 for the V extension" "$LINENO" 5 + fi + base_machine=riscv machine=riscv/rv$xlen/$float_machine diff --git a/sysdeps/riscv/preconfigure.ac b/sysdeps/riscv/preconfigure.ac index a5c30e0dbf..f95ffe83fb 100644 --- a/sysdeps/riscv/preconfigure.ac +++ b/sysdeps/riscv/preconfigure.ac @@ -7,6 +7,7 @@ riscv*) flen=`$CC $CFLAGS $CPPFLAGS -E -dM -xc /dev/null | sed -n 's/^#define __riscv_flen \(.*\)/\1/p'` float_abi=`$CC $CFLAGS $CPPFLAGS -E -dM -xc /dev/null | sed -n 's/^#define __riscv_float_abi_\([^ ]*\) .*/\1/p'` atomic=`$CC $CFLAGS $CPPFLAGS -E -dM -xc /dev/null | grep '#define __riscv_atomic' | cut -d' ' -f2` + vector=`$CC $CFLAGS $CPPFLAGS -E -dM -xc /dev/null | sed -n 's/^#define __riscv_v \(.*\)/\1/p'` case "$xlen" in 64 | 32) @@ -55,6 +56,12 @@ riscv*) ;; esac + if test -n "$vector"; then + version=`$CC $CFLAGS $CPPFLAGS -E -dM -xc /dev/null | sed -n 's/^#define __GNUC__ \(.*\)/\1/p'` + test $version -lt 15 && AC_MSG_ERROR([glibc requires GCC 15 or later for the V extension], [1]) + test $vector -lt "1000000" && AC_MSG_ERROR([glibc requires at least RVV 1.0 for the V extension], [1]) + fi + base_machine=riscv machine=riscv/rv$xlen/$float_machine diff --git a/sysdeps/unix/sysv/linux/riscv/sysdep.h b/sysdeps/unix/sysv/linux/riscv/sysdep.h index 05e0e0523d..7f0eb07045 100644 --- a/sysdeps/unix/sysv/linux/riscv/sysdep.h +++ b/sysdeps/unix/sysv/linux/riscv/sysdep.h @@ -355,7 +355,14 @@ _sys_result; \ }) +#ifdef __riscv_v +# define __SYSCALL_CLOBBERS "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", \ + "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", \ + "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", \ + "v30", "v31", "vl", "vtype", "vxrm", "vxsat", "memory" +#else # define __SYSCALL_CLOBBERS "memory" +#endif extern long int __syscall_error (long int neg_errno);