]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
arm64: syscall: Pass 'orig_x0' as first argument to native system call
authorWill Deacon <will@kernel.org>
Thu, 30 Jul 2026 13:26:51 +0000 (14:26 +0100)
committerWill Deacon <will@kernel.org>
Sun, 2 Aug 2026 09:52:36 +0000 (09:52 +0000)
syscall_get_arguments() returns 'regs->orig_x0' for the first system
call argument so as to avoid aliasing with the syscall return value in
'regs->regs[0]' on the return path, however the actual syscall
invocation passes 'regs->regs[0]' as the first parameter.

Although the two registers should be kept in sync during syscall entry
for native tasks, pass 'regs->orig_x0' as the first syscall parameter
for consistency with the syscall argument APIs. Compat tasks continue to
use 'regs->regs[0]' for compatibility with the behaviour of the 32-bit
kernel.

Suggested-by: Jinjie Ruan <ruanjinjie@huawei.com>
Signed-off-by: Will Deacon <will@kernel.org>
arch/arm64/include/asm/syscall_wrapper.h

index abb57bc543054fa18e793cb0548c04eed76a08e3..395152ef53725f0cbc83599b2431219e4a451d73 100644 (file)
 
 #include <asm/ptrace.h>
 
-#define SC_ARM64_REGS_TO_ARGS(x, ...)                          \
+#ifdef CONFIG_COMPAT
+
+#define COMPAT_SC_ARM64_REGS_TO_ARGS(x, ...)                   \
        __MAP(x,__SC_ARGS                                       \
              ,,regs->regs[0],,regs->regs[1],,regs->regs[2]     \
              ,,regs->regs[3],,regs->regs[4],,regs->regs[5])
 
-#ifdef CONFIG_COMPAT
-
 #define COMPAT_SYSCALL_DEFINEx(x, name, ...)                                           \
        asmlinkage long __arm64_compat_sys##name(const struct pt_regs *regs);           \
        ALLOW_ERROR_INJECTION(__arm64_compat_sys##name, ERRNO);                         \
@@ -24,7 +24,7 @@
        static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));       \
        asmlinkage long __arm64_compat_sys##name(const struct pt_regs *regs)            \
        {                                                                               \
-               return __se_compat_sys##name(SC_ARM64_REGS_TO_ARGS(x,__VA_ARGS__));     \
+               return __se_compat_sys##name(COMPAT_SC_ARM64_REGS_TO_ARGS(x,__VA_ARGS__));      \
        }                                                                               \
        static long __se_compat_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__))               \
        {                                                                               \
 
 #endif /* CONFIG_COMPAT */
 
+#define SC_ARM64_REGS_TO_ARGS(x, ...)                          \
+       __MAP(x,__SC_ARGS                                       \
+             ,,regs->orig_x0,,regs->regs[1],,regs->regs[2]     \
+             ,,regs->regs[3],,regs->regs[4],,regs->regs[5])
+
 #define __SYSCALL_DEFINEx(x, name, ...)                                                \
        asmlinkage long __arm64_sys##name(const struct pt_regs *regs);          \
        ALLOW_ERROR_INJECTION(__arm64_sys##name, ERRNO);                        \