* [PATCH v16 01/18] seccomp: Convert __secure_computing() to return boolean
2026-06-29 13:05 [PATCH v16 00/18] arm64: entry: Convert to Generic Entry Jinjie Ruan
@ 2026-06-29 13:05 ` Jinjie Ruan
2026-06-29 13:16 ` sashiko-bot
2026-06-29 13:06 ` [PATCH v16 02/18] syscall_user_dispatch: Introduce a weak fallback for arch_syscall_is_vdso_sigreturn() Jinjie Ruan
` (16 subsequent siblings)
17 siblings, 1 reply; 21+ messages in thread
From: Jinjie Ruan @ 2026-06-29 13:05 UTC (permalink / raw)
To: oleg, richard.henderson, mattst88, linmag7, linux,
catalin.marinas, will, kees, guoren, chenhuacai, kernel, geert,
tsbogend, James.Bottomley, deller, maddy, mpe, npiggin, chleroy,
pjw, palmer, aou, alex, hca, gor, agordeev, borntraeger, svens,
ysato, dalias, glaubitz, richard, anton.ivanov, johannes, luto,
tglx, mingo, bp, dave.hansen, hpa, chris, jcmvbkbc, peterz, wad,
ruanjinjie, thuth, mark.rutland, ada.coupriediaz, kevin.brodsky,
linusw, yeoreum.yun, song, james.morse, anshuman.khandual,
broonie, liqiang01, pengcan, ryan.roberts, yangtiezhu, sshegde,
mchauras, austin.kim, jchrist, arnd, thomas.weissschuh,
sohil.mehta, andrew.cooper3, jgross, kas, x86, linux-alpha,
linux-kernel, linux-arm-kernel, linux-mm, linux-csky, loongarch,
linux-m68k, linux-mips, linux-parisc, linuxppc-dev, linux-riscv,
linux-s390, linux-sh, linux-um
The return value of __secure_computing() currently uses 0 to indicate
that a system call should be allowed, and -1 to indicate that it should
be blocked/killed. This 0/-1 pattern is non-intuitive for a security
check function and makes the control flow at the call sites less readable.
Furthermore, any potential future changes to these return values would
require a high-risk, error-prone audit of all its users across different
architectures.
Sanitize this logic by converting the return type of __secure_computing()
to a proper boolean, where 'true' explicitly means 'allow' and 'false'
means 'fail/deny'.
Update all the two dozen or so call sites across the tree to align with
this new boolean semantic. No functional changes are intended, as the
callers still return -1 to the lower-level assembly entry code upon
seccomp denial.
Suggested-by: Thomas Gleixner <tglx@kernel.org>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/alpha/kernel/ptrace.c | 2 +-
arch/arm/kernel/ptrace.c | 2 +-
arch/arm64/kernel/ptrace.c | 2 +-
arch/csky/kernel/ptrace.c | 2 +-
arch/m68k/kernel/ptrace.c | 2 +-
arch/mips/kernel/ptrace.c | 2 +-
arch/parisc/kernel/ptrace.c | 2 +-
arch/sh/kernel/ptrace_32.c | 2 +-
arch/um/kernel/skas/syscall.c | 2 +-
arch/x86/entry/vsyscall/vsyscall_64.c | 2 +-
arch/xtensa/kernel/ptrace.c | 3 +--
include/linux/entry-common.h | 7 +++---
include/linux/seccomp.h | 10 ++++----
kernel/seccomp.c | 34 +++++++++++++--------------
14 files changed, 36 insertions(+), 38 deletions(-)
diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c
index 0687760ea466..27d9847b1082 100644
--- a/arch/alpha/kernel/ptrace.c
+++ b/arch/alpha/kernel/ptrace.c
@@ -387,7 +387,7 @@ asmlinkage unsigned long syscall_trace_enter(void)
* If this fails, seccomp may already have set up the return value
* (e.g. SECCOMP_RET_ERRNO / TRACE).
*/
- if (secure_computing() == -1) {
+ if (!secure_computing()) {
if (regs->r19 == 0 && regs->r0 == (unsigned long)-1)
syscall_set_return_value(current, regs, -ENOSYS, 0);
syscall_set_nr(current, regs, -1);
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 7951b2c06fec..5210745725ca 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -855,7 +855,7 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs)
/* Do seccomp after ptrace; syscall may have changed. */
#ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER
- if (secure_computing() == -1)
+ if (!secure_computing())
return -1;
#else
/* XXX: remove this once OABI gets fixed */
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 4d08598e2891..2ca6fab39a37 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -2420,7 +2420,7 @@ int syscall_trace_enter(struct pt_regs *regs)
}
/* Do the secure computing after ptrace; failures should be fast. */
- if (secure_computing() == -1)
+ if (!secure_computing())
return NO_SYSCALL;
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
diff --git a/arch/csky/kernel/ptrace.c b/arch/csky/kernel/ptrace.c
index 6bb685a2646b..11c5eff41e9d 100644
--- a/arch/csky/kernel/ptrace.c
+++ b/arch/csky/kernel/ptrace.c
@@ -323,7 +323,7 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs)
if (ptrace_report_syscall_entry(regs))
return -1;
- if (secure_computing() == -1)
+ if (!secure_computing())
return -1;
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c
index cfa2df24eced..d2411404b9df 100644
--- a/arch/m68k/kernel/ptrace.c
+++ b/arch/m68k/kernel/ptrace.c
@@ -281,7 +281,7 @@ asmlinkage int syscall_trace_enter(void)
if (test_thread_flag(TIF_SYSCALL_TRACE))
ret = ptrace_report_syscall_entry(task_pt_regs(current));
- if (secure_computing() == -1)
+ if (!secure_computing())
return -1;
return ret;
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 3f4c94c88124..0d809cda7542 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -1328,7 +1328,7 @@ asmlinkage long syscall_trace_enter(struct pt_regs *regs)
return -1;
}
- if (secure_computing())
+ if (!secure_computing())
return -1;
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index 8a17ab7e6e0b..565b51a48c8a 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -351,7 +351,7 @@ long do_syscall_trace_enter(struct pt_regs *regs)
}
/* Do the secure computing check after ptrace. */
- if (secure_computing() == -1)
+ if (!secure_computing())
return -1;
#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c
index 06f765d71a29..8687f17cbe5a 100644
--- a/arch/sh/kernel/ptrace_32.c
+++ b/arch/sh/kernel/ptrace_32.c
@@ -460,7 +460,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
return -1;
}
- if (secure_computing() == -1)
+ if (!secure_computing())
return -1;
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c
index ba7494f9bfe4..916cd7acceaf 100644
--- a/arch/um/kernel/skas/syscall.c
+++ b/arch/um/kernel/skas/syscall.c
@@ -27,7 +27,7 @@ void handle_syscall(struct uml_pt_regs *r)
goto out;
/* Do the seccomp check after ptrace; failures should be fast. */
- if (secure_computing() == -1)
+ if (!secure_computing())
goto out;
syscall = UPT_SYSCALL_NR(r);
diff --git a/arch/x86/entry/vsyscall/vsyscall_64.c b/arch/x86/entry/vsyscall/vsyscall_64.c
index ea36de9fa864..6aed3987b9f9 100644
--- a/arch/x86/entry/vsyscall/vsyscall_64.c
+++ b/arch/x86/entry/vsyscall/vsyscall_64.c
@@ -198,7 +198,7 @@ static bool __emulate_vsyscall(struct pt_regs *regs, unsigned long address)
regs->orig_ax = syscall_nr;
regs->ax = -ENOSYS;
tmp = secure_computing();
- if ((!tmp && regs->orig_ax != syscall_nr) || regs->ip != address) {
+ if ((tmp && regs->orig_ax != syscall_nr) || regs->ip != address) {
warn_bad_vsyscall(KERN_DEBUG, regs,
"seccomp tried to change syscall nr or ip");
force_exit_sig(SIGSYS);
diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c
index b80d54b2ea34..ef78fcd318ff 100644
--- a/arch/xtensa/kernel/ptrace.c
+++ b/arch/xtensa/kernel/ptrace.c
@@ -553,8 +553,7 @@ int do_syscall_trace_enter(struct pt_regs *regs)
return 0;
}
- if (regs->syscall == NO_SYSCALL ||
- secure_computing() == -1) {
+ if (regs->syscall == NO_SYSCALL || !secure_computing()) {
do_syscall_trace_leave(regs);
return 0;
}
diff --git a/include/linux/entry-common.h b/include/linux/entry-common.h
index 416a3352261f..3f66320e46d3 100644
--- a/include/linux/entry-common.h
+++ b/include/linux/entry-common.h
@@ -100,9 +100,8 @@ static __always_inline long syscall_trace_enter(struct pt_regs *regs, unsigned l
/* Do seccomp after ptrace, to catch any tracer changes. */
if (work & SYSCALL_WORK_SECCOMP) {
- ret = __secure_computing();
- if (ret == -1L)
- return ret;
+ if (!__secure_computing())
+ return -1L;
}
/* Either of the above might have changed the syscall number */
@@ -113,7 +112,7 @@ static __always_inline long syscall_trace_enter(struct pt_regs *regs, unsigned l
syscall_enter_audit(regs, syscall);
- return ret ? : syscall;
+ return syscall;
}
/**
diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
index 9b959972bf4a..7af3173f40e9 100644
--- a/include/linux/seccomp.h
+++ b/include/linux/seccomp.h
@@ -22,14 +22,14 @@
#include <linux/atomic.h>
#include <asm/seccomp.h>
-extern int __secure_computing(void);
+extern bool __secure_computing(void);
#ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER
-static inline int secure_computing(void)
+static inline bool secure_computing(void)
{
if (unlikely(test_syscall_work(SECCOMP)))
return __secure_computing();
- return 0;
+ return true;
}
#else
extern void secure_computing_strict(int this_syscall);
@@ -50,11 +50,11 @@ static inline int seccomp_mode(struct seccomp *s)
struct seccomp_data;
#ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER
-static inline int secure_computing(void) { return 0; }
+static inline bool secure_computing(void) { return true; }
#else
static inline void secure_computing_strict(int this_syscall) { return; }
#endif
-static inline int __secure_computing(void) { return 0; }
+static inline bool __secure_computing(void) { return true; }
static inline long prctl_get_seccomp(void)
{
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index 066909393c38..1fec6efedab6 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -1100,12 +1100,12 @@ void secure_computing_strict(int this_syscall)
else
BUG();
}
-int __secure_computing(void)
+bool __secure_computing(void)
{
int this_syscall = syscall_get_nr(current, current_pt_regs());
secure_computing_strict(this_syscall);
- return 0;
+ return true;
}
#else
@@ -1256,7 +1256,7 @@ static int seccomp_do_user_notification(int this_syscall,
return -1;
}
-static int __seccomp_filter(int this_syscall, const bool recheck_after_trace)
+static bool __seccomp_filter(int this_syscall, const bool recheck_after_trace)
{
u32 filter_ret, action;
struct seccomp_data sd;
@@ -1294,7 +1294,7 @@ static int __seccomp_filter(int this_syscall, const bool recheck_after_trace)
case SECCOMP_RET_TRACE:
/* We've been put in this state by the ptracer already. */
if (recheck_after_trace)
- return 0;
+ return true;
/* ENOSYS these calls if there is no tracer attached. */
if (!ptrace_event_enabled(current, PTRACE_EVENT_SECCOMP)) {
@@ -1330,19 +1330,19 @@ static int __seccomp_filter(int this_syscall, const bool recheck_after_trace)
* a skip would have already been reported.
*/
if (__seccomp_filter(this_syscall, true))
- return -1;
+ return false;
- return 0;
+ return true;
case SECCOMP_RET_USER_NOTIF:
if (seccomp_do_user_notification(this_syscall, match, &sd))
goto skip;
- return 0;
+ return true;
case SECCOMP_RET_LOG:
seccomp_log(this_syscall, 0, action, true);
- return 0;
+ return true;
case SECCOMP_RET_ALLOW:
/*
@@ -1350,7 +1350,7 @@ static int __seccomp_filter(int this_syscall, const bool recheck_after_trace)
* this action since SECCOMP_RET_ALLOW is the starting
* state in seccomp_run_filters().
*/
- return 0;
+ return true;
case SECCOMP_RET_KILL_THREAD:
case SECCOMP_RET_KILL_PROCESS:
@@ -1367,46 +1367,46 @@ static int __seccomp_filter(int this_syscall, const bool recheck_after_trace)
} else {
do_exit(SIGSYS);
}
- return -1; /* skip the syscall go directly to signal handling */
+ return false; /* skip the syscall go directly to signal handling */
}
unreachable();
skip:
seccomp_log(this_syscall, 0, action, match ? match->log : false);
- return -1;
+ return false;
}
#else
-static int __seccomp_filter(int this_syscall, const bool recheck_after_trace)
+static bool __seccomp_filter(int this_syscall, const bool recheck_after_trace)
{
BUG();
- return -1;
+ return false;
}
#endif
-int __secure_computing(void)
+bool __secure_computing(void)
{
int mode = current->seccomp.mode;
int this_syscall;
if (IS_ENABLED(CONFIG_CHECKPOINT_RESTORE) &&
unlikely(current->ptrace & PT_SUSPEND_SECCOMP))
- return 0;
+ return true;
this_syscall = syscall_get_nr(current, current_pt_regs());
switch (mode) {
case SECCOMP_MODE_STRICT:
__secure_computing_strict(this_syscall); /* may call do_exit */
- return 0;
+ return true;
case SECCOMP_MODE_FILTER:
return __seccomp_filter(this_syscall, false);
/* Surviving SECCOMP_RET_KILL_* must be proactively impossible. */
case SECCOMP_MODE_DEAD:
WARN_ON_ONCE(1);
do_exit(SIGKILL);
- return -1;
+ return false;
default:
BUG();
}
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* Re: [PATCH v16 01/18] seccomp: Convert __secure_computing() to return boolean
2026-06-29 13:05 ` [PATCH v16 01/18] seccomp: Convert __secure_computing() to return boolean Jinjie Ruan
@ 2026-06-29 13:16 ` sashiko-bot
0 siblings, 0 replies; 21+ messages in thread
From: sashiko-bot @ 2026-06-29 13:16 UTC (permalink / raw)
To: Jinjie Ruan; +Cc: Vasily Gorbik, linux-s390, Heiko Carstens, Alexander Gordeev
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Critical] Incomplete conversion of secure_computing() return semantics in x86 vsyscall emulation causes allowed vsyscalls to be incorrectly skipped and blocked vsyscalls to be executed.
- [Critical] Inverted seccomp evaluation logic for tracer-modified syscalls in SECCOMP_RET_TRACE allows ptracers to bypass seccomp and execute blocked system calls.
--
commit f5bc8c5696220b369255d486da26d273d661d2fa
Author: Jinjie Ruan <ruanjinjie@huawei.com>
seccomp: Convert __secure_computing() to return boolean
The return value of __secure_computing() currently uses 0 to indicate
that a system call should be allowed, and -1 to indicate that it should
be blocked/killed. This 0/-1 pattern is non-intuitive for a security
check function and makes the control flow at the call sites less readable.
> diff --git a/arch/x86/entry/vsyscall/vsyscall_64.c b/arch/x86/entry/vsyscall/vsyscall_64.c
> index ea36de9fa8641..6aed3987b9f96 100644
> --- a/arch/x86/entry/vsyscall/vsyscall_64.c
> +++ b/arch/x86/entry/vsyscall/vsyscall_64.c
> @@ -198,7 +198,7 @@ static bool __emulate_vsyscall(struct pt_regs *regs, unsigned long address)
> regs->orig_ax = syscall_nr;
> regs->ax = -ENOSYS;
> tmp = secure_computing();
> - if ((!tmp && regs->orig_ax != syscall_nr) || regs->ip != address) {
> + if ((tmp && regs->orig_ax != syscall_nr) || regs->ip != address) {
> warn_bad_vsyscall(KERN_DEBUG, regs,
> "seccomp tried to change syscall nr or ip");
> force_exit_sig(SIGSYS);
> return true;
> }
> regs->orig_ax = -1;
> if (tmp)
> goto do_ret; /* skip requested */
[Severity: Critical]
Since secure_computing() now returns true when allowing a system call, doesn't
this check skip the emulation for allowed vsyscalls and execute the blocked
ones instead?
[ ... ]
> diff --git a/kernel/seccomp.c b/kernel/seccomp.c
> index 066909393c38f..1fec6efedab62 100644
> --- a/kernel/seccomp.c
> +++ b/kernel/seccomp.c
[ ... ]
> @@ -1330,19 +1330,19 @@ static int __seccomp_filter(int this_syscall, const bool recheck_after_trace)
> * a skip would have already been reported.
> */
> if (__seccomp_filter(this_syscall, true))
> - return -1;
> + return false;
>
> - return 0;
> + return true;
[Severity: Critical]
Is this logic inverted for tracer-modified syscalls in SECCOMP_RET_TRACE?
__seccomp_filter() now returns true on allow and false on deny.
If the nested __seccomp_filter() call evaluates the modified syscall and
returns true (allow), the if condition evaluates to true and it returns
false (deny).
Conversely, if it returns false (deny), it bypasses the if condition and
returns true (allow).
Could a ptracer bypass the seccomp sandbox entirely by changing the syscall
to a prohibited one, which would then be incorrectly allowed here?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260629130616.642022-1-ruanjinjie@huawei.com?part=1
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v16 02/18] syscall_user_dispatch: Introduce a weak fallback for arch_syscall_is_vdso_sigreturn()
2026-06-29 13:05 [PATCH v16 00/18] arm64: entry: Convert to Generic Entry Jinjie Ruan
2026-06-29 13:05 ` [PATCH v16 01/18] seccomp: Convert __secure_computing() to return boolean Jinjie Ruan
@ 2026-06-29 13:06 ` Jinjie Ruan
2026-06-29 13:06 ` [PATCH v16 03/18] arm64: ptrace: Pass thread flags to syscall_trace_enter/exit() Jinjie Ruan
` (15 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Jinjie Ruan @ 2026-06-29 13:06 UTC (permalink / raw)
To: oleg, richard.henderson, mattst88, linmag7, linux,
catalin.marinas, will, kees, guoren, chenhuacai, kernel, geert,
tsbogend, James.Bottomley, deller, maddy, mpe, npiggin, chleroy,
pjw, palmer, aou, alex, hca, gor, agordeev, borntraeger, svens,
ysato, dalias, glaubitz, richard, anton.ivanov, johannes, luto,
tglx, mingo, bp, dave.hansen, hpa, chris, jcmvbkbc, peterz, wad,
ruanjinjie, thuth, mark.rutland, ada.coupriediaz, kevin.brodsky,
linusw, yeoreum.yun, song, james.morse, anshuman.khandual,
broonie, liqiang01, pengcan, ryan.roberts, yangtiezhu, sshegde,
mchauras, austin.kim, jchrist, arnd, thomas.weissschuh,
sohil.mehta, andrew.cooper3, jgross, kas, x86, linux-alpha,
linux-kernel, linux-arm-kernel, linux-mm, linux-csky, loongarch,
linux-m68k, linux-mips, linux-parisc, linuxppc-dev, linux-riscv,
linux-s390, linux-sh, linux-um
Currently, multiple architectures (LoongArch, RISC-V, S390, Powerpc)
provide identical stubs for arch_syscall_is_vdso_sigreturn() that simply
return false. This results in redundant boilerplate code across the tree.
Introduce a default __weak implementation of
arch_syscall_is_vdso_sigreturn() directly in syscall_user_dispatch.c that
returns false. This allows architectures that do not utilize a vDSO
sigreturn to entirely drop their redundant inline definitions.
Architectures requiring a specialized check (such as x86) will continue to
override this fallback with their strong symbol definitions.
Clean up the redundant implementations in loongarch, riscv, s390
and powerpc.
Cc: Thomas Gleixner <tglx@kernel.org>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/loongarch/include/asm/syscall.h | 5 -----
arch/powerpc/include/asm/syscall.h | 5 -----
arch/riscv/include/asm/syscall.h | 5 -----
arch/s390/include/asm/syscall.h | 5 -----
include/linux/syscall_user_dispatch.h | 1 +
kernel/entry/syscall_user_dispatch.c | 5 +++++
6 files changed, 6 insertions(+), 20 deletions(-)
diff --git a/arch/loongarch/include/asm/syscall.h b/arch/loongarch/include/asm/syscall.h
index df8ea223c77b..946886794ced 100644
--- a/arch/loongarch/include/asm/syscall.h
+++ b/arch/loongarch/include/asm/syscall.h
@@ -85,9 +85,4 @@ static inline int syscall_get_arch(struct task_struct *task)
#endif
}
-static inline bool arch_syscall_is_vdso_sigreturn(struct pt_regs *regs)
-{
- return false;
-}
-
#endif /* __ASM_LOONGARCH_SYSCALL_H */
diff --git a/arch/powerpc/include/asm/syscall.h b/arch/powerpc/include/asm/syscall.h
index 834fcc4f7b54..4b3c52ed6e9d 100644
--- a/arch/powerpc/include/asm/syscall.h
+++ b/arch/powerpc/include/asm/syscall.h
@@ -139,9 +139,4 @@ static inline int syscall_get_arch(struct task_struct *task)
else
return AUDIT_ARCH_PPC64;
}
-
-static inline bool arch_syscall_is_vdso_sigreturn(struct pt_regs *regs)
-{
- return false;
-}
#endif /* _ASM_SYSCALL_H */
diff --git a/arch/riscv/include/asm/syscall.h b/arch/riscv/include/asm/syscall.h
index 8067e666a4ca..987c9a78806f 100644
--- a/arch/riscv/include/asm/syscall.h
+++ b/arch/riscv/include/asm/syscall.h
@@ -112,11 +112,6 @@ static inline void syscall_handler(struct pt_regs *regs, ulong syscall)
regs->a0 = fn(regs);
}
-static inline bool arch_syscall_is_vdso_sigreturn(struct pt_regs *regs)
-{
- return false;
-}
-
asmlinkage long sys_riscv_flush_icache(uintptr_t, uintptr_t, uintptr_t);
asmlinkage long sys_riscv_hwprobe(struct riscv_hwprobe *, size_t, size_t,
diff --git a/arch/s390/include/asm/syscall.h b/arch/s390/include/asm/syscall.h
index 4271e4169f45..5f310caad1fc 100644
--- a/arch/s390/include/asm/syscall.h
+++ b/arch/s390/include/asm/syscall.h
@@ -89,11 +89,6 @@ static inline int syscall_get_arch(struct task_struct *task)
return AUDIT_ARCH_S390X;
}
-static inline bool arch_syscall_is_vdso_sigreturn(struct pt_regs *regs)
-{
- return false;
-}
-
#define SYSCALL_FMT_0
#define SYSCALL_FMT_1 , "0" (r2)
#define SYSCALL_FMT_2 , "d" (r3) SYSCALL_FMT_1
diff --git a/include/linux/syscall_user_dispatch.h b/include/linux/syscall_user_dispatch.h
index 3858a6ffdd5c..73d69e02807d 100644
--- a/include/linux/syscall_user_dispatch.h
+++ b/include/linux/syscall_user_dispatch.h
@@ -10,6 +10,7 @@
#ifdef CONFIG_GENERIC_ENTRY
+bool arch_syscall_is_vdso_sigreturn(struct pt_regs *regs);
int set_syscall_user_dispatch(unsigned long mode, unsigned long offset,
unsigned long len, char __user *selector);
diff --git a/kernel/entry/syscall_user_dispatch.c b/kernel/entry/syscall_user_dispatch.c
index d89dffcc2d64..acf545774d37 100644
--- a/kernel/entry/syscall_user_dispatch.c
+++ b/kernel/entry/syscall_user_dispatch.c
@@ -32,6 +32,11 @@ static void trigger_sigsys(struct pt_regs *regs)
force_sig_info(&info);
}
+bool __weak arch_syscall_is_vdso_sigreturn(struct pt_regs *regs)
+{
+ return false;
+}
+
bool syscall_user_dispatch(struct pt_regs *regs)
{
struct syscall_user_dispatch *sd = ¤t->syscall_dispatch;
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v16 03/18] arm64: ptrace: Pass thread flags to syscall_trace_enter/exit()
2026-06-29 13:05 [PATCH v16 00/18] arm64: entry: Convert to Generic Entry Jinjie Ruan
2026-06-29 13:05 ` [PATCH v16 01/18] seccomp: Convert __secure_computing() to return boolean Jinjie Ruan
2026-06-29 13:06 ` [PATCH v16 02/18] syscall_user_dispatch: Introduce a weak fallback for arch_syscall_is_vdso_sigreturn() Jinjie Ruan
@ 2026-06-29 13:06 ` Jinjie Ruan
2026-06-29 13:06 ` [PATCH v16 04/18] arm64: ptrace: Use syscall_get_nr() helper for syscall_trace_enter() Jinjie Ruan
` (14 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Jinjie Ruan @ 2026-06-29 13:06 UTC (permalink / raw)
To: oleg, richard.henderson, mattst88, linmag7, linux,
catalin.marinas, will, kees, guoren, chenhuacai, kernel, geert,
tsbogend, James.Bottomley, deller, maddy, mpe, npiggin, chleroy,
pjw, palmer, aou, alex, hca, gor, agordeev, borntraeger, svens,
ysato, dalias, glaubitz, richard, anton.ivanov, johannes, luto,
tglx, mingo, bp, dave.hansen, hpa, chris, jcmvbkbc, peterz, wad,
ruanjinjie, thuth, mark.rutland, ada.coupriediaz, kevin.brodsky,
linusw, yeoreum.yun, song, james.morse, anshuman.khandual,
broonie, liqiang01, pengcan, ryan.roberts, yangtiezhu, sshegde,
mchauras, austin.kim, jchrist, arnd, thomas.weissschuh,
sohil.mehta, andrew.cooper3, jgross, kas, x86, linux-alpha,
linux-kernel, linux-arm-kernel, linux-mm, linux-csky, loongarch,
linux-m68k, linux-mips, linux-parisc, linuxppc-dev, linux-riscv,
linux-s390, linux-sh, linux-um
Refactor syscall_trace_enter() and syscall_trace_exit() to move thread
flag reading to the caller. This aligns arm64's syscall trace enter/exit
function signature with generic entry framework.
[Changes]
1. Function signature changes:
- syscall_trace_enter(regs) → syscall_trace_enter(regs, flags)
- syscall_trace_exit(regs) → syscall_trace_exit(regs, flags)
2. Move flags reading to caller:
- Previously: read_thread_flags() called inside each function.
- Now: caller (like el0_svc_common) passes flags as parameter.
3. Update syscall.c:
- el0_svc_common() now passes flags to tracing functions and
re-fetches flags before entry/exit to handle potential TIF
updates.
[Why this matters]
- Aligns arm64 with the generic entry interface.
- Makes future migration to generic entry framework smoother.
No functional changes intended.
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: Ada Couprie Diaz <ada.coupriediaz@arm.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Reviewed-by: Yeoreum Yun <yeoreum.yun@arm.com>
Reviewed-by: Kevin Brodsky <kevin.brodsky@arm.com>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/arm64/include/asm/syscall.h | 4 ++--
arch/arm64/kernel/ptrace.c | 7 ++-----
arch/arm64/kernel/syscall.c | 5 +++--
3 files changed, 7 insertions(+), 9 deletions(-)
diff --git a/arch/arm64/include/asm/syscall.h b/arch/arm64/include/asm/syscall.h
index 5e4c7fc44f73..30b203ef156b 100644
--- a/arch/arm64/include/asm/syscall.h
+++ b/arch/arm64/include/asm/syscall.h
@@ -120,7 +120,7 @@ static inline int syscall_get_arch(struct task_struct *task)
return AUDIT_ARCH_AARCH64;
}
-int syscall_trace_enter(struct pt_regs *regs);
-void syscall_trace_exit(struct pt_regs *regs);
+int syscall_trace_enter(struct pt_regs *regs, unsigned long flags);
+void syscall_trace_exit(struct pt_regs *regs, unsigned long flags);
#endif /* __ASM_SYSCALL_H */
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 2ca6fab39a37..ac15b81a71b5 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -2408,9 +2408,8 @@ static void report_syscall_exit(struct pt_regs *regs)
}
}
-int syscall_trace_enter(struct pt_regs *regs)
+int syscall_trace_enter(struct pt_regs *regs, unsigned long flags)
{
- unsigned long flags = read_thread_flags();
int ret;
if (flags & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE)) {
@@ -2432,10 +2431,8 @@ int syscall_trace_enter(struct pt_regs *regs)
return regs->syscallno;
}
-void syscall_trace_exit(struct pt_regs *regs)
+void syscall_trace_exit(struct pt_regs *regs, unsigned long flags)
{
- unsigned long flags = read_thread_flags();
-
audit_syscall_exit(regs);
if (flags & _TIF_SYSCALL_TRACEPOINT)
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index 358ddfbf1401..c8e116397cfd 100644
--- a/arch/arm64/kernel/syscall.c
+++ b/arch/arm64/kernel/syscall.c
@@ -113,7 +113,7 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
*/
if (scno == NO_SYSCALL)
syscall_set_return_value(current, regs, -ENOSYS, 0);
- scno = syscall_trace_enter(regs);
+ scno = syscall_trace_enter(regs, read_thread_flags());
if (scno == NO_SYSCALL)
goto trace_exit;
}
@@ -132,7 +132,8 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
}
trace_exit:
- syscall_trace_exit(regs);
+ flags = read_thread_flags();
+ syscall_trace_exit(regs, flags);
}
void do_el0_svc(struct pt_regs *regs)
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v16 04/18] arm64: ptrace: Use syscall_get_nr() helper for syscall_trace_enter()
2026-06-29 13:05 [PATCH v16 00/18] arm64: entry: Convert to Generic Entry Jinjie Ruan
` (2 preceding siblings ...)
2026-06-29 13:06 ` [PATCH v16 03/18] arm64: ptrace: Pass thread flags to syscall_trace_enter/exit() Jinjie Ruan
@ 2026-06-29 13:06 ` Jinjie Ruan
2026-06-29 13:06 ` [PATCH v16 05/18] arm64: ptrace: Expand secure_computing() in place Jinjie Ruan
` (13 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Jinjie Ruan @ 2026-06-29 13:06 UTC (permalink / raw)
To: oleg, richard.henderson, mattst88, linmag7, linux,
catalin.marinas, will, kees, guoren, chenhuacai, kernel, geert,
tsbogend, James.Bottomley, deller, maddy, mpe, npiggin, chleroy,
pjw, palmer, aou, alex, hca, gor, agordeev, borntraeger, svens,
ysato, dalias, glaubitz, richard, anton.ivanov, johannes, luto,
tglx, mingo, bp, dave.hansen, hpa, chris, jcmvbkbc, peterz, wad,
ruanjinjie, thuth, mark.rutland, ada.coupriediaz, kevin.brodsky,
linusw, yeoreum.yun, song, james.morse, anshuman.khandual,
broonie, liqiang01, pengcan, ryan.roberts, yangtiezhu, sshegde,
mchauras, austin.kim, jchrist, arnd, thomas.weissschuh,
sohil.mehta, andrew.cooper3, jgross, kas, x86, linux-alpha,
linux-kernel, linux-arm-kernel, linux-mm, linux-csky, loongarch,
linux-m68k, linux-mips, linux-parisc, linuxppc-dev, linux-riscv,
linux-s390, linux-sh, linux-um
Use syscall_get_nr() to get syscall number for syscall_trace_enter().
This aligns arm64's internal tracing logic with the generic
entry framework.
[Changes]
1. Use syscall_get_nr() helper:
- Replace direct regs->syscallno access with
syscall_get_nr(current, regs).
- This helper is functionally equivalent to direct access on arm64.
2. Re-read syscall number after tracepoint:
- Re-fetch the syscall number after trace_sys_enter() as it may have
been modified by BPF or ftrace probes, matching generic entry behavior.
[Why this matters]
- Aligns arm64 with the generic entry interface.
- Makes future migration to generic entry framework smoother.
- Properly handles syscall number modifications by tracers.
- Uses standard architecture-independent helpers.
No functional changes intended.
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: Ada Couprie Diaz <ada.coupriediaz@arm.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Reviewed-by: Yeoreum Yun <yeoreum.yun@arm.com>
Reviewed-by: Kevin Brodsky <kevin.brodsky@arm.com>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/arm64/kernel/ptrace.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index ac15b81a71b5..863083de37c3 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -2410,6 +2410,7 @@ static void report_syscall_exit(struct pt_regs *regs)
int syscall_trace_enter(struct pt_regs *regs, unsigned long flags)
{
+ long syscall;
int ret;
if (flags & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE)) {
@@ -2422,13 +2423,23 @@ int syscall_trace_enter(struct pt_regs *regs, unsigned long flags)
if (!secure_computing())
return NO_SYSCALL;
- if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
- trace_sys_enter(regs, regs->syscallno);
+ /* Either of the above might have changed the syscall number */
+ syscall = syscall_get_nr(current, regs);
- audit_syscall_entry(regs->syscallno, regs->orig_x0, regs->regs[1],
+ if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) {
+ trace_sys_enter(regs, syscall);
+
+ /*
+ * Probes or BPF hooks in the tracepoint may have changed the
+ * system call number as well.
+ */
+ syscall = syscall_get_nr(current, regs);
+ }
+
+ audit_syscall_entry(syscall, regs->orig_x0, regs->regs[1],
regs->regs[2], regs->regs[3]);
- return regs->syscallno;
+ return syscall;
}
void syscall_trace_exit(struct pt_regs *regs, unsigned long flags)
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v16 05/18] arm64: ptrace: Expand secure_computing() in place
2026-06-29 13:05 [PATCH v16 00/18] arm64: entry: Convert to Generic Entry Jinjie Ruan
` (3 preceding siblings ...)
2026-06-29 13:06 ` [PATCH v16 04/18] arm64: ptrace: Use syscall_get_nr() helper for syscall_trace_enter() Jinjie Ruan
@ 2026-06-29 13:06 ` Jinjie Ruan
2026-06-29 13:29 ` sashiko-bot
2026-06-29 13:06 ` [PATCH v16 06/18] arm64: ptrace: Use syscall_get_arguments() helper for audit Jinjie Ruan
` (12 subsequent siblings)
17 siblings, 1 reply; 21+ messages in thread
From: Jinjie Ruan @ 2026-06-29 13:06 UTC (permalink / raw)
To: oleg, richard.henderson, mattst88, linmag7, linux,
catalin.marinas, will, kees, guoren, chenhuacai, kernel, geert,
tsbogend, James.Bottomley, deller, maddy, mpe, npiggin, chleroy,
pjw, palmer, aou, alex, hca, gor, agordeev, borntraeger, svens,
ysato, dalias, glaubitz, richard, anton.ivanov, johannes, luto,
tglx, mingo, bp, dave.hansen, hpa, chris, jcmvbkbc, peterz, wad,
ruanjinjie, thuth, mark.rutland, ada.coupriediaz, kevin.brodsky,
linusw, yeoreum.yun, song, james.morse, anshuman.khandual,
broonie, liqiang01, pengcan, ryan.roberts, yangtiezhu, sshegde,
mchauras, austin.kim, jchrist, arnd, thomas.weissschuh,
sohil.mehta, andrew.cooper3, jgross, kas, x86, linux-alpha,
linux-kernel, linux-arm-kernel, linux-mm, linux-csky, loongarch,
linux-m68k, linux-mips, linux-parisc, linuxppc-dev, linux-riscv,
linux-s390, linux-sh, linux-um
Refactor syscall_trace_enter() by open-coding the seccomp check
to align with the generic entry framework.
[Background]
The generic entry implementation expands the seccomp check in-place
instead of using the secure_computing() wrapper. It directly tests
SYSCALL_WORK_SECCOMP and calls the underlying __secure_computing()
function to handle syscall filtering.
[Changes]
1. Open-code seccomp check:
- Instead of calling the secure_computing() wrapper, explicitly check
the 'flags' parameter for _TIF_SECCOMP.
- Call __secure_computing() directly if the flag is set.
[Why this matters]
- Aligns the arm64 syscall path with the generic entry implementation,
simplifying future migration to the generic entry framework.
- No functional changes are intended; seccomp behavior remains identical.
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: Ada Couprie Diaz <ada.coupriediaz@arm.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Reviewed-by: Yeoreum Yun <yeoreum.yun@arm.com>
Reviewed-by: Kevin Brodsky <kevin.brodsky@arm.com>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/arm64/kernel/ptrace.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 863083de37c3..30df515528e8 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -2420,8 +2420,10 @@ int syscall_trace_enter(struct pt_regs *regs, unsigned long flags)
}
/* Do the secure computing after ptrace; failures should be fast. */
- if (!secure_computing())
- return NO_SYSCALL;
+ if (flags & _TIF_SECCOMP) {
+ if (!__secure_computing())
+ return NO_SYSCALL;
+ }
/* Either of the above might have changed the syscall number */
syscall = syscall_get_nr(current, regs);
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* Re: [PATCH v16 05/18] arm64: ptrace: Expand secure_computing() in place
2026-06-29 13:06 ` [PATCH v16 05/18] arm64: ptrace: Expand secure_computing() in place Jinjie Ruan
@ 2026-06-29 13:29 ` sashiko-bot
0 siblings, 0 replies; 21+ messages in thread
From: sashiko-bot @ 2026-06-29 13:29 UTC (permalink / raw)
To: Jinjie Ruan; +Cc: Vasily Gorbik, linux-s390, Heiko Carstens, Alexander Gordeev
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Open-coding the seccomp check using a cached `flags` variable creates a Time-of-Check to Time-of-Use (TOCTOU) vulnerability during ptrace stops, allowing a seccomp filter installed via TSYNC to be bypassed.
--
commit 138e96f2aef98ac6348b34ceeb3157f77bd0f2f7
Author: Jinjie Ruan <ruanjinjie@huawei.com>
arm64: ptrace: Expand secure_computing() in place
This commit refactors syscall_trace_enter() by open-coding the seccomp
check to align with the generic entry framework. It explicitly checks
the flags parameter for _TIF_SECCOMP instead of calling the wrapper.
> diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
> index 863083de37c37..30df515528e8f 100644
> --- a/arch/arm64/kernel/ptrace.c
> +++ b/arch/arm64/kernel/ptrace.c
> @@ -2420,8 +2420,10 @@ int syscall_trace_enter(struct pt_regs *regs, unsigned long flags)
[ ... ]
> /* Do the secure computing after ptrace; failures should be fast. */
> - if (!secure_computing())
> - return NO_SYSCALL;
> + if (flags & _TIF_SECCOMP) {
> + if (!__secure_computing())
> + return NO_SYSCALL;
> + }
[Severity: High]
Does checking the cached 'flags' argument here instead of dynamically
reading the thread flags create a race condition?
If the current thread stops for ptrace earlier in syscall_trace_enter(),
and another thread installs a filter via seccomp with
SECCOMP_FILTER_FLAG_TSYNC while this thread is stopped, the newly set
_TIF_SECCOMP flag wouldn't be reflected in the local 'flags' variable.
Could this allow an unprivileged process to bypass a newly installed
seccomp filter for the current syscall, especially since the tracer might
modify the syscall number (e.g., to execve) during the ptrace stop?
As an additional detail, the generic entry code in include/linux/entry-common.h
seems to exhibit the same pattern by checking a cached 'work' variable passed
into syscall_trace_enter().
>
> /* Either of the above might have changed the syscall number */
> syscall = syscall_get_nr(current, regs);
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260629130616.642022-1-ruanjinjie@huawei.com?part=5
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v16 06/18] arm64: ptrace: Use syscall_get_arguments() helper for audit
2026-06-29 13:05 [PATCH v16 00/18] arm64: entry: Convert to Generic Entry Jinjie Ruan
` (4 preceding siblings ...)
2026-06-29 13:06 ` [PATCH v16 05/18] arm64: ptrace: Expand secure_computing() in place Jinjie Ruan
@ 2026-06-29 13:06 ` Jinjie Ruan
2026-06-29 13:06 ` [PATCH v16 07/18] arm64: ptrace: Protect rseq_syscall() from tracer PC modifications Jinjie Ruan
` (11 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Jinjie Ruan @ 2026-06-29 13:06 UTC (permalink / raw)
To: oleg, richard.henderson, mattst88, linmag7, linux,
catalin.marinas, will, kees, guoren, chenhuacai, kernel, geert,
tsbogend, James.Bottomley, deller, maddy, mpe, npiggin, chleroy,
pjw, palmer, aou, alex, hca, gor, agordeev, borntraeger, svens,
ysato, dalias, glaubitz, richard, anton.ivanov, johannes, luto,
tglx, mingo, bp, dave.hansen, hpa, chris, jcmvbkbc, peterz, wad,
ruanjinjie, thuth, mark.rutland, ada.coupriediaz, kevin.brodsky,
linusw, yeoreum.yun, song, james.morse, anshuman.khandual,
broonie, liqiang01, pengcan, ryan.roberts, yangtiezhu, sshegde,
mchauras, austin.kim, jchrist, arnd, thomas.weissschuh,
sohil.mehta, andrew.cooper3, jgross, kas, x86, linux-alpha,
linux-kernel, linux-arm-kernel, linux-mm, linux-csky, loongarch,
linux-m68k, linux-mips, linux-parisc, linuxppc-dev, linux-riscv,
linux-s390, linux-sh, linux-um
Extract syscall_enter_audit() helper and use syscall_get_arguments()
to get syscall arguments, matching the generic entry implementation.
The new code:
- Checks audit_context() first to avoid unnecessary memcpy when audit
is not active.
- Uses syscall_get_arguments() helper instead of directly accessing
regs fields.
- Is now exactly equivalent to generic entry's syscall_enter_audit().
No functional changes.
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: Ada Couprie Diaz <ada.coupriediaz@arm.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Reviewed-by: Yeoreum Yun <yeoreum.yun@arm.com>
Reviewed-by: Kevin Brodsky <kevin.brodsky@arm.com>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/arm64/kernel/ptrace.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 30df515528e8..ae71cadbd4df 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -2408,6 +2408,16 @@ static void report_syscall_exit(struct pt_regs *regs)
}
}
+static inline void syscall_enter_audit(struct pt_regs *regs, long syscall)
+{
+ if (unlikely(audit_context())) {
+ unsigned long args[6];
+
+ syscall_get_arguments(current, regs, args);
+ audit_syscall_entry(syscall, args[0], args[1], args[2], args[3]);
+ }
+}
+
int syscall_trace_enter(struct pt_regs *regs, unsigned long flags)
{
long syscall;
@@ -2438,8 +2448,7 @@ int syscall_trace_enter(struct pt_regs *regs, unsigned long flags)
syscall = syscall_get_nr(current, regs);
}
- audit_syscall_entry(syscall, regs->orig_x0, regs->regs[1],
- regs->regs[2], regs->regs[3]);
+ syscall_enter_audit(regs, syscall);
return syscall;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v16 07/18] arm64: ptrace: Protect rseq_syscall() from tracer PC modifications
2026-06-29 13:05 [PATCH v16 00/18] arm64: entry: Convert to Generic Entry Jinjie Ruan
` (5 preceding siblings ...)
2026-06-29 13:06 ` [PATCH v16 06/18] arm64: ptrace: Use syscall_get_arguments() helper for audit Jinjie Ruan
@ 2026-06-29 13:06 ` Jinjie Ruan
2026-06-29 13:06 ` [PATCH v16 08/18] arm64: ptrace: Rename syscall_trace_exit() to syscall_exit_work() Jinjie Ruan
` (10 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Jinjie Ruan @ 2026-06-29 13:06 UTC (permalink / raw)
To: oleg, richard.henderson, mattst88, linmag7, linux,
catalin.marinas, will, kees, guoren, chenhuacai, kernel, geert,
tsbogend, James.Bottomley, deller, maddy, mpe, npiggin, chleroy,
pjw, palmer, aou, alex, hca, gor, agordeev, borntraeger, svens,
ysato, dalias, glaubitz, richard, anton.ivanov, johannes, luto,
tglx, mingo, bp, dave.hansen, hpa, chris, jcmvbkbc, peterz, wad,
ruanjinjie, thuth, mark.rutland, ada.coupriediaz, kevin.brodsky,
linusw, yeoreum.yun, song, james.morse, anshuman.khandual,
broonie, liqiang01, pengcan, ryan.roberts, yangtiezhu, sshegde,
mchauras, austin.kim, jchrist, arnd, thomas.weissschuh,
sohil.mehta, andrew.cooper3, jgross, kas, x86, linux-alpha,
linux-kernel, linux-arm-kernel, linux-mm, linux-csky, loongarch,
linux-m68k, linux-mips, linux-parisc, linuxppc-dev, linux-riscv,
linux-s390, linux-sh, linux-um
Move the rseq_syscall() check earlier in the syscall exit path to ensure
it operates on the original instruction pointer (regs->pc) before any
potential modification by a tracer.
[Background]
When CONFIG_DEBUG_RSEQ is enabled, rseq_syscall() verifies that a system
call was not executed within an rseq critical section by examining
regs->pc. If a violation is detected, it triggers a SIGSEGV.
[Problem]
Currently, arm64 invokes rseq_syscall() after report_syscall_exit().
However, during report_syscall_exit(), a ptrace tracer can modify the
task's instruction pointer via PTRACE_SETREGSET (with NT_PRSTATUS). This
leads to an inconsistency where rseq may analyze a post-trace PC instead
of the actual PC at the time of syscall exit.
[Why this matters]
The rseq check is intended to validate the execution context of the
syscall itself. Analyzing a tracer-modified PC can lead to incorrect
detection or missed violations. Moving the check earlier ensures rseq
sees the authentic state of the task.
[Alignment]
This change aligns arm64 with:
- Generic entry, which calls rseq_syscall() first.
- arm32 implementation, which also performs the check before audit.
[Impact]
There is no functional change to signal delivery; SIGSEGV will still be
processed in arm64_exit_to_user_mode() at the end of the exit path.
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Thomas Gleixner <tglx@kernel.org>
Cc: Will Deacon <will@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: Ada Couprie Diaz <ada.coupriediaz@arm.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Reviewed-by: Yeoreum Yun <yeoreum.yun@arm.com>
Reviewed-by: Kevin Brodsky <kevin.brodsky@arm.com>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/arm64/kernel/ptrace.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index ae71cadbd4df..bc08c93c69c5 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -2455,6 +2455,8 @@ int syscall_trace_enter(struct pt_regs *regs, unsigned long flags)
void syscall_trace_exit(struct pt_regs *regs, unsigned long flags)
{
+ rseq_syscall(regs);
+
audit_syscall_exit(regs);
if (flags & _TIF_SYSCALL_TRACEPOINT)
@@ -2462,8 +2464,6 @@ void syscall_trace_exit(struct pt_regs *regs, unsigned long flags)
if (flags & (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP))
report_syscall_exit(regs);
-
- rseq_syscall(regs);
}
/*
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v16 08/18] arm64: ptrace: Rename syscall_trace_exit() to syscall_exit_work()
2026-06-29 13:05 [PATCH v16 00/18] arm64: entry: Convert to Generic Entry Jinjie Ruan
` (6 preceding siblings ...)
2026-06-29 13:06 ` [PATCH v16 07/18] arm64: ptrace: Protect rseq_syscall() from tracer PC modifications Jinjie Ruan
@ 2026-06-29 13:06 ` Jinjie Ruan
2026-06-29 13:06 ` [PATCH v16 09/18] arm64: syscall: Rework the syscall exit path in el0_svc_common() Jinjie Ruan
` (9 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Jinjie Ruan @ 2026-06-29 13:06 UTC (permalink / raw)
To: oleg, richard.henderson, mattst88, linmag7, linux,
catalin.marinas, will, kees, guoren, chenhuacai, kernel, geert,
tsbogend, James.Bottomley, deller, maddy, mpe, npiggin, chleroy,
pjw, palmer, aou, alex, hca, gor, agordeev, borntraeger, svens,
ysato, dalias, glaubitz, richard, anton.ivanov, johannes, luto,
tglx, mingo, bp, dave.hansen, hpa, chris, jcmvbkbc, peterz, wad,
ruanjinjie, thuth, mark.rutland, ada.coupriediaz, kevin.brodsky,
linusw, yeoreum.yun, song, james.morse, anshuman.khandual,
broonie, liqiang01, pengcan, ryan.roberts, yangtiezhu, sshegde,
mchauras, austin.kim, jchrist, arnd, thomas.weissschuh,
sohil.mehta, andrew.cooper3, jgross, kas, x86, linux-alpha,
linux-kernel, linux-arm-kernel, linux-mm, linux-csky, loongarch,
linux-m68k, linux-mips, linux-parisc, linuxppc-dev, linux-riscv,
linux-s390, linux-sh, linux-um
In preparation for moving arm64 over to the generic entry code, rename
syscall_trace_exit() to syscall_exit_work(). The renamed function checks
and prevents illegal system calls inside user-space rseq critical
sections, while also handling tracing, auditing, and ptrace reporting.
No functional changes.
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Thomas Gleixner <tglx@kernel.org>
Cc: Will Deacon <will@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Ada Couprie Diaz <ada.coupriediaz@arm.com>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/arm64/include/asm/syscall.h | 2 +-
arch/arm64/kernel/ptrace.c | 2 +-
arch/arm64/kernel/syscall.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/include/asm/syscall.h b/arch/arm64/include/asm/syscall.h
index 30b203ef156b..8205af0be612 100644
--- a/arch/arm64/include/asm/syscall.h
+++ b/arch/arm64/include/asm/syscall.h
@@ -121,6 +121,6 @@ static inline int syscall_get_arch(struct task_struct *task)
}
int syscall_trace_enter(struct pt_regs *regs, unsigned long flags);
-void syscall_trace_exit(struct pt_regs *regs, unsigned long flags);
+void syscall_exit_work(struct pt_regs *regs, unsigned long flags);
#endif /* __ASM_SYSCALL_H */
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index bc08c93c69c5..9ebe3389451c 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -2453,7 +2453,7 @@ int syscall_trace_enter(struct pt_regs *regs, unsigned long flags)
return syscall;
}
-void syscall_trace_exit(struct pt_regs *regs, unsigned long flags)
+void syscall_exit_work(struct pt_regs *regs, unsigned long flags)
{
rseq_syscall(regs);
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index c8e116397cfd..43ffb74162c5 100644
--- a/arch/arm64/kernel/syscall.c
+++ b/arch/arm64/kernel/syscall.c
@@ -133,7 +133,7 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
trace_exit:
flags = read_thread_flags();
- syscall_trace_exit(regs, flags);
+ syscall_exit_work(regs, flags);
}
void do_el0_svc(struct pt_regs *regs)
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v16 09/18] arm64: syscall: Rework the syscall exit path in el0_svc_common()
2026-06-29 13:05 [PATCH v16 00/18] arm64: entry: Convert to Generic Entry Jinjie Ruan
` (7 preceding siblings ...)
2026-06-29 13:06 ` [PATCH v16 08/18] arm64: ptrace: Rename syscall_trace_exit() to syscall_exit_work() Jinjie Ruan
@ 2026-06-29 13:06 ` Jinjie Ruan
2026-06-29 13:06 ` [PATCH v16 10/18] arm64: ptrace: Extract syscall_exit_to_user_mode_work() helper Jinjie Ruan
` (8 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Jinjie Ruan @ 2026-06-29 13:06 UTC (permalink / raw)
To: oleg, richard.henderson, mattst88, linmag7, linux,
catalin.marinas, will, kees, guoren, chenhuacai, kernel, geert,
tsbogend, James.Bottomley, deller, maddy, mpe, npiggin, chleroy,
pjw, palmer, aou, alex, hca, gor, agordeev, borntraeger, svens,
ysato, dalias, glaubitz, richard, anton.ivanov, johannes, luto,
tglx, mingo, bp, dave.hansen, hpa, chris, jcmvbkbc, peterz, wad,
ruanjinjie, thuth, mark.rutland, ada.coupriediaz, kevin.brodsky,
linusw, yeoreum.yun, song, james.morse, anshuman.khandual,
broonie, liqiang01, pengcan, ryan.roberts, yangtiezhu, sshegde,
mchauras, austin.kim, jchrist, arnd, thomas.weissschuh,
sohil.mehta, andrew.cooper3, jgross, kas, x86, linux-alpha,
linux-kernel, linux-arm-kernel, linux-mm, linux-csky, loongarch,
linux-m68k, linux-mips, linux-parisc, linuxppc-dev, linux-riscv,
linux-s390, linux-sh, linux-um
In preparation for moving arm64 over to the generic entry code,
restructure the fast-path syscall exit sequence within el0_svc_common().
Invert the nested conditional flags check so that when syscall work is
pending or single-stepping is active, the corresponding exit work can be
dispatched directly from within the fast-path bailout block. This clarifies
the separation between the fast and slow exit paths, facilitating a cleaner
transition to the generic entry state machine in subsequent patches.
No functional changes.
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Ada Couprie Diaz <ada.coupriediaz@arm.com>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/arm64/kernel/syscall.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index 43ffb74162c5..f6e9aa132b09 100644
--- a/arch/arm64/kernel/syscall.c
+++ b/arch/arm64/kernel/syscall.c
@@ -127,8 +127,11 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
*/
if (!has_syscall_work(flags) && !IS_ENABLED(CONFIG_DEBUG_RSEQ)) {
flags = read_thread_flags();
- if (!has_syscall_work(flags) && !(flags & _TIF_SINGLESTEP))
- return;
+ if (has_syscall_work(flags) || flags & _TIF_SINGLESTEP) {
+ flags = read_thread_flags();
+ syscall_exit_work(regs, flags);
+ }
+ return;
}
trace_exit:
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v16 10/18] arm64: ptrace: Extract syscall_exit_to_user_mode_work() helper
2026-06-29 13:05 [PATCH v16 00/18] arm64: entry: Convert to Generic Entry Jinjie Ruan
` (8 preceding siblings ...)
2026-06-29 13:06 ` [PATCH v16 09/18] arm64: syscall: Rework the syscall exit path in el0_svc_common() Jinjie Ruan
@ 2026-06-29 13:06 ` Jinjie Ruan
2026-06-29 13:06 ` [PATCH v16 11/18] arm64: ptrace: Align syscall exit work semantics with generic entry Jinjie Ruan
` (7 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Jinjie Ruan @ 2026-06-29 13:06 UTC (permalink / raw)
To: oleg, richard.henderson, mattst88, linmag7, linux,
catalin.marinas, will, kees, guoren, chenhuacai, kernel, geert,
tsbogend, James.Bottomley, deller, maddy, mpe, npiggin, chleroy,
pjw, palmer, aou, alex, hca, gor, agordeev, borntraeger, svens,
ysato, dalias, glaubitz, richard, anton.ivanov, johannes, luto,
tglx, mingo, bp, dave.hansen, hpa, chris, jcmvbkbc, peterz, wad,
ruanjinjie, thuth, mark.rutland, ada.coupriediaz, kevin.brodsky,
linusw, yeoreum.yun, song, james.morse, anshuman.khandual,
broonie, liqiang01, pengcan, ryan.roberts, yangtiezhu, sshegde,
mchauras, austin.kim, jchrist, arnd, thomas.weissschuh,
sohil.mehta, andrew.cooper3, jgross, kas, x86, linux-alpha,
linux-kernel, linux-arm-kernel, linux-mm, linux-csky, loongarch,
linux-m68k, linux-mips, linux-parisc, linuxppc-dev, linux-riscv,
linux-s390, linux-sh, linux-um
In preparation for moving arm64 over to the generic entry code, extract
the core syscall exit tracing logic into a new inline helper,
syscall_exit_to_user_mode_work().
This new helper encapsulates the thread flags retrieval and syscall exit
processing, unifying the exit invocation paths across both the fast-path
bailout block and the slow-path trace_exit fallback in el0_svc_common().
This restructuring significantly streamlines the architecture for
the upcoming transition to the generic entry framework.
No functional changes.
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Ada Couprie Diaz <ada.coupriediaz@arm.com>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/arm64/include/asm/syscall.h | 7 +++++++
arch/arm64/kernel/syscall.c | 9 +++------
2 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/include/asm/syscall.h b/arch/arm64/include/asm/syscall.h
index 8205af0be612..72461c22bb5e 100644
--- a/arch/arm64/include/asm/syscall.h
+++ b/arch/arm64/include/asm/syscall.h
@@ -123,4 +123,11 @@ static inline int syscall_get_arch(struct task_struct *task)
int syscall_trace_enter(struct pt_regs *regs, unsigned long flags);
void syscall_exit_work(struct pt_regs *regs, unsigned long flags);
+static __always_inline void syscall_exit_to_user_mode_work(struct pt_regs *regs)
+{
+ unsigned long flags = read_thread_flags();
+
+ syscall_exit_work(regs, flags);
+}
+
#endif /* __ASM_SYSCALL_H */
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index f6e9aa132b09..6de1fe281d61 100644
--- a/arch/arm64/kernel/syscall.c
+++ b/arch/arm64/kernel/syscall.c
@@ -127,16 +127,13 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
*/
if (!has_syscall_work(flags) && !IS_ENABLED(CONFIG_DEBUG_RSEQ)) {
flags = read_thread_flags();
- if (has_syscall_work(flags) || flags & _TIF_SINGLESTEP) {
- flags = read_thread_flags();
- syscall_exit_work(regs, flags);
- }
+ if (has_syscall_work(flags) || flags & _TIF_SINGLESTEP)
+ syscall_exit_to_user_mode_work(regs);
return;
}
trace_exit:
- flags = read_thread_flags();
- syscall_exit_work(regs, flags);
+ syscall_exit_to_user_mode_work(regs);
}
void do_el0_svc(struct pt_regs *regs)
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v16 11/18] arm64: ptrace: Align syscall exit work semantics with generic entry
2026-06-29 13:05 [PATCH v16 00/18] arm64: entry: Convert to Generic Entry Jinjie Ruan
` (9 preceding siblings ...)
2026-06-29 13:06 ` [PATCH v16 10/18] arm64: ptrace: Extract syscall_exit_to_user_mode_work() helper Jinjie Ruan
@ 2026-06-29 13:06 ` Jinjie Ruan
2026-06-29 13:06 ` [PATCH v16 12/18] arm64: syscall: Use exit-specific flags check in el0_svc_common() Jinjie Ruan
` (6 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Jinjie Ruan @ 2026-06-29 13:06 UTC (permalink / raw)
To: oleg, richard.henderson, mattst88, linmag7, linux,
catalin.marinas, will, kees, guoren, chenhuacai, kernel, geert,
tsbogend, James.Bottomley, deller, maddy, mpe, npiggin, chleroy,
pjw, palmer, aou, alex, hca, gor, agordeev, borntraeger, svens,
ysato, dalias, glaubitz, richard, anton.ivanov, johannes, luto,
tglx, mingo, bp, dave.hansen, hpa, chris, jcmvbkbc, peterz, wad,
ruanjinjie, thuth, mark.rutland, ada.coupriediaz, kevin.brodsky,
linusw, yeoreum.yun, song, james.morse, anshuman.khandual,
broonie, liqiang01, pengcan, ryan.roberts, yangtiezhu, sshegde,
mchauras, austin.kim, jchrist, arnd, thomas.weissschuh,
sohil.mehta, andrew.cooper3, jgross, kas, x86, linux-alpha,
linux-kernel, linux-arm-kernel, linux-mm, linux-csky, loongarch,
linux-m68k, linux-mips, linux-parisc, linuxppc-dev, linux-riscv,
linux-s390, linux-sh, linux-um
Streamline syscall_exit_to_user_mode_work() to align arm64's syscall
exit behavior with the generic entry framework.
[Rationale]
1. Unconditional RSEQ Execution: Relocate rseq_syscall() from the slow-path
helper to the very beginning of syscall_exit_to_user_mode_work(). This
ensures that RSEQ validation executes unconditionally across all exit
scenarios, preventing it from being incorrectly bypassed on fast paths
when CONFIG_DEBUG_RSEQ is active.
2. Centralized Exit Work Gating: Introduce the `_TIF_SYSCALL_EXIT_WORK`
mask to aggregate exit thread flags and gate the execution of
syscall_exit_work().
Gating audit_syscall_exit() behind this exit-time check introduces
no functional changes. The `SYSCALL_AUDIT` flag and its context are
statically allocated via audit_alloc() at fork time and only freed via
audit_free() at do_exit(). Since the flag remains persistent and static
throughout syscall execution, checking `_TIF_SYSCALL_AUDIT` in the mask
is fully equivalent to evaluating audit_context() inside
audit_syscall_exit().
[Changes]
- Introduce the `_TIF_SYSCALL_EXIT_WORK` mask to bundle exit-specific
flags.
- Relocate rseq_syscall() to run unconditionally on the outermost layer.
- Gate syscall_exit_work() via the new aggregated flag check to mirror
the generic entry loop behavior.
No functional changes intended.
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Ada Couprie Diaz <ada.coupriediaz@arm.com>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/arm64/include/asm/syscall.h | 6 +++++-
arch/arm64/include/asm/thread_info.h | 3 +++
arch/arm64/kernel/ptrace.c | 3 ---
3 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/include/asm/syscall.h b/arch/arm64/include/asm/syscall.h
index 72461c22bb5e..b982398f8765 100644
--- a/arch/arm64/include/asm/syscall.h
+++ b/arch/arm64/include/asm/syscall.h
@@ -8,6 +8,7 @@
#include <uapi/linux/audit.h>
#include <linux/compat.h>
#include <linux/err.h>
+#include <linux/rseq.h>
typedef long (*syscall_fn_t)(const struct pt_regs *regs);
@@ -127,7 +128,10 @@ static __always_inline void syscall_exit_to_user_mode_work(struct pt_regs *regs)
{
unsigned long flags = read_thread_flags();
- syscall_exit_work(regs, flags);
+ rseq_syscall(regs);
+
+ if (unlikely(flags & _TIF_SYSCALL_EXIT_WORK) || flags & _TIF_SINGLESTEP)
+ syscall_exit_work(regs, flags);
}
#endif /* __ASM_SYSCALL_H */
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index 5d7fe3e153c8..56a2c9426a32 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -112,6 +112,9 @@ void arch_setup_new_exec(void);
_TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \
_TIF_SYSCALL_EMU)
+#define _TIF_SYSCALL_EXIT_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
+ _TIF_SYSCALL_TRACEPOINT)
+
#ifdef CONFIG_SHADOW_CALL_STACK
#define INIT_SCS \
.scs_base = init_shadow_call_stack, \
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 9ebe3389451c..05ceb9f2d038 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -28,7 +28,6 @@
#include <linux/hw_breakpoint.h>
#include <linux/regset.h>
#include <linux/elf.h>
-#include <linux/rseq.h>
#include <asm/compat.h>
#include <asm/cpufeature.h>
@@ -2455,8 +2454,6 @@ int syscall_trace_enter(struct pt_regs *regs, unsigned long flags)
void syscall_exit_work(struct pt_regs *regs, unsigned long flags)
{
- rseq_syscall(regs);
-
audit_syscall_exit(regs);
if (flags & _TIF_SYSCALL_TRACEPOINT)
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v16 12/18] arm64: syscall: Use exit-specific flags check in el0_svc_common()
2026-06-29 13:05 [PATCH v16 00/18] arm64: entry: Convert to Generic Entry Jinjie Ruan
` (10 preceding siblings ...)
2026-06-29 13:06 ` [PATCH v16 11/18] arm64: ptrace: Align syscall exit work semantics with generic entry Jinjie Ruan
@ 2026-06-29 13:06 ` Jinjie Ruan
2026-06-29 13:06 ` [PATCH v16 13/18] arm64: syscall: Simplify el0_svc_common() syscall exit path Jinjie Ruan
` (5 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Jinjie Ruan @ 2026-06-29 13:06 UTC (permalink / raw)
To: oleg, richard.henderson, mattst88, linmag7, linux,
catalin.marinas, will, kees, guoren, chenhuacai, kernel, geert,
tsbogend, James.Bottomley, deller, maddy, mpe, npiggin, chleroy,
pjw, palmer, aou, alex, hca, gor, agordeev, borntraeger, svens,
ysato, dalias, glaubitz, richard, anton.ivanov, johannes, luto,
tglx, mingo, bp, dave.hansen, hpa, chris, jcmvbkbc, peterz, wad,
ruanjinjie, thuth, mark.rutland, ada.coupriediaz, kevin.brodsky,
linusw, yeoreum.yun, song, james.morse, anshuman.khandual,
broonie, liqiang01, pengcan, ryan.roberts, yangtiezhu, sshegde,
mchauras, austin.kim, jchrist, arnd, thomas.weissschuh,
sohil.mehta, andrew.cooper3, jgross, kas, x86, linux-alpha,
linux-kernel, linux-arm-kernel, linux-mm, linux-csky, loongarch,
linux-m68k, linux-mips, linux-parisc, linuxppc-dev, linux-riscv,
linux-s390, linux-sh, linux-um
Use exit-specific _TIF_SYSCALL_EXIT_WORK mask to filter out entry-only
flags during the system call exit path checks. This aligns arm64 with
the generic entry framework's SYSCALL_WORK_EXIT semantics.
[Rationale]
The current syscall exit path re-evaluates the thread flags using
the global _TIF_SYSCALL_WORK mask. However, _TIF_SYSCALL_WORK includes
flags that are strictly relevant to system call entry processing:
1. _TIF_SECCOMP: Seccomp filtering (__secure_computing()) only runs
on entry. There is no seccomp callback for syscall exit.
2. _TIF_SYSCALL_EMU: In PTRACE_SYSEMU mode, the syscall is
intercepted and skipped on entry. Since the syscall is never fully
executed, reporting a separate syscall exit stop is unnecessary.
[Changes]
- _TIF_SYSCALL_EXIT_WORK: A new mask containing only flags
requiring exit-time processing: _TIF_SYSCALL_TRACE, _TIF_SYSCALL_AUDIT,
and _TIF_SYSCALL_TRACEPOINT.
- Optimize re-evaluation check: Use _TIF_SYSCALL_EXIT_WORK inside the
el0_svc_common() fast-path block to prevent redundant exit work execution
when entry-only flags fluctuate or are synchronously modified under
the hood. The outermost gating maintains _TIF_SYSCALL_WORK to preserve
architectural entry-exit symmetry for tracers.
- Cleanup: Remove the has_syscall_work() helper as it is no longer
needed, supporting direct flag comparison to clearly distinguish between
entry and exit mandates.
[Impact]
Unnecessary exit tracing and auditing processing are safely bypassed when
entry-specific flags fluctuate during the fast-path re-check block. This
safely streamlines the syscall exit sequence to mirror the generic entry
loop behaviors without breaking debugger expectations.
No functional changes intended
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Ada Couprie Diaz <ada.coupriediaz@arm.com>
Reviewed-by: Ada Couprie Diaz <ada.coupriediaz@arm.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Reviewed-by: Yeoreum Yun <yeoreum.yun@arm.com>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/arm64/kernel/syscall.c | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index 6de1fe281d61..5dd94bece929 100644
--- a/arch/arm64/kernel/syscall.c
+++ b/arch/arm64/kernel/syscall.c
@@ -54,11 +54,6 @@ static void invoke_syscall(struct pt_regs *regs, unsigned int scno,
syscall_set_return_value(current, regs, 0, ret);
}
-static inline bool has_syscall_work(unsigned long flags)
-{
- return unlikely(flags & _TIF_SYSCALL_WORK);
-}
-
static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
const syscall_fn_t syscall_table[])
{
@@ -95,7 +90,7 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
return;
}
- if (has_syscall_work(flags)) {
+ if (unlikely(flags & _TIF_SYSCALL_WORK)) {
/*
* The de-facto standard way to skip a system call using ptrace
* is to set the system call to -1 (NO_SYSCALL) and set x0 to a
@@ -125,9 +120,9 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
* check again. However, if we were tracing entry, then we always trace
* exit regardless, as the old entry assembly did.
*/
- if (!has_syscall_work(flags) && !IS_ENABLED(CONFIG_DEBUG_RSEQ)) {
+ if (!(unlikely(flags & _TIF_SYSCALL_WORK)) && !IS_ENABLED(CONFIG_DEBUG_RSEQ)) {
flags = read_thread_flags();
- if (has_syscall_work(flags) || flags & _TIF_SINGLESTEP)
+ if (unlikely(flags & _TIF_SYSCALL_EXIT_WORK) || flags & _TIF_SINGLESTEP)
syscall_exit_to_user_mode_work(regs);
return;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v16 13/18] arm64: syscall: Simplify el0_svc_common() syscall exit path
2026-06-29 13:05 [PATCH v16 00/18] arm64: entry: Convert to Generic Entry Jinjie Ruan
` (11 preceding siblings ...)
2026-06-29 13:06 ` [PATCH v16 12/18] arm64: syscall: Use exit-specific flags check in el0_svc_common() Jinjie Ruan
@ 2026-06-29 13:06 ` Jinjie Ruan
2026-06-29 13:06 ` [PATCH v16 14/18] arm64: syscall: Simplify syscall exit path in el0_svc_common() Jinjie Ruan
` (4 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Jinjie Ruan @ 2026-06-29 13:06 UTC (permalink / raw)
To: oleg, richard.henderson, mattst88, linmag7, linux,
catalin.marinas, will, kees, guoren, chenhuacai, kernel, geert,
tsbogend, James.Bottomley, deller, maddy, mpe, npiggin, chleroy,
pjw, palmer, aou, alex, hca, gor, agordeev, borntraeger, svens,
ysato, dalias, glaubitz, richard, anton.ivanov, johannes, luto,
tglx, mingo, bp, dave.hansen, hpa, chris, jcmvbkbc, peterz, wad,
ruanjinjie, thuth, mark.rutland, ada.coupriediaz, kevin.brodsky,
linusw, yeoreum.yun, song, james.morse, anshuman.khandual,
broonie, liqiang01, pengcan, ryan.roberts, yangtiezhu, sshegde,
mchauras, austin.kim, jchrist, arnd, thomas.weissschuh,
sohil.mehta, andrew.cooper3, jgross, kas, x86, linux-alpha,
linux-kernel, linux-arm-kernel, linux-mm, linux-csky, loongarch,
linux-m68k, linux-mips, linux-parisc, linuxppc-dev, linux-riscv,
linux-s390, linux-sh, linux-um
Remove the redundant nested conditional check within the system call
exit path of el0_svc_common() to streamline the exit sequence.
When entering this fast-path block, CONFIG_DEBUG_RSEQ is guaranteed to be
disabled. Under this constraint, the code logic inside the block becomes
completely identical to the evaluation performed within
syscall_exit_to_user_mode_work(). Therefore, invoking the inline helper
directly achieves full logical equivalence while eliminating duplicate
code nesting.
No functional changes.
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Ada Couprie Diaz <ada.coupriediaz@arm.com>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/arm64/kernel/syscall.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index 5dd94bece929..74308b6df43b 100644
--- a/arch/arm64/kernel/syscall.c
+++ b/arch/arm64/kernel/syscall.c
@@ -121,9 +121,7 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
* exit regardless, as the old entry assembly did.
*/
if (!(unlikely(flags & _TIF_SYSCALL_WORK)) && !IS_ENABLED(CONFIG_DEBUG_RSEQ)) {
- flags = read_thread_flags();
- if (unlikely(flags & _TIF_SYSCALL_EXIT_WORK) || flags & _TIF_SINGLESTEP)
- syscall_exit_to_user_mode_work(regs);
+ syscall_exit_to_user_mode_work(regs);
return;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v16 14/18] arm64: syscall: Simplify syscall exit path in el0_svc_common()
2026-06-29 13:05 [PATCH v16 00/18] arm64: entry: Convert to Generic Entry Jinjie Ruan
` (12 preceding siblings ...)
2026-06-29 13:06 ` [PATCH v16 13/18] arm64: syscall: Simplify el0_svc_common() syscall exit path Jinjie Ruan
@ 2026-06-29 13:06 ` Jinjie Ruan
2026-06-29 13:06 ` [PATCH v16 15/18] arm64: ptrace: Skip syscall exit reporting for PTRACE_SYSEMU_SINGLESTEP Jinjie Ruan
` (3 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Jinjie Ruan @ 2026-06-29 13:06 UTC (permalink / raw)
To: oleg, richard.henderson, mattst88, linmag7, linux,
catalin.marinas, will, kees, guoren, chenhuacai, kernel, geert,
tsbogend, James.Bottomley, deller, maddy, mpe, npiggin, chleroy,
pjw, palmer, aou, alex, hca, gor, agordeev, borntraeger, svens,
ysato, dalias, glaubitz, richard, anton.ivanov, johannes, luto,
tglx, mingo, bp, dave.hansen, hpa, chris, jcmvbkbc, peterz, wad,
ruanjinjie, thuth, mark.rutland, ada.coupriediaz, kevin.brodsky,
linusw, yeoreum.yun, song, james.morse, anshuman.khandual,
broonie, liqiang01, pengcan, ryan.roberts, yangtiezhu, sshegde,
mchauras, austin.kim, jchrist, arnd, thomas.weissschuh,
sohil.mehta, andrew.cooper3, jgross, kas, x86, linux-alpha,
linux-kernel, linux-arm-kernel, linux-mm, linux-csky, loongarch,
linux-m68k, linux-mips, linux-parisc, linuxppc-dev, linux-riscv,
linux-s390, linux-sh, linux-um
Remove the redundant conditional fast-path check within el0_svc_common()
as both branches now execute the exact the same
syscall_exit_to_user_mode_work().
Since both the conditional fast-path and the fallback slow-path now
uniformly invoke syscall_exit_to_user_mode_work(), this explicit
conditional branch is entirely redundant regardless of whether
the evaluation is true or false. Removing it collapses the duplicated
logic into a single, unconditional path.
No functional changes.
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Ada Couprie Diaz <ada.coupriediaz@arm.com>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/arm64/kernel/syscall.c | 11 -----------
1 file changed, 11 deletions(-)
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index 74308b6df43b..275cde8ab6f4 100644
--- a/arch/arm64/kernel/syscall.c
+++ b/arch/arm64/kernel/syscall.c
@@ -114,17 +114,6 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
}
invoke_syscall(regs, scno, sc_nr, syscall_table);
-
- /*
- * The tracing status may have changed under our feet, so we have to
- * check again. However, if we were tracing entry, then we always trace
- * exit regardless, as the old entry assembly did.
- */
- if (!(unlikely(flags & _TIF_SYSCALL_WORK)) && !IS_ENABLED(CONFIG_DEBUG_RSEQ)) {
- syscall_exit_to_user_mode_work(regs);
- return;
- }
-
trace_exit:
syscall_exit_to_user_mode_work(regs);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v16 15/18] arm64: ptrace: Skip syscall exit reporting for PTRACE_SYSEMU_SINGLESTEP
2026-06-29 13:05 [PATCH v16 00/18] arm64: entry: Convert to Generic Entry Jinjie Ruan
` (13 preceding siblings ...)
2026-06-29 13:06 ` [PATCH v16 14/18] arm64: syscall: Simplify syscall exit path in el0_svc_common() Jinjie Ruan
@ 2026-06-29 13:06 ` Jinjie Ruan
2026-06-29 13:06 ` [PATCH v16 16/18] arm64: entry: Convert to generic entry Jinjie Ruan
` (2 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Jinjie Ruan @ 2026-06-29 13:06 UTC (permalink / raw)
To: oleg, richard.henderson, mattst88, linmag7, linux,
catalin.marinas, will, kees, guoren, chenhuacai, kernel, geert,
tsbogend, James.Bottomley, deller, maddy, mpe, npiggin, chleroy,
pjw, palmer, aou, alex, hca, gor, agordeev, borntraeger, svens,
ysato, dalias, glaubitz, richard, anton.ivanov, johannes, luto,
tglx, mingo, bp, dave.hansen, hpa, chris, jcmvbkbc, peterz, wad,
ruanjinjie, thuth, mark.rutland, ada.coupriediaz, kevin.brodsky,
linusw, yeoreum.yun, song, james.morse, anshuman.khandual,
broonie, liqiang01, pengcan, ryan.roberts, yangtiezhu, sshegde,
mchauras, austin.kim, jchrist, arnd, thomas.weissschuh,
sohil.mehta, andrew.cooper3, jgross, kas, x86, linux-alpha,
linux-kernel, linux-arm-kernel, linux-mm, linux-csky, loongarch,
linux-m68k, linux-mips, linux-parisc, linuxppc-dev, linux-riscv,
linux-s390, linux-sh, linux-um
Align the syscall exit reporting logic with the generic entry
framework by skipping the exit stop when PTRACE_SYSEMU_SINGLESTEP is
in effect.
[Rationale]
When a tracer uses PTRACE_SYSEMU_SINGLESTEP, both _TIF_SYSCALL_EMU
and _TIF_SINGLESTEP flags are set. Currently, arm64 reports a syscall
exit stop whenever _TIF_SINGLESTEP is set, regardless of the
emulation state.
However, as per the generic entry implementation (see
include/linux/entry-common.h):
"If SYSCALL_EMU is set, then the only reason to report is when SINGLESTEP
is set (i.e. PTRACE_SYSEMU_SINGLESTEP). This syscall instruction has been
already reported in syscall_trace_enter()."
Since PTRACE_SYSEMU intercepts and skips the actual syscall
execution, reporting a subsequent exit stop is redundant and
inconsistent with the expected behavior of emulated system calls.
[Changes]
- Introduce report_single_step(): Add a helper to encapsulate the
logic for deciding whether to report a single-step stop at syscall
exit. It returns false if _TIF_SYSCALL_EMU is set, ensuring the
emulated syscall does not trigger a duplicate report.
- Update syscall_exit_work(): Use the new helper to determine
the stepping state instead of directly checking _TIF_SINGLESTEP.
[Impact]
- PTRACE_SINGLESTEP: Continues to report exit stops for actual
instructions.
- PTRACE_SYSEMU: Continues to skip exit stops.
- PTRACE_SYSEMU_SINGLESTEP: Now correctly skips the redundant exit
stop, aligning arm64 with the generic entry infrastructure.
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: Ada Couprie Diaz <ada.coupriediaz@arm.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Reviewed-by: Yeoreum Yun <yeoreum.yun@arm.com>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/arm64/kernel/ptrace.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 05ceb9f2d038..650db9b47373 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -2452,14 +2452,25 @@ int syscall_trace_enter(struct pt_regs *regs, unsigned long flags)
return syscall;
}
+static inline bool report_single_step(unsigned long flags)
+{
+ if (flags & _TIF_SYSCALL_EMU)
+ return false;
+
+ return flags & _TIF_SINGLESTEP;
+}
+
void syscall_exit_work(struct pt_regs *regs, unsigned long flags)
{
+ bool step;
+
audit_syscall_exit(regs);
if (flags & _TIF_SYSCALL_TRACEPOINT)
trace_sys_exit(regs, syscall_get_return_value(current, regs));
- if (flags & (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP))
+ step = report_single_step(flags);
+ if (step || flags & _TIF_SYSCALL_TRACE)
report_syscall_exit(regs);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v16 16/18] arm64: entry: Convert to generic entry
2026-06-29 13:05 [PATCH v16 00/18] arm64: entry: Convert to Generic Entry Jinjie Ruan
` (14 preceding siblings ...)
2026-06-29 13:06 ` [PATCH v16 15/18] arm64: ptrace: Skip syscall exit reporting for PTRACE_SYSEMU_SINGLESTEP Jinjie Ruan
@ 2026-06-29 13:06 ` Jinjie Ruan
2026-06-29 13:06 ` [PATCH v16 17/18] arm64: Inline el0_svc_common() Jinjie Ruan
2026-06-29 13:06 ` [PATCH v16 18/18] arm64: vdso: Expose sigreturn address on vdso to the kernel Jinjie Ruan
17 siblings, 0 replies; 21+ messages in thread
From: Jinjie Ruan @ 2026-06-29 13:06 UTC (permalink / raw)
To: oleg, richard.henderson, mattst88, linmag7, linux,
catalin.marinas, will, kees, guoren, chenhuacai, kernel, geert,
tsbogend, James.Bottomley, deller, maddy, mpe, npiggin, chleroy,
pjw, palmer, aou, alex, hca, gor, agordeev, borntraeger, svens,
ysato, dalias, glaubitz, richard, anton.ivanov, johannes, luto,
tglx, mingo, bp, dave.hansen, hpa, chris, jcmvbkbc, peterz, wad,
ruanjinjie, thuth, mark.rutland, ada.coupriediaz, kevin.brodsky,
linusw, yeoreum.yun, song, james.morse, anshuman.khandual,
broonie, liqiang01, pengcan, ryan.roberts, yangtiezhu, sshegde,
mchauras, austin.kim, jchrist, arnd, thomas.weissschuh,
sohil.mehta, andrew.cooper3, jgross, kas, x86, linux-alpha,
linux-kernel, linux-arm-kernel, linux-mm, linux-csky, loongarch,
linux-m68k, linux-mips, linux-parisc, linuxppc-dev, linux-riscv,
linux-s390, linux-sh, linux-um
Implement the generic entry framework for arm64 to handle system call
entry and exit. This follows the migration of x86, RISC-V, and LoongArch,
consolidating architecture-specific syscall tracing and auditing into
the common kernel entry infrastructure, making it easier to enable
advanced features on arm64, such as "Syscall User Dispatch" and "rseq time
slice extension" optimization.
[Background]
Arm64 has already adopted generic IRQ entry. Completing the conversion
to the generic syscall entry framework reduces architectural divergence,
simplifies maintenance, and allows arm64 to automatically benefit from
improvements in the common entry code.
[Changes]
1. Kconfig and Infrastructure:
- Select GENERIC_ENTRY and remove GENERIC_IRQ_ENTRY (now implied).
- Migrate struct thread_info to use the syscall_work field instead
of TIF flags for syscall-related tasks.
2. Thread Info and Flags:
- Remove definitions for TIF_SYSCALL_TRACE, TIF_SYSCALL_AUDIT,
TIF_SYSCALL_TRACEPOINT, TIF_SECCOMP, and TIF_SYSCALL_EMU.
- Replace _TIF_SYSCALL_WORK and _TIF_SYSCALL_EXIT_WORK with the
generic SYSCALL_WORK bitmask.
- Map single-step state to SYSCALL_EXIT_TRAP in debug-monitors.c.
3. Architecture-Specific Hooks (asm/entry-common.h):
- Implement arch_ptrace_report_syscall_entry() and _exit() by
porting the existing arm64 logic to the generic interface.
4. Cleanup and Refactoring:
- Remove redundant arm64-specific syscall tracing functions from
ptrace.c, including syscall_trace_enter(), syscall_exit_work(),
and related audit/step helpers.
- Update el0_svc_common() in syscall.c to use the generic
syscall_work checks and entry/exit call sites.
[Why this matters]
- Unified Interface: Aligns arm64 with the modern kernel entry standard.
- Improved Maintainability: Bug fixes in kernel/entry/common.c now
apply to arm64 automatically.
- Feature Readiness: Simplifies the implementation of future
cross-architecture syscall features.
[Compatibility]
This conversion maintains full ABI compatibility with existing
userspace. The ptrace register-saving behavior, seccomp filtering, and
syscall tracing semantics remain identical to the previous implementation.
Additionally, since arm64 now does not select HAVE_GENERIC_TIF_BITS, there
is no functional change regarding rseq management, as those generic entry
pathways remain a no-op for this architecture."
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Thomas Gleixner <tglx@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Tested-by: Ada Couprie Diaz <ada.coupriediaz@arm.com>
Reviewed-by: Ada Couprie Diaz <ada.coupriediaz@arm.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Yeoreum Yun <yeoreum.yun@arm.com>
Reviewed-by: Kevin Brodsky <kevin.brodsky@arm.com>
Suggested-by: Kevin Brodsky <kevin.brodsky@arm.com>
Suggested-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/arm64/Kconfig | 2 +-
arch/arm64/include/asm/entry-common.h | 76 ++++++++++++++
arch/arm64/include/asm/syscall.h | 13 ---
arch/arm64/include/asm/thread_info.h | 19 +---
arch/arm64/kernel/debug-monitors.c | 8 ++
arch/arm64/kernel/ptrace.c | 142 --------------------------
arch/arm64/kernel/signal.c | 2 +-
arch/arm64/kernel/syscall.c | 7 +-
8 files changed, 92 insertions(+), 177 deletions(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b3afe0688919..aea686dce3d5 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -128,9 +128,9 @@ config ARM64
select GENERIC_CPU_DEVICES
select GENERIC_CPU_VULNERABILITIES
select GENERIC_EARLY_IOREMAP
+ select GENERIC_ENTRY
select GENERIC_IDLE_POLL_SETUP
select GENERIC_IOREMAP
- select GENERIC_IRQ_ENTRY
select GENERIC_IRQ_IPI
select GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD
select GENERIC_IRQ_PROBE
diff --git a/arch/arm64/include/asm/entry-common.h b/arch/arm64/include/asm/entry-common.h
index cab8cd78f693..d8bf4bf342e8 100644
--- a/arch/arm64/include/asm/entry-common.h
+++ b/arch/arm64/include/asm/entry-common.h
@@ -3,14 +3,21 @@
#ifndef _ASM_ARM64_ENTRY_COMMON_H
#define _ASM_ARM64_ENTRY_COMMON_H
+#include <linux/ptrace.h>
#include <linux/thread_info.h>
+#include <asm/compat.h>
#include <asm/cpufeature.h>
#include <asm/daifflags.h>
#include <asm/fpsimd.h>
#include <asm/mte.h>
#include <asm/stacktrace.h>
+enum ptrace_syscall_dir {
+ PTRACE_SYSCALL_ENTER = 0,
+ PTRACE_SYSCALL_EXIT,
+};
+
#define ARCH_EXIT_TO_USER_MODE_WORK (_TIF_MTE_ASYNC_FAULT | _TIF_FOREIGN_FPSTATE)
static __always_inline void arch_exit_to_user_mode_work(struct pt_regs *regs,
@@ -54,4 +61,73 @@ static inline bool arch_irqentry_exit_need_resched(void)
#define arch_irqentry_exit_need_resched arch_irqentry_exit_need_resched
+static __always_inline unsigned long ptrace_save_reg(struct pt_regs *regs,
+ enum ptrace_syscall_dir dir,
+ int *regno)
+{
+ unsigned long saved_reg;
+
+ /*
+ * We have some ABI weirdness here in the way that we handle syscall
+ * exit stops because we indicate whether or not the stop has been
+ * signalled from syscall entry or syscall exit by clobbering a general
+ * purpose register (ip/r12 for AArch32, x7 for AArch64) in the tracee
+ * and restoring its old value after the stop. This means that:
+ *
+ * - Any writes by the tracer to this register during the stop are
+ * ignored/discarded.
+ *
+ * - The actual value of the register is not available during the stop,
+ * so the tracer cannot save it and restore it later.
+ *
+ * - Syscall stops behave differently to seccomp and pseudo-step traps
+ * (the latter do not nobble any registers).
+ */
+ *regno = (is_compat_task() ? 12 : 7);
+ saved_reg = regs->regs[*regno];
+ regs->regs[*regno] = dir;
+
+ return saved_reg;
+}
+
+static __always_inline int arch_ptrace_report_syscall_entry(struct pt_regs *regs)
+{
+ unsigned long saved_reg;
+ int regno, ret;
+
+ saved_reg = ptrace_save_reg(regs, PTRACE_SYSCALL_ENTER, ®no);
+ ret = ptrace_report_syscall_entry(regs);
+ if (ret)
+ forget_syscall(regs);
+ regs->regs[regno] = saved_reg;
+
+ return ret;
+}
+
+#define arch_ptrace_report_syscall_entry arch_ptrace_report_syscall_entry
+
+static __always_inline void arch_ptrace_report_syscall_exit(struct pt_regs *regs,
+ int step)
+{
+ unsigned long saved_reg;
+ int regno;
+
+ saved_reg = ptrace_save_reg(regs, PTRACE_SYSCALL_EXIT, ®no);
+ if (!step) {
+ ptrace_report_syscall_exit(regs, 0);
+ regs->regs[regno] = saved_reg;
+ } else {
+ regs->regs[regno] = saved_reg;
+
+ /*
+ * Signal a pseudo-step exception since we are stepping but
+ * tracer modifications to the registers may have rewound the
+ * state machine.
+ */
+ ptrace_report_syscall_exit(regs, 1);
+ }
+}
+
+#define arch_ptrace_report_syscall_exit arch_ptrace_report_syscall_exit
+
#endif /* _ASM_ARM64_ENTRY_COMMON_H */
diff --git a/arch/arm64/include/asm/syscall.h b/arch/arm64/include/asm/syscall.h
index b982398f8765..84b1c36233d4 100644
--- a/arch/arm64/include/asm/syscall.h
+++ b/arch/arm64/include/asm/syscall.h
@@ -121,17 +121,4 @@ static inline int syscall_get_arch(struct task_struct *task)
return AUDIT_ARCH_AARCH64;
}
-int syscall_trace_enter(struct pt_regs *regs, unsigned long flags);
-void syscall_exit_work(struct pt_regs *regs, unsigned long flags);
-
-static __always_inline void syscall_exit_to_user_mode_work(struct pt_regs *regs)
-{
- unsigned long flags = read_thread_flags();
-
- rseq_syscall(regs);
-
- if (unlikely(flags & _TIF_SYSCALL_EXIT_WORK) || flags & _TIF_SINGLESTEP)
- syscall_exit_work(regs, flags);
-}
-
#endif /* __ASM_SYSCALL_H */
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index 56a2c9426a32..3f621ba0f961 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -46,6 +46,7 @@ struct thread_info {
u64 mpam_partid_pmg;
#endif
u32 cpu;
+ unsigned long syscall_work; /* SYSCALL_WORK_ flags */
};
#define thread_saved_pc(tsk) \
@@ -68,11 +69,6 @@ void arch_setup_new_exec(void);
#define TIF_UPROBE 5 /* uprobe breakpoint or singlestep */
#define TIF_MTE_ASYNC_FAULT 6 /* MTE Asynchronous Tag Check Fault */
#define TIF_NOTIFY_SIGNAL 7 /* signal notifications exist */
-#define TIF_SYSCALL_TRACE 8 /* syscall trace active */
-#define TIF_SYSCALL_AUDIT 9 /* syscall auditing */
-#define TIF_SYSCALL_TRACEPOINT 10 /* syscall tracepoint for ftrace */
-#define TIF_SECCOMP 11 /* syscall secure computing */
-#define TIF_SYSCALL_EMU 12 /* syscall emulation active */
#define TIF_PATCH_PENDING 13 /* pending live patching update */
#define TIF_MEMDIE 18 /* is terminating due to OOM killer */
#define TIF_FREEZE 19
@@ -94,27 +90,14 @@ void arch_setup_new_exec(void);
#define _TIF_NEED_RESCHED_LAZY (1 << TIF_NEED_RESCHED_LAZY)
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
#define _TIF_FOREIGN_FPSTATE (1 << TIF_FOREIGN_FPSTATE)
-#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
-#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
-#define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT)
-#define _TIF_SECCOMP (1 << TIF_SECCOMP)
-#define _TIF_SYSCALL_EMU (1 << TIF_SYSCALL_EMU)
#define _TIF_PATCH_PENDING (1 << TIF_PATCH_PENDING)
#define _TIF_UPROBE (1 << TIF_UPROBE)
-#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
#define _TIF_32BIT (1 << TIF_32BIT)
#define _TIF_SVE (1 << TIF_SVE)
#define _TIF_MTE_ASYNC_FAULT (1 << TIF_MTE_ASYNC_FAULT)
#define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL)
#define _TIF_TSC_SIGSEGV (1 << TIF_TSC_SIGSEGV)
-#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
- _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \
- _TIF_SYSCALL_EMU)
-
-#define _TIF_SYSCALL_EXIT_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
- _TIF_SYSCALL_TRACEPOINT)
-
#ifdef CONFIG_SHADOW_CALL_STACK
#define INIT_SCS \
.scs_base = init_shadow_call_stack, \
diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c
index 29307642f4c9..c53683839155 100644
--- a/arch/arm64/kernel/debug-monitors.c
+++ b/arch/arm64/kernel/debug-monitors.c
@@ -385,11 +385,19 @@ void user_enable_single_step(struct task_struct *task)
if (!test_and_set_ti_thread_flag(ti, TIF_SINGLESTEP))
set_regs_spsr_ss(task_pt_regs(task));
+
+ /*
+ * Ensure that the generic entry code triggers a trap once stepping
+ * out of a system call prior to executing any user instruction,
+ * as the generic entry code does not natively check for TIF_SINGLESTEP.
+ */
+ set_task_syscall_work(task, SYSCALL_EXIT_TRAP);
}
NOKPROBE_SYMBOL(user_enable_single_step);
void user_disable_single_step(struct task_struct *task)
{
clear_ti_thread_flag(task_thread_info(task), TIF_SINGLESTEP);
+ clear_task_syscall_work(task, SYSCALL_EXIT_TRAP);
}
NOKPROBE_SYMBOL(user_disable_single_step);
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 650db9b47373..61a668682947 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -8,7 +8,6 @@
* Copyright (C) 2012 ARM Ltd.
*/
-#include <linux/audit.h>
#include <linux/compat.h>
#include <linux/kernel.h>
#include <linux/sched/signal.h>
@@ -18,7 +17,6 @@
#include <linux/smp.h>
#include <linux/ptrace.h>
#include <linux/user.h>
-#include <linux/seccomp.h>
#include <linux/security.h>
#include <linux/init.h>
#include <linux/signal.h>
@@ -37,13 +35,9 @@
#include <asm/mte.h>
#include <asm/pointer_auth.h>
#include <asm/stacktrace.h>
-#include <asm/syscall.h>
#include <asm/traps.h>
#include <asm/system_misc.h>
-#define CREATE_TRACE_POINTS
-#include <trace/events/syscalls.h>
-
struct pt_regs_offset {
const char *name;
int offset;
@@ -2338,142 +2332,6 @@ long arch_ptrace(struct task_struct *child, long request,
return ptrace_request(child, request, addr, data);
}
-enum ptrace_syscall_dir {
- PTRACE_SYSCALL_ENTER = 0,
- PTRACE_SYSCALL_EXIT,
-};
-
-static __always_inline unsigned long ptrace_save_reg(struct pt_regs *regs,
- enum ptrace_syscall_dir dir,
- int *regno)
-{
- unsigned long saved_reg;
-
- /*
- * We have some ABI weirdness here in the way that we handle syscall
- * exit stops because we indicate whether or not the stop has been
- * signalled from syscall entry or syscall exit by clobbering a general
- * purpose register (ip/r12 for AArch32, x7 for AArch64) in the tracee
- * and restoring its old value after the stop. This means that:
- *
- * - Any writes by the tracer to this register during the stop are
- * ignored/discarded.
- *
- * - The actual value of the register is not available during the stop,
- * so the tracer cannot save it and restore it later.
- *
- * - Syscall stops behave differently to seccomp and pseudo-step traps
- * (the latter do not nobble any registers).
- */
- *regno = (is_compat_task() ? 12 : 7);
- saved_reg = regs->regs[*regno];
- regs->regs[*regno] = dir;
-
- return saved_reg;
-}
-
-static int report_syscall_entry(struct pt_regs *regs)
-{
- unsigned long saved_reg;
- int regno, ret;
-
- saved_reg = ptrace_save_reg(regs, PTRACE_SYSCALL_ENTER, ®no);
- ret = ptrace_report_syscall_entry(regs);
- if (ret)
- forget_syscall(regs);
- regs->regs[regno] = saved_reg;
-
- return ret;
-}
-
-static void report_syscall_exit(struct pt_regs *regs)
-{
- unsigned long saved_reg;
- int regno;
-
- saved_reg = ptrace_save_reg(regs, PTRACE_SYSCALL_EXIT, ®no);
- if (!test_thread_flag(TIF_SINGLESTEP)) {
- ptrace_report_syscall_exit(regs, 0);
- regs->regs[regno] = saved_reg;
- } else {
- regs->regs[regno] = saved_reg;
-
- /*
- * Signal a pseudo-step exception since we are stepping but
- * tracer modifications to the registers may have rewound the
- * state machine.
- */
- ptrace_report_syscall_exit(regs, 1);
- }
-}
-
-static inline void syscall_enter_audit(struct pt_regs *regs, long syscall)
-{
- if (unlikely(audit_context())) {
- unsigned long args[6];
-
- syscall_get_arguments(current, regs, args);
- audit_syscall_entry(syscall, args[0], args[1], args[2], args[3]);
- }
-}
-
-int syscall_trace_enter(struct pt_regs *regs, unsigned long flags)
-{
- long syscall;
- int ret;
-
- if (flags & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE)) {
- ret = report_syscall_entry(regs);
- if (ret || (flags & _TIF_SYSCALL_EMU))
- return NO_SYSCALL;
- }
-
- /* Do the secure computing after ptrace; failures should be fast. */
- if (flags & _TIF_SECCOMP) {
- if (!__secure_computing())
- return NO_SYSCALL;
- }
-
- /* Either of the above might have changed the syscall number */
- syscall = syscall_get_nr(current, regs);
-
- if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) {
- trace_sys_enter(regs, syscall);
-
- /*
- * Probes or BPF hooks in the tracepoint may have changed the
- * system call number as well.
- */
- syscall = syscall_get_nr(current, regs);
- }
-
- syscall_enter_audit(regs, syscall);
-
- return syscall;
-}
-
-static inline bool report_single_step(unsigned long flags)
-{
- if (flags & _TIF_SYSCALL_EMU)
- return false;
-
- return flags & _TIF_SINGLESTEP;
-}
-
-void syscall_exit_work(struct pt_regs *regs, unsigned long flags)
-{
- bool step;
-
- audit_syscall_exit(regs);
-
- if (flags & _TIF_SYSCALL_TRACEPOINT)
- trace_sys_exit(regs, syscall_get_return_value(current, regs));
-
- step = report_single_step(flags);
- if (step || flags & _TIF_SYSCALL_TRACE)
- report_syscall_exit(regs);
-}
-
/*
* SPSR_ELx bits which are always architecturally RES0 per ARM DDI 0487D.a.
* We permit userspace to set SSBS (AArch64 bit 12, AArch32 bit 23) which is
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 38e6fa204c17..093eebb9d764 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -8,8 +8,8 @@
#include <linux/cache.h>
#include <linux/compat.h>
+#include <linux/entry-common.h>
#include <linux/errno.h>
-#include <linux/irq-entry-common.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/freezer.h>
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index 275cde8ab6f4..41a3b70a9374 100644
--- a/arch/arm64/kernel/syscall.c
+++ b/arch/arm64/kernel/syscall.c
@@ -2,6 +2,7 @@
#include <linux/compiler.h>
#include <linux/context_tracking.h>
+#include <linux/entry-common.h>
#include <linux/errno.h>
#include <linux/nospec.h>
#include <linux/ptrace.h>
@@ -58,6 +59,7 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
const syscall_fn_t syscall_table[])
{
unsigned long flags = read_thread_flags();
+ unsigned long work;
regs->orig_x0 = regs->regs[0];
regs->syscallno = scno;
@@ -90,7 +92,8 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
return;
}
- if (unlikely(flags & _TIF_SYSCALL_WORK)) {
+ work = READ_ONCE(current_thread_info()->syscall_work);
+ if (unlikely(work & SYSCALL_WORK_ENTER)) {
/*
* The de-facto standard way to skip a system call using ptrace
* is to set the system call to -1 (NO_SYSCALL) and set x0 to a
@@ -108,7 +111,7 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
*/
if (scno == NO_SYSCALL)
syscall_set_return_value(current, regs, -ENOSYS, 0);
- scno = syscall_trace_enter(regs, read_thread_flags());
+ scno = syscall_trace_enter(regs, work);
if (scno == NO_SYSCALL)
goto trace_exit;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v16 17/18] arm64: Inline el0_svc_common()
2026-06-29 13:05 [PATCH v16 00/18] arm64: entry: Convert to Generic Entry Jinjie Ruan
` (15 preceding siblings ...)
2026-06-29 13:06 ` [PATCH v16 16/18] arm64: entry: Convert to generic entry Jinjie Ruan
@ 2026-06-29 13:06 ` Jinjie Ruan
2026-06-29 13:06 ` [PATCH v16 18/18] arm64: vdso: Expose sigreturn address on vdso to the kernel Jinjie Ruan
17 siblings, 0 replies; 21+ messages in thread
From: Jinjie Ruan @ 2026-06-29 13:06 UTC (permalink / raw)
To: oleg, richard.henderson, mattst88, linmag7, linux,
catalin.marinas, will, kees, guoren, chenhuacai, kernel, geert,
tsbogend, James.Bottomley, deller, maddy, mpe, npiggin, chleroy,
pjw, palmer, aou, alex, hca, gor, agordeev, borntraeger, svens,
ysato, dalias, glaubitz, richard, anton.ivanov, johannes, luto,
tglx, mingo, bp, dave.hansen, hpa, chris, jcmvbkbc, peterz, wad,
ruanjinjie, thuth, mark.rutland, ada.coupriediaz, kevin.brodsky,
linusw, yeoreum.yun, song, james.morse, anshuman.khandual,
broonie, liqiang01, pengcan, ryan.roberts, yangtiezhu, sshegde,
mchauras, austin.kim, jchrist, arnd, thomas.weissschuh,
sohil.mehta, andrew.cooper3, jgross, kas, x86, linux-alpha,
linux-kernel, linux-arm-kernel, linux-mm, linux-csky, loongarch,
linux-m68k, linux-mips, linux-parisc, linuxppc-dev, linux-riscv,
linux-s390, linux-sh, linux-um
After converting arm64 to Generic Entry framework, the compiler no longer
inlines el0_svc_common() into its caller do_el0_svc(). This introduces
a small but measurable overhead in the critical system call path.
Manually forcing el0_svc_common() to be inlined restores the
performance. Benchmarking with perf bench syscall basic on a
Kunpeng 920 platform (based on v6.19-rc1) shows a ~1% performance
uplift.
Inlining this function reduces function prologue/epilogue overhead
and allows for better compiler optimization in the hot system call
dispatch path.
| Metric | W/O this patch | With this patch | Change |
| ---------- | -------------- | --------------- | --------- |
| Total time | 2.195 [sec] | 2.171 [sec] | ↓1.1% |
| usecs/op | 0.219575 | 0.217192 | ↓1.1% |
| ops/sec | 4,554,260 | 4,604,225 | ↑1.1% |
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: Ada Couprie Diaz <ada.coupriediaz@arm.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Reviewed-by: Yeoreum Yun <yeoreum.yun@arm.com>
Reviewed-by: Kevin Brodsky <kevin.brodsky@arm.com>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/arm64/kernel/syscall.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index 41a3b70a9374..e0a98fac3b85 100644
--- a/arch/arm64/kernel/syscall.c
+++ b/arch/arm64/kernel/syscall.c
@@ -55,8 +55,8 @@ static void invoke_syscall(struct pt_regs *regs, unsigned int scno,
syscall_set_return_value(current, regs, 0, ret);
}
-static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
- const syscall_fn_t syscall_table[])
+static __always_inline void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
+ const syscall_fn_t syscall_table[])
{
unsigned long flags = read_thread_flags();
unsigned long work;
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v16 18/18] arm64: vdso: Expose sigreturn address on vdso to the kernel
2026-06-29 13:05 [PATCH v16 00/18] arm64: entry: Convert to Generic Entry Jinjie Ruan
` (16 preceding siblings ...)
2026-06-29 13:06 ` [PATCH v16 17/18] arm64: Inline el0_svc_common() Jinjie Ruan
@ 2026-06-29 13:06 ` Jinjie Ruan
17 siblings, 0 replies; 21+ messages in thread
From: Jinjie Ruan @ 2026-06-29 13:06 UTC (permalink / raw)
To: oleg, richard.henderson, mattst88, linmag7, linux,
catalin.marinas, will, kees, guoren, chenhuacai, kernel, geert,
tsbogend, James.Bottomley, deller, maddy, mpe, npiggin, chleroy,
pjw, palmer, aou, alex, hca, gor, agordeev, borntraeger, svens,
ysato, dalias, glaubitz, richard, anton.ivanov, johannes, luto,
tglx, mingo, bp, dave.hansen, hpa, chris, jcmvbkbc, peterz, wad,
ruanjinjie, thuth, mark.rutland, ada.coupriediaz, kevin.brodsky,
linusw, yeoreum.yun, song, james.morse, anshuman.khandual,
broonie, liqiang01, pengcan, ryan.roberts, yangtiezhu, sshegde,
mchauras, austin.kim, jchrist, arnd, thomas.weissschuh,
sohil.mehta, andrew.cooper3, jgross, kas, x86, linux-alpha,
linux-kernel, linux-arm-kernel, linux-mm, linux-csky, loongarch,
linux-m68k, linux-mips, linux-parisc, linuxppc-dev, linux-riscv,
linux-s390, linux-sh, linux-um
Syscall User Dispatch (SUD) requires the signal trampoline code to not be
intercepted. This is necessary to support returning with a locked selector
while avoiding infinite recursion back into the signal handler.
Implement arch_syscall_is_vdso_sigreturn() for arm64 to support this
exclusion mechanism. For native 64-bit tasks, it checks whether the current
PC matches the 'svc #0' instruction inside the vDSO sigreturn trampoline.
SYM_CODE_START(__kernel_rt_sigreturn)
mov x8, #__NR_rt_sigreturn
svc #0
SYM_CODE_END(__kernel_rt_sigreturn)
For COMPAT tasks, it verifies if the instruction falls within
the architecture's 'sigpage' range, allowing the kernel to safely bypass
dispatching syscalls originating from these areas back to userspace.
Suggested-by: Kevin Brodsky <kevin.brodsky@arm.com>
Suggested-by: kemal <kmal@cock.li>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/arm64/include/asm/elf.h | 1 +
arch/arm64/kernel/vdso.c | 16 ++++++++++++++++
2 files changed, 17 insertions(+)
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index d2779d604c7b..f43d4dea916a 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -185,6 +185,7 @@ do { \
struct linux_binprm;
extern int arch_setup_additional_pages(struct linux_binprm *bprm,
int uses_interp);
+extern bool arch_syscall_is_vdso_sigreturn(struct pt_regs *regs);
/* 1GB of VA */
#ifdef CONFIG_COMPAT
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index 592dd8668de4..5a0314a3c26e 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -343,3 +343,19 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
return ret;
}
+
+bool arch_syscall_is_vdso_sigreturn(struct pt_regs *regs)
+{
+ unsigned long sigtramp;
+
+#ifdef CONFIG_COMPAT
+ if (is_compat_task()) {
+ unsigned long sigpage = (unsigned long)current->mm->context.sigpage;
+
+ return regs->pc >= sigpage && regs->pc < (sigpage + PAGE_SIZE);
+ }
+#endif
+ sigtramp = (unsigned long)VDSO_SYMBOL(current->mm->context.vdso, sigtramp);
+
+ return regs->pc == (sigtramp + 8);
+}
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread