|
|
Message-ID: <20261004035159.GG23438@brightrain.aerifal.cx>
Date: Sat, 3 Oct 2026 23:51:59 -0400
From: Rich Felker <dalias@...c.org>
To: Alex Rønne Petersen <alex@...xrp.com>
Cc: musl@...ts.openwall.com
Subject: Re: [PATCH] riscv: declare all vector registers as clobbers
of syscalls
On Sun, Oct 04, 2026 at 05:35:36AM +0200, Alex Rønne Petersen wrote:
> On Sun, Oct 4, 2026, at 05:04, Rich Felker wrote:
> > On Sun, Oct 04, 2026 at 04:48:52AM +0200, Alex Rønne Petersen wrote:
> >> 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.
> >> ---
> >> arch/riscv32/syscall_arch.h | 9 ++++++++-
> >> arch/riscv64/syscall_arch.h | 9 ++++++++-
> >> 2 files changed, 16 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/arch/riscv32/syscall_arch.h b/arch/riscv32/syscall_arch.h
> >> index 70d2773f..9149cb9e 100644
> >> --- a/arch/riscv32/syscall_arch.h
> >> +++ b/arch/riscv32/syscall_arch.h
> >> @@ -3,9 +3,16 @@
> >> ((union { long long ll; long l[2]; }){ .ll = x }).l[1]
> >> #define __SYSCALL_LL_O(x) __SYSCALL_LL_E((x))
> >>
> >> +#define SYSCALL_CLOBBERLIST \
> >> + "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", "memory"
> >> +
> >> #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)
> >> diff --git a/arch/riscv64/syscall_arch.h b/arch/riscv64/syscall_arch.h
> >> index 81993fc8..6e05c9b3 100644
> >> --- a/arch/riscv64/syscall_arch.h
> >> +++ b/arch/riscv64/syscall_arch.h
> >> @@ -1,9 +1,16 @@
> >> #define __SYSCALL_LL_E(x) (x)
> >> #define __SYSCALL_LL_O(x) (x)
> >>
> >> +#define SYSCALL_CLOBBERLIST \
> >> + "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", "memory"
> >> +
> >> #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)
> >> --
> >> 2.53.0
> >
> > I don't doubt that something like this is needed, but I'm a little
> > concerned about a couple things. Does this break build for targets that
> > lack these registers or compilers that aren't aware of them? And is
> > the set stable, or will it grow as other extensions are added?
> >
> > If there are no good answers to these questions, it might require
> > dropping inline syscalls for riscv and forcing them all to go through
> > an external call where the call ABI governs the register clobbers.
>
> Older GCCs will complain about the V registers. GCC 13 (~2023) is
> the first version that became aware of them. A newer GCC with V
> disabled will just ignore those clobbers. I believe the story is
> similar for Clang; it gained full awareness of V registers in Clang
> 18 (~2024).
>
> So we probably need to at least check __GNUC__ and __clang__ if we
> go with this approach.
>
> I seem to recall the kernel did something similar to this for
> SVE/SME state on AArch64? So I don't think we can rule out the
> possibility of this being the norm going forward. Then again, it's
> not the case for vector registers on LoongArch... :shrug:
>
> My suggestion, FWIW, would be to leave it as-is for now. If the
> kernel folks do decide to do this again for a future RISC-V
> extension, then it's probably time to switch to an external call
> because a pattern has been established.
Well if we're going to include this fix, it needs to actually compile
on any compiler someone might use.
Is there a predefined macro that declares the availability of these
registers that we could use? I really do not want to hard-code
particular gcc or clang versions.
Rich
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.