[PATCH v2] RISC-V: Add vector registers to __SYSCALL_CLOBBERS

Peter Bergner bergner@tenstorrent.com
Wed Sep 3 22:52:44 GMT 2025


Here's an updated patch that takes Palmer's suggestions into account.

Differences from v1:
* Added vl, vtype, vxrm, and vxsat registers.
* Added preconfigure fragment to disallow GCC 14 or earlier when
  vector is enabled and only allow RVV 1.0 or later.

The vl, vtype, vxrm, and vxsat registers all exist in GCC 15 (vxsat was
added in GCC 15), so we don't need any extra preconfigure checks that
they exist in old compilers, since we're only allowing the vector
extension for GCC 15 and later. 

This was tested with GCC 14 and verified that the preconfigure check
flags the error.  I then built using GCC 15 with -march=rv64gcv0p7
and again verified that the preconfigure check flags an error.
I then built with GCC 15 using -march=rv64gc & -march=rv64gcv and they
both showed no build or testsuite regressions to the base build.

Ok for trunk and backports after some burn-in time on trunk?

Peter



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 <bergner@tenstorrent.com>
---
 sysdeps/riscv/preconfigure             | 7 +++++++
 sysdeps/riscv/preconfigure.ac          | 7 +++++++
 sysdeps/unix/sysv/linux/riscv/sysdep.h | 7 +++++++
 3 files changed, 21 insertions(+)

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);
 
-- 
2.43.0



More information about the Libc-alpha mailing list