|
|
Message-ID: <20261018010912.304405-1-alex@alexrp.com>
Date: Sun, 18 Oct 2026 03:09:12 +0200
From: Alex Rønne Petersen <alex@...xrp.com>
To: musl@...ts.openwall.com
Cc: Alex Rønne Petersen <alex@...xrp.com>,
Rich Felker <dalias@...ifal.cx>
Subject: [PATCH v3] riscv: declare all vector registers as clobbers of syscalls
The kernel intentionally clobbers vector registers (by setting them to
all 1s). musl didn't declare this, so with a compiler targeting the V
extension, this could lead to all sorts of breakage that at first
glance looks like miscompilations.
Because the history of vector clobber support in compilers is messy,
we detect support for them at configure time. If the clobbers we need
are not supported, we instead declare the syscall functions noinline
and rely on the calling convention to mark the registers clobbered.
Co-authored-by: Rich Felker <dalias@...ifal.cx>
---
arch/riscv32/syscall_arch.h | 41 +++++++++++++++++++++++++++++--------
arch/riscv64/syscall_arch.h | 41 +++++++++++++++++++++++++++++--------
configure | 8 ++++++++
3 files changed, 74 insertions(+), 16 deletions(-)
diff --git a/arch/riscv32/syscall_arch.h b/arch/riscv32/syscall_arch.h
index 70d2773f..0e8bc225 100644
--- a/arch/riscv32/syscall_arch.h
+++ b/arch/riscv32/syscall_arch.h
@@ -3,26 +3,47 @@
((union { long long ll; long l[2]; }){ .ll = x }).l[1]
#define __SYSCALL_LL_O(x) __SYSCALL_LL_E((x))
+#ifndef MISSING_RVV_CLOBBERS
+#define SYSCALL_CLOBBERLIST "memory", \
+ "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", "vxsat", "vxrm"
+#else
+#define SYSCALL_CLOBBERLIST "memory"
+#if defined(__riscv_v) || defined(__riscv_vector)
+#define SYSCALL_FUNCTION_ATTRS __attribute__((__noinline__, __unused__))
+#endif
+#endif
+
+#ifndef SYSCALL_FUNCTION_ATTRS
+#define SYSCALL_FUNCTION_ATTRS inline
+#endif
+
#define __asm_syscall(...) \
__asm__ __volatile__ ("ecall\n\t" \
- : "=r"(a0) : __VA_ARGS__ : "memory"); \
+ : "=r"(a0) : __VA_ARGS__ : SYSCALL_CLOBBERLIST); \
return a0; \
-static inline long __syscall0(long n)
+SYSCALL_FUNCTION_ATTRS
+static long __syscall0(long n)
{
register long a7 __asm__("a7") = n;
register long a0 __asm__("a0");
__asm_syscall("r"(a7))
}
-static inline long __syscall1(long n, long a)
+SYSCALL_FUNCTION_ATTRS
+static long __syscall1(long n, long a)
{
register long a7 __asm__("a7") = n;
register long a0 __asm__("a0") = a;
__asm_syscall("r"(a7), "0"(a0))
}
-static inline long __syscall2(long n, long a, long b)
+SYSCALL_FUNCTION_ATTRS
+static long __syscall2(long n, long a, long b)
{
register long a7 __asm__("a7") = n;
register long a0 __asm__("a0") = a;
@@ -30,7 +51,8 @@ static inline long __syscall2(long n, long a, long b)
__asm_syscall("r"(a7), "0"(a0), "r"(a1))
}
-static inline long __syscall3(long n, long a, long b, long c)
+SYSCALL_FUNCTION_ATTRS
+static long __syscall3(long n, long a, long b, long c)
{
register long a7 __asm__("a7") = n;
register long a0 __asm__("a0") = a;
@@ -39,7 +61,8 @@ static inline long __syscall3(long n, long a, long b, long c)
__asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2))
}
-static inline long __syscall4(long n, long a, long b, long c, long d)
+SYSCALL_FUNCTION_ATTRS
+static long __syscall4(long n, long a, long b, long c, long d)
{
register long a7 __asm__("a7") = n;
register long a0 __asm__("a0") = a;
@@ -49,7 +72,8 @@ static inline long __syscall4(long n, long a, long b, long c, long d)
__asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3))
}
-static inline long __syscall5(long n, long a, long b, long c, long d, long e)
+SYSCALL_FUNCTION_ATTRS
+static long __syscall5(long n, long a, long b, long c, long d, long e)
{
register long a7 __asm__("a7") = n;
register long a0 __asm__("a0") = a;
@@ -60,7 +84,8 @@ static inline long __syscall5(long n, long a, long b, long c, long d, long e)
__asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4))
}
-static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)
+SYSCALL_FUNCTION_ATTRS
+static long __syscall6(long n, long a, long b, long c, long d, long e, long f)
{
register long a7 __asm__("a7") = n;
register long a0 __asm__("a0") = a;
diff --git a/arch/riscv64/syscall_arch.h b/arch/riscv64/syscall_arch.h
index 81993fc8..b7158f90 100644
--- a/arch/riscv64/syscall_arch.h
+++ b/arch/riscv64/syscall_arch.h
@@ -1,26 +1,47 @@
#define __SYSCALL_LL_E(x) (x)
#define __SYSCALL_LL_O(x) (x)
+#ifndef MISSING_RVV_CLOBBERS
+#define SYSCALL_CLOBBERLIST "memory", \
+ "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", "vxsat", "vxrm"
+#else
+#define SYSCALL_CLOBBERLIST "memory"
+#if defined(__riscv_v) || defined(__riscv_vector)
+#define SYSCALL_FUNCTION_ATTRS __attribute__((__noinline__, __unused__))
+#endif
+#endif
+
+#ifndef SYSCALL_FUNCTION_ATTRS
+#define SYSCALL_FUNCTION_ATTRS inline
+#endif
+
#define __asm_syscall(...) \
__asm__ __volatile__ ("ecall\n\t" \
- : "=r"(a0) : __VA_ARGS__ : "memory"); \
+ : "=r"(a0) : __VA_ARGS__ : SYSCALL_CLOBBERLIST); \
return a0; \
-static inline long __syscall0(long n)
+SYSCALL_FUNCTION_ATTRS
+static long __syscall0(long n)
{
register long a7 __asm__("a7") = n;
register long a0 __asm__("a0");
__asm_syscall("r"(a7))
}
-static inline long __syscall1(long n, long a)
+SYSCALL_FUNCTION_ATTRS
+static long __syscall1(long n, long a)
{
register long a7 __asm__("a7") = n;
register long a0 __asm__("a0") = a;
__asm_syscall("r"(a7), "0"(a0))
}
-static inline long __syscall2(long n, long a, long b)
+SYSCALL_FUNCTION_ATTRS
+static long __syscall2(long n, long a, long b)
{
register long a7 __asm__("a7") = n;
register long a0 __asm__("a0") = a;
@@ -28,7 +49,8 @@ static inline long __syscall2(long n, long a, long b)
__asm_syscall("r"(a7), "0"(a0), "r"(a1))
}
-static inline long __syscall3(long n, long a, long b, long c)
+SYSCALL_FUNCTION_ATTRS
+static long __syscall3(long n, long a, long b, long c)
{
register long a7 __asm__("a7") = n;
register long a0 __asm__("a0") = a;
@@ -37,7 +59,8 @@ static inline long __syscall3(long n, long a, long b, long c)
__asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2))
}
-static inline long __syscall4(long n, long a, long b, long c, long d)
+SYSCALL_FUNCTION_ATTRS
+static long __syscall4(long n, long a, long b, long c, long d)
{
register long a7 __asm__("a7") = n;
register long a0 __asm__("a0") = a;
@@ -47,7 +70,8 @@ static inline long __syscall4(long n, long a, long b, long c, long d)
__asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3))
}
-static inline long __syscall5(long n, long a, long b, long c, long d, long e)
+SYSCALL_FUNCTION_ATTRS
+static long __syscall5(long n, long a, long b, long c, long d, long e)
{
register long a7 __asm__("a7") = n;
register long a0 __asm__("a0") = a;
@@ -58,7 +82,8 @@ static inline long __syscall5(long n, long a, long b, long c, long d, long e)
__asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4))
}
-static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)
+SYSCALL_FUNCTION_ATTRS
+static long __syscall6(long n, long a, long b, long c, long d, long e, long f)
{
register long a7 __asm__("a7") = n;
register long a0 __asm__("a0") = a;
diff --git a/configure b/configure
index bc9fbe48..e5377589 100755
--- a/configure
+++ b/configure
@@ -731,6 +731,14 @@ fi
if test "$ARCH" = "riscv64" -o "$ARCH" = "riscv32" ; then
trycppif __riscv_float_abi_soft "$t" && SUBARCH=${SUBARCH}-sf
trycppif __riscv_float_abi_single "$t" && SUBARCH=${SUBARCH}-sp
+printf "checking whether compiler supports vector clobbers... "
+echo 'void f(void) { __asm__("":::"v0","vl","vtype","vxsat","vxrm","memory"); }' > "$tmpc"
+if $CC $CFLAGS_C99FSE $CPPFLAGS $CFLAGS -c -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
+printf "yes\n"
+else
+printf "no\n"
+CFLAGS_AUTO="$CFLAGS_AUTO -DMISSING_RVV_CLOBBERS"
+fi
fi
if test "$ARCH" = "sh" ; then
--
2.53.0
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.