* [PATCH v17 00/15] arm64: entry: Convert to Generic Entry
@ 2026-07-21 8:18 Jinjie Ruan
2026-07-21 8:18 ` [PATCH v17 01/15] arm64: ptrace: Skip syscall exit reporting for PTRACE_SYSEMU_SINGLESTEP Jinjie Ruan
` (14 more replies)
0 siblings, 15 replies; 31+ messages in thread
From: Jinjie Ruan @ 2026-07-21 8:18 UTC (permalink / raw)
To: catalin.marinas, will, kees, oleg, luto, wad, thuth, peterz,
mark.rutland, linusw, ada.coupriediaz, kevin.brodsky,
yeoreum.yun, anshuman.khandual, james.morse, tglx, broonie,
pengcan, ryan.roberts, liqiang01, linux-arm-kernel, linux-kernel,
linux-mm
Cc: ruanjinjie
This is the 17th iteration of the patch series. I would like to express
my sincere gratitude to everyone who has contributed to the reviews
and testing across the previous versions, which helped significantly
refine this work.
Currently, architectures such as x86, Riscv, Loongarch and S390 use
the Generic Entry, which significantly eases maintenance burden
and improves code elegance. Given that arm64 has already successfully
adopted the Generic IRQ Entry in commit b3cf07851b6c ("arm64: entry: Switch
to generic IRQ entry"), it is now the right time to completely convert
arm64 to the Generic Entry infrastructure.
The objective of this series is to bring arm64 in line with other major
architectures, reducing duplicated boilerplate code and simplifying the
sharing of future improvements in entry/exit paths, such as "Syscall User
Dispatch" and "rseq time slice extension" optimizations.
This patch set is rebased on "core/entry". It contains the foundational
updates required for arm64. Following the suggestion from Linus Walleij,
these patches are being submitted separately for inclusion via
the arm64 tree.
Tested successfully on "Kunpeng HIP09" using the following test cases:
- stress-ng: CPU, Virtual Memory, Syscall, and Interrupt stress tests.
- hackbench: Evaluated in both thread and pipe modes.
- kselftests (ptrace): get_syscall_info, set_syscall_info, peeksiginfo.
- kselftests (breakpoints): breakpoint_test_arm64.
- kselftests (arm64/abi): syscall-abi and ptrace.
- kselftests (arm64/fp): fp-ptrace, sve-ptrace, and za-ptrace.
- kselftests (vDSO): vdso_test_getrandom.
- ptrace stress test: tracing stress-ng system calls under load.
- Pseudo-NMI load test using perf.
Changes in v17:
- Rebased on core/entry.
- Make return type of arm64_syscall_trace_enter() bool.
- Use vdso label for arch_syscall_is_vdso_sigreturn() to make it more
clear as Thomas suggested.
- Update the rework of audit_syscall_entry().
- Prefix these functions with arm64_ to clearly distinguish arch-specific
logic when switching to the generic entry framework.
- Merge some related patches to make it clearer, and adjust the patch
sequence so that bugfix patches come first.
- Update the commit message.
- Link to v16: https://lore.kernel.org/all/20260629130616.642022-1-ruanjinjie@huawei.com/
Changes in v16:
- Rebased on v7.2-rc1.
- Convert __secure_computing() to return boolean as Thomas suggested.
- Introduce a weak vesion for arch_syscall_is_vdso_sigreturn()
to simplify the code.
- Split out the implementation of arch_syscall_is_vdso_sigreturn()
into a separate patch to facilitate reviewing.
- Break down the syscall_exit_to_user_mode_work() refactoring into
5 smaller, bite-sized patches for easier review and justification.
- Update the comment and commit message as Ada suggeted.
- Clarify patch titles and align title prefixes for consistency.
- Collect Reviewed-by and Tesed-by.
- Link to v15: https://lore.kernel.org/all/20260511092103.1974980-1-ruanjinjie@huawei.com/
Changes in v15:
- Rebased on v7.1-rc1 and Mark's fix patch in [1].
- Solve issues Sashiko AI pointed out, "Fix potential syscall truncation
in syscall_trace_enter()".
- Make syscall_exit_to_user_mode_work() __always_inline to keep
the fast-path performance as Sashiko pointed out.
Changes in v14:
- Initialize ret = 0 in syscall_trace_enter().
- Split into two patch sets as Linus Walleij suggested, so this patch set
can be applied separately to the arm64 tree.
- Rebased on arm64 for-next/core branch.
- Collect Reviewed-by and Acked-by.
- Link to v13 resend: https://lore.kernel.org/all/20260317082020.737779-15-ruanjinjie@huawei.com/
Changes in v13 resend:
- Fix exit_to_user_mode_prepare_legacy() issues.
- Also move TIF_SINGLESTEP to generic TIF infrastructure for loongarch.
- Use generic TIF bits for arm64 and moving TIF_SINGLESTEP to
generic TIF for related architectures separately.
- Refactor syscall_trace_enter/exit() to accept flags and Use
syscall_get_nr() helper separately.
- Tested with slice_test for rseq optimizations.
- Add acked-by.
- Link to v13: https://lore.kernel.org/all/20260313094738.3985794-1-ruanjinjie@huawei.com/
Changes in v13:
- Rebased on v7.0-rc3, so drop the firt applied arm64 patch.
- Use generic TIF bits to enables RSEQ optimization.
- Update most of the commit message to make it more clear.
- Link to v12: https://lore.kernel.org/all/20260203133728.848283-1-ruanjinjie@huawei.com/
Changes in v12:
- Rebased on "sched/core", so remove the four generic entry patches.
- Move "Expand secure_computing() in place" and
"Use syscall_get_arguments() helper" patch forward, which will group all
non-functional cleanups at the front.
- Adjust the explanation for moving rseq_syscall() before
audit_syscall_exit().
- Link to v11: https://lore.kernel.org/all/20260128031934.3906955-1-ruanjinjie@huawei.com/
Changes in v11:
- Remove unused syscall in syscall_trace_enter().
- Update and provide a detailed explanation of the differences after
moving rseq_syscall() before audit_syscall_exit().
- Rebased on arm64 (for-next/entry), and remove the first applied 3 patchs.
- syscall_exit_to_user_mode_work() for arch reuse instead of adding
new syscall_exit_to_user_mode_work_prepare() helper.
- Link to v10: https://lore.kernel.org/all/20251222114737.1334364-1-ruanjinjie@huawei.com/
Changes in v10:
- Rebased on v6.19-rc1, rename syscall_exit_to_user_mode_prepare() to
syscall_exit_to_user_mode_work_prepare() to avoid conflict.
- Also inline syscall_trace_enter().
- Support aarch64 for sud_benchmark.
- Update and correct the commit message.
- Add Reviewed-by.
- Link to v9: https://lore.kernel.org/all/20251204082123.2792067-1-ruanjinjie@huawei.com/
Changes in v9:
- Move "Return early for ptrace_report_syscall_entry() error" patch ahead
to make it not introduce a regression.
- Not check _TIF_SECCOMP/SYSCALL_EMU for syscall_exit_work() in
a separate patch.
- Do not report_syscall_exit() for PTRACE_SYSEMU_SINGLESTEP in a separate
patch.
- Add two performance patch to improve the arm64 performance.
- Add Reviewed-by.
- Link to v8: https://lore.kernel.org/all/20251126071446.3234218-1-ruanjinjie@huawei.com/
Changes in v8:
- Rename "report_syscall_enter()" to "report_syscall_entry()".
- Add ptrace_save_reg() to avoid duplication.
- Remove unused _TIF_WORK_MASK in a standalone patch.
- Align syscall_trace_enter() return value with the generic version.
- Use "scno" instead of regs->syscallno in el0_svc_common().
- Move rseq_syscall() ahead in a standalone patch to clarify it clearly.
- Rename "syscall_trace_exit()" to "syscall_exit_work()".
- Keep the goto in el0_svc_common().
- No argument was passed to __secure_computing() and check -1 not -1L.
- Remove "Add has_syscall_work() helper" patch.
- Move "Add syscall_exit_to_user_mode_prepare() helper" patch later.
- Add miss header for asm/entry-common.h.
- Update the implementation of arch_syscall_is_vdso_sigreturn().
- Add "ARCH_SYSCALL_WORK_EXIT" to be defined as "SECCOMP | SYSCALL_EMU"
to keep the behaviour unchanged.
- Add more testcases test.
- Add Reviewed-by.
- Update the commit message.
- Link to v7: https://lore.kernel.org/all/20251117133048.53182-1-ruanjinjie@huawei.com/
Jinjie Ruan (15):
arm64: ptrace: Skip syscall exit reporting for
PTRACE_SYSEMU_SINGLESTEP
arm64: ptrace: Rework audit_syscall_entry()
arm64: ptrace: Open-code seccomp check in syscall_trace_enter()
arm64: ptrace: Rename and clean up syscall_trace_enter()
arm64: ptrace: Protect rseq_syscall() from tracer PC modifications
arm64: syscall: Rework the syscall exit path in el0_svc_common()
arm64: ptrace: Pass thread flags to trace enter/exit
arm64: ptrace: Extract arm64_syscall_exit_to_user_mode_work() helper
arm64: ptrace: Align syscall exit work semantics with generic entry
arm64: syscall: Use exit-specific flags check in el0_svc_common()
arm64: syscall: Simplify el0_svc_common() syscall exit path
arm64: ptrace: Make return type of arm64_syscall_trace_enter() bool
arm64: entry: Convert to generic entry
arm64: Inline el0_svc_common()
arm64: vdso: Expose sigreturn address on vdso to the kernel
arch/arm64/Kconfig | 3 +-
arch/arm64/include/asm/elf.h | 1 +
arch/arm64/include/asm/entry-common.h | 77 +++++++++++++++++
arch/arm64/include/asm/syscall.h | 5 +-
arch/arm64/include/asm/thread_info.h | 16 +---
arch/arm64/kernel/debug-monitors.c | 8 ++
arch/arm64/kernel/entry-common.c | 2 +-
arch/arm64/kernel/ptrace.c | 115 --------------------------
arch/arm64/kernel/signal.c | 2 +-
arch/arm64/kernel/syscall.c | 34 +++-----
arch/arm64/kernel/vdso.c | 16 ++++
arch/arm64/kernel/vdso/sigreturn.S | 1 +
arch/arm64/kernel/vdso/vdso.lds.S | 1 +
13 files changed, 122 insertions(+), 159 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH v17 01/15] arm64: ptrace: Skip syscall exit reporting for PTRACE_SYSEMU_SINGLESTEP
2026-07-21 8:18 [PATCH v17 00/15] arm64: entry: Convert to Generic Entry Jinjie Ruan
@ 2026-07-21 8:18 ` Jinjie Ruan
2026-07-21 8:18 ` [PATCH v17 02/15] arm64: ptrace: Rework audit_syscall_entry() Jinjie Ruan
` (13 subsequent siblings)
14 siblings, 0 replies; 31+ messages in thread
From: Jinjie Ruan @ 2026-07-21 8:18 UTC (permalink / raw)
To: catalin.marinas, will, kees, oleg, luto, wad, thuth, peterz,
mark.rutland, linusw, ada.coupriediaz, kevin.brodsky,
yeoreum.yun, anshuman.khandual, james.morse, tglx, broonie,
pengcan, ryan.roberts, liqiang01, linux-arm-kernel, linux-kernel,
linux-mm
Cc: ruanjinjie
According to the ptrace man page (Syscall-stops section):
"If the tracee was restarted by PTRACE_SYSCALL or PTRACE_SYSEMU,
the tracee enters syscall-enter-stop just prior to entering any
system call (which will not be executed if the restart was using
PTRACE_SYSEMU, regardless of any change made to registers at this
point or how the tracee is restarted after this stop). ...
If the tracee is continued using any other method (including
PTRACE_SYSEMU), no syscall-exit-stop occurs. Note that all mentions
PTRACE_SYSEMU apply equally to PTRACE_SYSEMU_SINGLESTEP."
When a tracer uses PTRACE_SYSEMU_SINGLESTEP, both _TIF_SYSCALL_EMU
and _TIF_SINGLESTEP are set. Currently, arm64 unconditionally reports
a syscall exit stop whenever _TIF_SINGLESTEP is set, regardless of the
emulation state. This deviates from the documented behavior and breaks
consistency with x86, where PTRACE_SYSEMU_SINGLESTEP does not trigger
a redundant exit stop.
[Changes]
- Introduce report_single_step(): Returns false when _TIF_SYSCALL_EMU
is set, ensuring emulated syscalls do not trigger a duplicate report.
- Update syscall_exit_work(): Use the new helper 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 documentation and the generic entry infrastructure.
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Fixes: ac2081cdc4d9 ("arm64: ptrace: Consistently use pseudo-singlestep exceptions")
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 | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 924805e0c8da..4e9c71d477a5 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -2482,16 +2482,26 @@ int syscall_trace_enter(struct pt_regs *regs)
return regs->syscallno;
}
+static inline bool report_single_step(unsigned long flags)
+{
+ if (flags & _TIF_SYSCALL_EMU)
+ return false;
+
+ return flags & _TIF_SINGLESTEP;
+}
+
void syscall_trace_exit(struct pt_regs *regs)
{
unsigned long flags = read_thread_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);
rseq_syscall(regs);
--
2.34.1
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH v17 02/15] arm64: ptrace: Rework audit_syscall_entry()
2026-07-21 8:18 [PATCH v17 00/15] arm64: entry: Convert to Generic Entry Jinjie Ruan
2026-07-21 8:18 ` [PATCH v17 01/15] arm64: ptrace: Skip syscall exit reporting for PTRACE_SYSEMU_SINGLESTEP Jinjie Ruan
@ 2026-07-21 8:18 ` Jinjie Ruan
2026-07-21 8:18 ` [PATCH v17 03/15] arm64: ptrace: Open-code seccomp check in syscall_trace_enter() Jinjie Ruan
` (12 subsequent siblings)
14 siblings, 0 replies; 31+ messages in thread
From: Jinjie Ruan @ 2026-07-21 8:18 UTC (permalink / raw)
To: catalin.marinas, will, kees, oleg, luto, wad, thuth, peterz,
mark.rutland, linusw, ada.coupriediaz, kevin.brodsky,
yeoreum.yun, anshuman.khandual, james.morse, tglx, broonie,
pengcan, ryan.roberts, liqiang01, linux-arm-kernel, linux-kernel,
linux-mm
Cc: ruanjinjie
Extract syscall_enter_audit() helper and switch to generic helpers to
get syscall number and syscall arguments, matching the generic entry
implementation.
The new code:
- Checks audit_context() first to avoid unnecessary work when audit
is not active.
- Use syscall_get_arguments() helper instead of directly accessing
regs fields.
- Use syscall_get_nr() helper to get syscall number instead of directly
accessing regs->syscallno.
- Now exactly equivalent to generic entry's syscall_enter_audit().
This is a preparation step for converting arm64 to the generic entry
infrastructure. 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 | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 4e9c71d477a5..643e63a65734 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -2458,6 +2458,17 @@ static void report_syscall_exit(struct pt_regs *regs)
}
}
+#ifdef CONFIG_AUDITSYSCALL
+static inline void syscall_enter_audit(struct pt_regs *regs)
+{
+ long syscall = syscall_get_nr(current, regs);
+ unsigned long args[6];
+
+ syscall_get_arguments(current, regs, args);
+ __audit_syscall_entry(syscall, args[0], args[1], args[2], args[3]);
+}
+#endif
+
int syscall_trace_enter(struct pt_regs *regs)
{
unsigned long flags = read_thread_flags();
@@ -2476,8 +2487,8 @@ int syscall_trace_enter(struct pt_regs *regs)
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
trace_sys_enter(regs, regs->syscallno);
- audit_syscall_entry(regs->syscallno, regs->orig_x0, regs->regs[1],
- regs->regs[2], regs->regs[3]);
+ if (unlikely(audit_context()))
+ syscall_enter_audit(regs);
return regs->syscallno;
}
--
2.34.1
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH v17 03/15] arm64: ptrace: Open-code seccomp check in syscall_trace_enter()
2026-07-21 8:18 [PATCH v17 00/15] arm64: entry: Convert to Generic Entry Jinjie Ruan
2026-07-21 8:18 ` [PATCH v17 01/15] arm64: ptrace: Skip syscall exit reporting for PTRACE_SYSEMU_SINGLESTEP Jinjie Ruan
2026-07-21 8:18 ` [PATCH v17 02/15] arm64: ptrace: Rework audit_syscall_entry() Jinjie Ruan
@ 2026-07-21 8:18 ` Jinjie Ruan
2026-07-21 8:18 ` [PATCH v17 04/15] arm64: ptrace: Rename and clean up syscall_trace_enter() Jinjie Ruan
` (11 subsequent siblings)
14 siblings, 0 replies; 31+ messages in thread
From: Jinjie Ruan @ 2026-07-21 8:18 UTC (permalink / raw)
To: catalin.marinas, will, kees, oleg, luto, wad, thuth, peterz,
mark.rutland, linusw, ada.coupriediaz, kevin.brodsky,
yeoreum.yun, anshuman.khandual, james.morse, tglx, broonie,
pengcan, ryan.roberts, liqiang01, linux-arm-kernel, linux-kernel,
linux-mm
Cc: ruanjinjie
Refactor syscall_trace_enter() by open-coding the seccomp check to
align with the generic entry framework.
The generic entry implementation expands the seccomp check in-place
by testing SYSCALL_WORK_SECCOMP and directly calling the underlying
__seccomp_permit_syscall() function. Moreover, generic entry explicitly
re-reads work flags after ptrace handling to ensure any updates to
seccomp work flags during the ptrace stop are observed.
Bring arm64 in line with this behavior:
- Re-read thread flags after ptrace handling.
- Test the updated flags for _TIF_SECCOMP and call
__seccomp_permit_syscall().
No functional changes are intended; this change simplifies future
migration to the generic entry framework.
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Link: https://lore.kernel.org/all/20260713025712.416366-1-ruanjinjie@huawei.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 | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 643e63a65734..cd0607ec70ef 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -2478,11 +2478,16 @@ int syscall_trace_enter(struct pt_regs *regs)
ret = report_syscall_entry(regs);
if (ret || (flags & _TIF_SYSCALL_EMU))
return NO_SYSCALL;
+
+ /* ptrace might have changed thread flags */
+ flags = read_thread_flags();
}
/* Do the secure computing after ptrace; failures should be fast. */
- if (!seccomp_permit_syscall())
- return NO_SYSCALL;
+ if (unlikely(flags & _TIF_SECCOMP)) {
+ if (!__seccomp_permit_syscall())
+ return NO_SYSCALL;
+ }
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
trace_sys_enter(regs, regs->syscallno);
--
2.34.1
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH v17 04/15] arm64: ptrace: Rename and clean up syscall_trace_enter()
2026-07-21 8:18 [PATCH v17 00/15] arm64: entry: Convert to Generic Entry Jinjie Ruan
` (2 preceding siblings ...)
2026-07-21 8:18 ` [PATCH v17 03/15] arm64: ptrace: Open-code seccomp check in syscall_trace_enter() Jinjie Ruan
@ 2026-07-21 8:18 ` Jinjie Ruan
2026-07-21 8:39 ` Linus Walleij
2026-07-21 8:18 ` [PATCH v17 05/15] arm64: ptrace: Protect rseq_syscall() from tracer PC modifications Jinjie Ruan
` (10 subsequent siblings)
14 siblings, 1 reply; 31+ messages in thread
From: Jinjie Ruan @ 2026-07-21 8:18 UTC (permalink / raw)
To: catalin.marinas, will, kees, oleg, luto, wad, thuth, peterz,
mark.rutland, linusw, ada.coupriediaz, kevin.brodsky,
yeoreum.yun, anshuman.khandual, james.morse, tglx, broonie,
pengcan, ryan.roberts, liqiang01, linux-arm-kernel, linux-kernel,
linux-mm
Cc: ruanjinjie
Rename syscall_trace_enter() to arm64_syscall_trace_enter() to avoid
name collisions and clarify the boundary when arm64 eventually switches
to the generic entry infrastructure.
In addition, replace direct accesses to regs->syscallno with the standard
syscall_get_nr() helper for both trace_sys_enter() and the return value.
This decouples the tracing logic from architecture-specific struct pt_regs
layouts, aligning the implementation with the generic entry pattern.
No functional changes intended; this is a preparation step for
converting arm64 to the generic entry infrastructure.
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/arm64/include/asm/syscall.h | 2 +-
arch/arm64/kernel/ptrace.c | 6 +++---
arch/arm64/kernel/syscall.c | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/arm64/include/asm/syscall.h b/arch/arm64/include/asm/syscall.h
index 5e4c7fc44f73..d1dabdcde41c 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);
+int arm64_syscall_trace_enter(struct pt_regs *regs);
void syscall_trace_exit(struct pt_regs *regs);
#endif /* __ASM_SYSCALL_H */
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index cd0607ec70ef..4c7dba12629c 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -2469,7 +2469,7 @@ static inline void syscall_enter_audit(struct pt_regs *regs)
}
#endif
-int syscall_trace_enter(struct pt_regs *regs)
+int arm64_syscall_trace_enter(struct pt_regs *regs)
{
unsigned long flags = read_thread_flags();
int ret;
@@ -2490,12 +2490,12 @@ int syscall_trace_enter(struct pt_regs *regs)
}
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
- trace_sys_enter(regs, regs->syscallno);
+ trace_sys_enter(regs, syscall_get_nr(current, regs));
if (unlikely(audit_context()))
syscall_enter_audit(regs);
- return regs->syscallno;
+ return syscall_get_nr(current, regs);
}
static inline bool report_single_step(unsigned long flags)
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index 358ddfbf1401..3e78e159b2a1 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 = arm64_syscall_trace_enter(regs);
if (scno == NO_SYSCALL)
goto trace_exit;
}
--
2.34.1
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH v17 05/15] arm64: ptrace: Protect rseq_syscall() from tracer PC modifications
2026-07-21 8:18 [PATCH v17 00/15] arm64: entry: Convert to Generic Entry Jinjie Ruan
` (3 preceding siblings ...)
2026-07-21 8:18 ` [PATCH v17 04/15] arm64: ptrace: Rename and clean up syscall_trace_enter() Jinjie Ruan
@ 2026-07-21 8:18 ` Jinjie Ruan
2026-07-21 8:18 ` [PATCH v17 06/15] arm64: syscall: Rework the syscall exit path in el0_svc_common() Jinjie Ruan
` (9 subsequent siblings)
14 siblings, 0 replies; 31+ messages in thread
From: Jinjie Ruan @ 2026-07-21 8:18 UTC (permalink / raw)
To: catalin.marinas, will, kees, oleg, luto, wad, thuth, peterz,
mark.rutland, linusw, ada.coupriediaz, kevin.brodsky,
yeoreum.yun, anshuman.khandual, james.morse, tglx, broonie,
pengcan, ryan.roberts, liqiang01, linux-arm-kernel, linux-kernel,
linux-mm
Cc: ruanjinjie
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 4c7dba12629c..a7091333a9e9 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -2511,6 +2511,8 @@ void syscall_trace_exit(struct pt_regs *regs)
unsigned long flags = read_thread_flags();
bool step;
+ rseq_syscall(regs);
+
audit_syscall_exit(regs);
if (flags & _TIF_SYSCALL_TRACEPOINT)
@@ -2519,8 +2521,6 @@ void syscall_trace_exit(struct pt_regs *regs)
step = report_single_step(flags);
if (step || flags & _TIF_SYSCALL_TRACE)
report_syscall_exit(regs);
-
- rseq_syscall(regs);
}
/*
--
2.34.1
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH v17 06/15] arm64: syscall: Rework the syscall exit path in el0_svc_common()
2026-07-21 8:18 [PATCH v17 00/15] arm64: entry: Convert to Generic Entry Jinjie Ruan
` (4 preceding siblings ...)
2026-07-21 8:18 ` [PATCH v17 05/15] arm64: ptrace: Protect rseq_syscall() from tracer PC modifications Jinjie Ruan
@ 2026-07-21 8:18 ` Jinjie Ruan
2026-07-21 8:43 ` Linus Walleij
2026-07-21 8:18 ` [PATCH v17 07/15] arm64: ptrace: Pass thread flags to trace enter/exit Jinjie Ruan
` (8 subsequent siblings)
14 siblings, 1 reply; 31+ messages in thread
From: Jinjie Ruan @ 2026-07-21 8:18 UTC (permalink / raw)
To: catalin.marinas, will, kees, oleg, luto, wad, thuth, peterz,
mark.rutland, linusw, ada.coupriediaz, kevin.brodsky,
yeoreum.yun, anshuman.khandual, james.morse, tglx, broonie,
pengcan, ryan.roberts, liqiang01, linux-arm-kernel, linux-kernel,
linux-mm
Cc: ruanjinjie
In preparation for moving arm64 over to the generic entry,
invert the nested conditional flags check within el0_svc_common().
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 | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index 3e78e159b2a1..b8d7d29a431b 100644
--- a/arch/arm64/kernel/syscall.c
+++ b/arch/arm64/kernel/syscall.c
@@ -127,8 +127,9 @@ 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)
+ syscall_trace_exit(regs);
+ return;
}
trace_exit:
--
2.34.1
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH v17 07/15] arm64: ptrace: Pass thread flags to trace enter/exit
2026-07-21 8:18 [PATCH v17 00/15] arm64: entry: Convert to Generic Entry Jinjie Ruan
` (5 preceding siblings ...)
2026-07-21 8:18 ` [PATCH v17 06/15] arm64: syscall: Rework the syscall exit path in el0_svc_common() Jinjie Ruan
@ 2026-07-21 8:18 ` Jinjie Ruan
2026-07-21 8:18 ` [PATCH v17 08/15] arm64: ptrace: Extract arm64_syscall_exit_to_user_mode_work() helper Jinjie Ruan
` (7 subsequent siblings)
14 siblings, 0 replies; 31+ messages in thread
From: Jinjie Ruan @ 2026-07-21 8:18 UTC (permalink / raw)
To: catalin.marinas, will, kees, oleg, luto, wad, thuth, peterz,
mark.rutland, linusw, ada.coupriediaz, kevin.brodsky,
yeoreum.yun, anshuman.khandual, james.morse, tglx, broonie,
pengcan, ryan.roberts, liqiang01, linux-arm-kernel, linux-kernel,
linux-mm
Cc: ruanjinjie
Move the reading of thread flags from inside arm64_syscall_trace_enter()
and syscall_trace_exit() to their callers. This aligns the function
signatures with the generic entry framework, where the caller
is responsible for supplying the flags.
In el0_svc_common(), the flags are now passed directly to the tracing
functions, and re-read before the enter/exit path to reflect any updates.
No functional change intended; this is a preparatory step for
converting arm64 to 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>
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 | 6 ++----
arch/arm64/kernel/syscall.c | 11 +++++++----
3 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/arch/arm64/include/asm/syscall.h b/arch/arm64/include/asm/syscall.h
index d1dabdcde41c..696739f5a250 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 arm64_syscall_trace_enter(struct pt_regs *regs);
-void syscall_trace_exit(struct pt_regs *regs);
+int arm64_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 a7091333a9e9..18fa29ae1425 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -2469,9 +2469,8 @@ static inline void syscall_enter_audit(struct pt_regs *regs)
}
#endif
-int arm64_syscall_trace_enter(struct pt_regs *regs)
+int arm64_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)) {
@@ -2506,9 +2505,8 @@ static inline bool report_single_step(unsigned long flags)
return flags & _TIF_SINGLESTEP;
}
-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();
bool step;
rseq_syscall(regs);
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index b8d7d29a431b..e778aac6fab9 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 = arm64_syscall_trace_enter(regs);
+ scno = arm64_syscall_trace_enter(regs, read_thread_flags());
if (scno == NO_SYSCALL)
goto trace_exit;
}
@@ -127,13 +127,16 @@ 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)
- syscall_trace_exit(regs);
+ if (has_syscall_work(flags) || flags & _TIF_SINGLESTEP) {
+ flags = read_thread_flags();
+ syscall_trace_exit(regs, flags);
+ }
return;
}
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 [flat|nested] 31+ messages in thread
* [PATCH v17 08/15] arm64: ptrace: Extract arm64_syscall_exit_to_user_mode_work() helper
2026-07-21 8:18 [PATCH v17 00/15] arm64: entry: Convert to Generic Entry Jinjie Ruan
` (6 preceding siblings ...)
2026-07-21 8:18 ` [PATCH v17 07/15] arm64: ptrace: Pass thread flags to trace enter/exit Jinjie Ruan
@ 2026-07-21 8:18 ` Jinjie Ruan
2026-07-21 8:45 ` Linus Walleij
2026-07-21 8:18 ` [PATCH v17 09/15] arm64: ptrace: Align syscall exit work semantics with generic entry Jinjie Ruan
` (6 subsequent siblings)
14 siblings, 1 reply; 31+ messages in thread
From: Jinjie Ruan @ 2026-07-21 8:18 UTC (permalink / raw)
To: catalin.marinas, will, kees, oleg, luto, wad, thuth, peterz,
mark.rutland, linusw, ada.coupriediaz, kevin.brodsky,
yeoreum.yun, anshuman.khandual, james.morse, tglx, broonie,
pengcan, ryan.roberts, liqiang01, linux-arm-kernel, linux-kernel,
linux-mm
Cc: ruanjinjie
Introduce a helper arm64_syscall_exit_to_user_mode_work() that
encapsulates the re-reading of thread flags and the call to
syscall_trace_exit(). Use it in el0_svc_common() to replace
the open-coded instances, removing the duplicated flags read
and making the control flow simpler.
This aligns the arm64 exit path with the pattern expected by the
generic entry infrastructure, which uses a similar
syscall_exit_to_user_mode_work() callback.
No functional changes intended; this is a preparation step for converting
arm64 to the generic entry infrastructure.
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 696739f5a250..3e4672ab4a4f 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 arm64_syscall_trace_enter(struct pt_regs *regs, unsigned long flags);
void syscall_trace_exit(struct pt_regs *regs, unsigned long flags);
+static __always_inline void arm64_syscall_exit_to_user_mode_work(struct pt_regs *regs)
+{
+ unsigned long flags = read_thread_flags();
+
+ syscall_trace_exit(regs, flags);
+}
+
#endif /* __ASM_SYSCALL_H */
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index e778aac6fab9..0061fc63e7ba 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_trace_exit(regs, flags);
- }
+ if (has_syscall_work(flags) || flags & _TIF_SINGLESTEP)
+ arm64_syscall_exit_to_user_mode_work(regs);
return;
}
trace_exit:
- flags = read_thread_flags();
- syscall_trace_exit(regs, flags);
+ arm64_syscall_exit_to_user_mode_work(regs);
}
void do_el0_svc(struct pt_regs *regs)
--
2.34.1
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH v17 09/15] arm64: ptrace: Align syscall exit work semantics with generic entry
2026-07-21 8:18 [PATCH v17 00/15] arm64: entry: Convert to Generic Entry Jinjie Ruan
` (7 preceding siblings ...)
2026-07-21 8:18 ` [PATCH v17 08/15] arm64: ptrace: Extract arm64_syscall_exit_to_user_mode_work() helper Jinjie Ruan
@ 2026-07-21 8:18 ` Jinjie Ruan
2026-07-21 8:46 ` Linus Walleij
2026-07-21 8:18 ` [PATCH v17 10/15] arm64: syscall: Use exit-specific flags check in el0_svc_common() Jinjie Ruan
` (5 subsequent siblings)
14 siblings, 1 reply; 31+ messages in thread
From: Jinjie Ruan @ 2026-07-21 8:18 UTC (permalink / raw)
To: catalin.marinas, will, kees, oleg, luto, wad, thuth, peterz,
mark.rutland, linusw, ada.coupriediaz, kevin.brodsky,
yeoreum.yun, anshuman.khandual, james.morse, tglx, broonie,
pengcan, ryan.roberts, liqiang01, linux-arm-kernel, linux-kernel,
linux-mm
Cc: ruanjinjie
Refactor the syscall exit path to better match the generic entry
framework. Specifically:
- Introduce `_TIF_SYSCALL_EXIT_WORK` to aggregate exit-time thread
flags (trace, audit, tracepoint).
- Rename `syscall_trace_exit()` to `arm64_syscall_exit_work()` to
better reflect its role.
- Move `rseq_syscall()` out of `arm64_syscall_exit_work()` and into
`arm64_syscall_exit_to_user_mode_work()` so that it runs
unconditionally on all exits, consistent with generic entry.
- Gate `arm64_syscall_exit_work()` behind the new flag check,
mirroring the generic entry exit's pattern.
Gating audit on `_TIF_SYSCALL_AUDIT` is equivalent to the previous
`audit_context()` check: the audit context and flag are statically
allocated at fork and freed at exit, remaining stable throughout
syscall execution.
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 | 8 ++++++--
arch/arm64/include/asm/thread_info.h | 3 +++
arch/arm64/kernel/ptrace.c | 5 +----
3 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/include/asm/syscall.h b/arch/arm64/include/asm/syscall.h
index 3e4672ab4a4f..7cc872fde019 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);
@@ -121,13 +122,16 @@ static inline int syscall_get_arch(struct task_struct *task)
}
int arm64_syscall_trace_enter(struct pt_regs *regs, unsigned long flags);
-void syscall_trace_exit(struct pt_regs *regs, unsigned long flags);
+void arm64_syscall_exit_work(struct pt_regs *regs, unsigned long flags);
static __always_inline void arm64_syscall_exit_to_user_mode_work(struct pt_regs *regs)
{
unsigned long flags = read_thread_flags();
- syscall_trace_exit(regs, flags);
+ rseq_syscall(regs);
+
+ if (unlikely(flags & _TIF_SYSCALL_EXIT_WORK) || flags & _TIF_SINGLESTEP)
+ arm64_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 18fa29ae1425..10ead67b4eaf 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>
@@ -2505,12 +2504,10 @@ static inline bool report_single_step(unsigned long flags)
return flags & _TIF_SINGLESTEP;
}
-void syscall_trace_exit(struct pt_regs *regs, unsigned long flags)
+void arm64_syscall_exit_work(struct pt_regs *regs, unsigned long flags)
{
bool step;
- rseq_syscall(regs);
-
audit_syscall_exit(regs);
if (flags & _TIF_SYSCALL_TRACEPOINT)
--
2.34.1
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH v17 10/15] arm64: syscall: Use exit-specific flags check in el0_svc_common()
2026-07-21 8:18 [PATCH v17 00/15] arm64: entry: Convert to Generic Entry Jinjie Ruan
` (8 preceding siblings ...)
2026-07-21 8:18 ` [PATCH v17 09/15] arm64: ptrace: Align syscall exit work semantics with generic entry Jinjie Ruan
@ 2026-07-21 8:18 ` Jinjie Ruan
2026-07-21 8:18 ` [PATCH v17 11/15] arm64: syscall: Simplify el0_svc_common() syscall exit path Jinjie Ruan
` (4 subsequent siblings)
14 siblings, 0 replies; 31+ messages in thread
From: Jinjie Ruan @ 2026-07-21 8:18 UTC (permalink / raw)
To: catalin.marinas, will, kees, oleg, luto, wad, thuth, peterz,
mark.rutland, linusw, ada.coupriediaz, kevin.brodsky,
yeoreum.yun, anshuman.khandual, james.morse, tglx, broonie,
pengcan, ryan.roberts, liqiang01, linux-arm-kernel, linux-kernel,
linux-mm
Cc: ruanjinjie
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 (__seccomp_permit_syscall()) 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
syscall exit 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 0061fc63e7ba..a8e0bf8d362e 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)
arm64_syscall_exit_to_user_mode_work(regs);
return;
}
--
2.34.1
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH v17 11/15] arm64: syscall: Simplify el0_svc_common() syscall exit path
2026-07-21 8:18 [PATCH v17 00/15] arm64: entry: Convert to Generic Entry Jinjie Ruan
` (9 preceding siblings ...)
2026-07-21 8:18 ` [PATCH v17 10/15] arm64: syscall: Use exit-specific flags check in el0_svc_common() Jinjie Ruan
@ 2026-07-21 8:18 ` Jinjie Ruan
2026-07-21 8:51 ` Linus Walleij
2026-07-21 8:18 ` [PATCH v17 12/15] arm64: ptrace: Make return type of arm64_syscall_trace_enter() bool Jinjie Ruan
` (3 subsequent siblings)
14 siblings, 1 reply; 31+ messages in thread
From: Jinjie Ruan @ 2026-07-21 8:18 UTC (permalink / raw)
To: catalin.marinas, will, kees, oleg, luto, wad, thuth, peterz,
mark.rutland, linusw, ada.coupriediaz, kevin.brodsky,
yeoreum.yun, anshuman.khandual, james.morse, tglx, broonie,
pengcan, ryan.roberts, liqiang01, linux-arm-kernel, linux-kernel,
linux-mm
Cc: ruanjinjie
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 so the call of rseq_syscall() is a no-op. Under this constraint,
the code logic inside the block becomes completely identical to what
the arm64_syscall_exit_to_user_mode_work() helper already does. Replace
that nested logic with a direct invocation of the helper, eliminating
redundant code.
Before:
| if (... && !IS_ENABLED(CONFIG_DEBUG_RSEQ)) {
| flags = read_thread_flags();
| if (unlikely(flags & _TIF_SYSCALL_EXIT_WORK) || flags & _TIF_SINGLESTEP)
| arm64_syscall_exit_to_user_mode_work(regs);
| return;
| }
| trace_exit:
| arm64_syscall_exit_to_user_mode_work(regs);
After simplify:
| if (... && !IS_ENABLED(CONFIG_DEBUG_RSEQ)) {
| arm64_syscall_exit_to_user_mode_work(regs);
| return;
| }
| trace_exit:
| arm64_syscall_exit_to_user_mode_work(regs);
Furthermore, Since both the conditional fast-path and the fallback
slow-path now uniformly invoke arm64_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 | 13 -------------
1 file changed, 13 deletions(-)
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index a8e0bf8d362e..3488afd45d20 100644
--- a/arch/arm64/kernel/syscall.c
+++ b/arch/arm64/kernel/syscall.c
@@ -114,19 +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)) {
- flags = read_thread_flags();
- if (unlikely(flags & _TIF_SYSCALL_EXIT_WORK) || flags & _TIF_SINGLESTEP)
- arm64_syscall_exit_to_user_mode_work(regs);
- return;
- }
-
trace_exit:
arm64_syscall_exit_to_user_mode_work(regs);
}
--
2.34.1
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH v17 12/15] arm64: ptrace: Make return type of arm64_syscall_trace_enter() bool
2026-07-21 8:18 [PATCH v17 00/15] arm64: entry: Convert to Generic Entry Jinjie Ruan
` (10 preceding siblings ...)
2026-07-21 8:18 ` [PATCH v17 11/15] arm64: syscall: Simplify el0_svc_common() syscall exit path Jinjie Ruan
@ 2026-07-21 8:18 ` Jinjie Ruan
2026-07-21 8:52 ` Linus Walleij
2026-07-21 8:18 ` [PATCH v17 13/15] arm64: entry: Convert to generic entry Jinjie Ruan
` (2 subsequent siblings)
14 siblings, 1 reply; 31+ messages in thread
From: Jinjie Ruan @ 2026-07-21 8:18 UTC (permalink / raw)
To: catalin.marinas, will, kees, oleg, luto, wad, thuth, peterz,
mark.rutland, linusw, ada.coupriediaz, kevin.brodsky,
yeoreum.yun, anshuman.khandual, james.morse, tglx, broonie,
pengcan, ryan.roberts, liqiang01, linux-arm-kernel, linux-kernel,
linux-mm
Cc: ruanjinjie
In preparation for migrating arm64 to the generic entry infrastructure,
decouple the decision to execute the syscall from the syscall number
itself. The ptrace and seccomp now returns a boolean flag rather than
overloading NO_SYSCALL (-1).
Changes:
- arm64_syscall_trace_enter() returns bool:
- false: abort syscall execution
- true: proceed, with syscall number reread from regs
- If we decide to execute the syscall, reread the syscall number
and check if it is NO_SYSCALL again. Because when a tracer sets
the syscall number to -1 and provides a custom return value in x0,
this avoids calling invoke_syscall() which would overwrite the custom
value with -ENOSYS by sys_ni_syscall().
Behavioral impact (unchanged):
- User-issued syscall(-1): unchanged, returns -ENOSYS.
- Tracer skip with custom x0: unchanged, returns custom x0
- Tracer skip without setting x0: unchanged, returns original
argument (garbage)
- Normal syscalls and seccomp rejects: unaffected
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 | 2 +-
arch/arm64/kernel/ptrace.c | 8 ++++----
arch/arm64/kernel/syscall.c | 6 +++++-
3 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/include/asm/syscall.h b/arch/arm64/include/asm/syscall.h
index 7cc872fde019..f19d4a8824ba 100644
--- a/arch/arm64/include/asm/syscall.h
+++ b/arch/arm64/include/asm/syscall.h
@@ -121,7 +121,7 @@ static inline int syscall_get_arch(struct task_struct *task)
return AUDIT_ARCH_AARCH64;
}
-int arm64_syscall_trace_enter(struct pt_regs *regs, unsigned long flags);
+bool arm64_syscall_trace_enter(struct pt_regs *regs, unsigned long flags);
void arm64_syscall_exit_work(struct pt_regs *regs, unsigned long flags);
static __always_inline void arm64_syscall_exit_to_user_mode_work(struct pt_regs *regs)
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 10ead67b4eaf..b2b28dcb2826 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -2468,14 +2468,14 @@ static inline void syscall_enter_audit(struct pt_regs *regs)
}
#endif
-int arm64_syscall_trace_enter(struct pt_regs *regs, unsigned long flags)
+bool arm64_syscall_trace_enter(struct pt_regs *regs, unsigned long flags)
{
int ret;
if (flags & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE)) {
ret = report_syscall_entry(regs);
if (ret || (flags & _TIF_SYSCALL_EMU))
- return NO_SYSCALL;
+ return false;
/* ptrace might have changed thread flags */
flags = read_thread_flags();
@@ -2484,7 +2484,7 @@ int arm64_syscall_trace_enter(struct pt_regs *regs, unsigned long flags)
/* Do the secure computing after ptrace; failures should be fast. */
if (unlikely(flags & _TIF_SECCOMP)) {
if (!__seccomp_permit_syscall())
- return NO_SYSCALL;
+ return false;
}
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
@@ -2493,7 +2493,7 @@ int arm64_syscall_trace_enter(struct pt_regs *regs, unsigned long flags)
if (unlikely(audit_context()))
syscall_enter_audit(regs);
- return syscall_get_nr(current, regs);
+ return true;
}
static inline bool report_single_step(unsigned long flags)
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index 3488afd45d20..72c6e8b7ab21 100644
--- a/arch/arm64/kernel/syscall.c
+++ b/arch/arm64/kernel/syscall.c
@@ -108,7 +108,11 @@ 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 = arm64_syscall_trace_enter(regs, read_thread_flags());
+ if (!arm64_syscall_trace_enter(regs, read_thread_flags()))
+ goto trace_exit;
+
+ /* Reread the syscall number as it might have been modified */
+ scno = syscall_get_nr(current, regs);
if (scno == NO_SYSCALL)
goto trace_exit;
}
--
2.34.1
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH v17 13/15] arm64: entry: Convert to generic entry
2026-07-21 8:18 [PATCH v17 00/15] arm64: entry: Convert to Generic Entry Jinjie Ruan
` (11 preceding siblings ...)
2026-07-21 8:18 ` [PATCH v17 12/15] arm64: ptrace: Make return type of arm64_syscall_trace_enter() bool Jinjie Ruan
@ 2026-07-21 8:18 ` Jinjie Ruan
2026-07-21 8:18 ` [PATCH v17 14/15] arm64: Inline el0_svc_common() Jinjie Ruan
2026-07-21 8:18 ` [PATCH v17 15/15] arm64: vdso: Expose sigreturn address on vdso to the kernel Jinjie Ruan
14 siblings, 0 replies; 31+ messages in thread
From: Jinjie Ruan @ 2026-07-21 8:18 UTC (permalink / raw)
To: catalin.marinas, will, kees, oleg, luto, wad, thuth, peterz,
mark.rutland, linusw, ada.coupriediaz, kevin.brodsky,
yeoreum.yun, anshuman.khandual, james.morse, tglx, broonie,
pengcan, ryan.roberts, liqiang01, linux-arm-kernel, linux-kernel,
linux-mm
Cc: ruanjinjie
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 following
arch function by porting the existing arm64 logic to the generic
interface:
- arch_ptrace_report_syscall_permit_entry()
- arch_ptrace_report_syscall_exit()
4. Cleanup and Refactoring: Remove redundant arm64-specific syscall
tracing functions from ptrace.c, including following key functions
and related audit/step helpers:
- arm64_syscall_exit_to_user_mode_work()
- arm64_syscall_trace_enter()
- arm64_syscall_exit_work().
- 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 | 77 +++++++++++++++
arch/arm64/include/asm/syscall.h | 14 ---
arch/arm64/include/asm/thread_info.h | 19 +---
arch/arm64/kernel/debug-monitors.c | 8 ++
arch/arm64/kernel/entry-common.c | 2 +-
arch/arm64/kernel/ptrace.c | 136 --------------------------
arch/arm64/kernel/signal.c | 2 +-
arch/arm64/kernel/syscall.c | 9 +-
9 files changed, 95 insertions(+), 174 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..2b053acbe10f 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,74 @@ 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 bool arch_ptrace_report_syscall_permit_entry(struct pt_regs *regs)
+{
+ unsigned long saved_reg;
+ bool permit;
+ int regno;
+
+ saved_reg = ptrace_save_reg(regs, PTRACE_SYSCALL_ENTER, ®no);
+ permit = ptrace_report_syscall_permit_entry(regs);
+ if (!permit)
+ forget_syscall(regs);
+ regs->regs[regno] = saved_reg;
+
+ return permit;
+}
+
+#define arch_ptrace_report_syscall_permit_entry arch_ptrace_report_syscall_permit_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 f19d4a8824ba..e3e716575846 100644
--- a/arch/arm64/include/asm/syscall.h
+++ b/arch/arm64/include/asm/syscall.h
@@ -120,18 +120,4 @@ static inline int syscall_get_arch(struct task_struct *task)
return AUDIT_ARCH_AARCH64;
}
-
-bool arm64_syscall_trace_enter(struct pt_regs *regs, unsigned long flags);
-void arm64_syscall_exit_work(struct pt_regs *regs, unsigned long flags);
-
-static __always_inline void arm64_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)
- arm64_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/entry-common.c b/arch/arm64/kernel/entry-common.c
index ceb4eb11232a..9eac76804bd9 100644
--- a/arch/arm64/kernel/entry-common.c
+++ b/arch/arm64/kernel/entry-common.c
@@ -6,7 +6,7 @@
*/
#include <linux/context_tracking.h>
-#include <linux/irq-entry-common.h>
+#include <linux/entry-common.h>
#include <linux/kasan.h>
#include <linux/linkage.h>
#include <linux/livepatch.h>
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index b2b28dcb2826..8bdee1805c93 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;
@@ -2388,136 +2382,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_permit_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);
- }
-}
-
-#ifdef CONFIG_AUDITSYSCALL
-static inline void syscall_enter_audit(struct pt_regs *regs)
-{
- long syscall = syscall_get_nr(current, regs);
- unsigned long args[6];
-
- syscall_get_arguments(current, regs, args);
- __audit_syscall_entry(syscall, args[0], args[1], args[2], args[3]);
-}
-#endif
-
-bool arm64_syscall_trace_enter(struct pt_regs *regs, unsigned long flags)
-{
- int ret;
-
- if (flags & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE)) {
- ret = report_syscall_entry(regs);
- if (ret || (flags & _TIF_SYSCALL_EMU))
- return false;
-
- /* ptrace might have changed thread flags */
- flags = read_thread_flags();
- }
-
- /* Do the secure computing after ptrace; failures should be fast. */
- if (unlikely(flags & _TIF_SECCOMP)) {
- if (!__seccomp_permit_syscall())
- return false;
- }
-
- if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
- trace_sys_enter(regs, syscall_get_nr(current, regs));
-
- if (unlikely(audit_context()))
- syscall_enter_audit(regs);
-
- return true;
-}
-
-static inline bool report_single_step(unsigned long flags)
-{
- if (flags & _TIF_SYSCALL_EMU)
- return false;
-
- return flags & _TIF_SINGLESTEP;
-}
-
-void arm64_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 72c6e8b7ab21..4a13108defb0 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);
- if (!arm64_syscall_trace_enter(regs, read_thread_flags()))
+ if (!syscall_trace_enter(regs, work, scno))
goto trace_exit;
/* Reread the syscall number as it might have been modified */
@@ -119,7 +122,7 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
invoke_syscall(regs, scno, sc_nr, syscall_table);
trace_exit:
- arm64_syscall_exit_to_user_mode_work(regs);
+ syscall_exit_to_user_mode_work(regs);
}
void do_el0_svc(struct pt_regs *regs)
--
2.34.1
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH v17 14/15] arm64: Inline el0_svc_common()
2026-07-21 8:18 [PATCH v17 00/15] arm64: entry: Convert to Generic Entry Jinjie Ruan
` (12 preceding siblings ...)
2026-07-21 8:18 ` [PATCH v17 13/15] arm64: entry: Convert to generic entry Jinjie Ruan
@ 2026-07-21 8:18 ` Jinjie Ruan
2026-07-21 8:18 ` [PATCH v17 15/15] arm64: vdso: Expose sigreturn address on vdso to the kernel Jinjie Ruan
14 siblings, 0 replies; 31+ messages in thread
From: Jinjie Ruan @ 2026-07-21 8:18 UTC (permalink / raw)
To: catalin.marinas, will, kees, oleg, luto, wad, thuth, peterz,
mark.rutland, linusw, ada.coupriediaz, kevin.brodsky,
yeoreum.yun, anshuman.khandual, james.morse, tglx, broonie,
pengcan, ryan.roberts, liqiang01, linux-arm-kernel, linux-kernel,
linux-mm
Cc: ruanjinjie
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 4a13108defb0..2535cae9413d 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 [flat|nested] 31+ messages in thread
* [PATCH v17 15/15] arm64: vdso: Expose sigreturn address on vdso to the kernel
2026-07-21 8:18 [PATCH v17 00/15] arm64: entry: Convert to Generic Entry Jinjie Ruan
` (13 preceding siblings ...)
2026-07-21 8:18 ` [PATCH v17 14/15] arm64: Inline el0_svc_common() Jinjie Ruan
@ 2026-07-21 8:18 ` Jinjie Ruan
2026-07-21 8:51 ` Thomas Weißschuh
2026-07-21 8:55 ` Linus Walleij
14 siblings, 2 replies; 31+ messages in thread
From: Jinjie Ruan @ 2026-07-21 8:18 UTC (permalink / raw)
To: catalin.marinas, will, kees, oleg, luto, wad, thuth, peterz,
mark.rutland, linusw, ada.coupriediaz, kevin.brodsky,
yeoreum.yun, anshuman.khandual, james.morse, tglx, broonie,
pengcan, ryan.roberts, liqiang01, linux-arm-kernel, linux-kernel,
linux-mm
Cc: ruanjinjie
Syscall User Dispatch (SUD) must not intercept the signal trampoline
code, otherwise returning from a signal with a locked selector may
cause infinite recursion into the signal handler.
Provide an arm64 implementation of arch_syscall_is_vdso_sigreturn()
to exclude these sigreturn syscalls from dispatch.
For native 64-bit tasks, check whether the current PC matches the 'svc #0'
instruction inside the vDSO sigreturn trampoline (defined in
arch/arm64/kernel/vdso/sigreturn.S as below).
SYM_CODE_START(__kernel_rt_sigreturn)
mov x8, #__NR_rt_sigreturn
svc #0
SYM_CODE_END(__kernel_rt_sigreturn)
For COMPAT tasks, verify that the instruction falls within the dedicated
'sigpage' range, since compat signal handlers use this architecture-
specific page (not the vDSO) for their return trampoline. This prevents
SUD from incorrectly dispatching syscalls issued during signal return.
Suggested-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Suggested-by: Kevin Brodsky <kevin.brodsky@arm.com>
Suggested-by: kemal <kmal@cock.li>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/arm64/Kconfig | 1 +
arch/arm64/include/asm/elf.h | 1 +
arch/arm64/kernel/vdso.c | 16 ++++++++++++++++
arch/arm64/kernel/vdso/sigreturn.S | 1 +
arch/arm64/kernel/vdso/vdso.lds.S | 1 +
5 files changed, 20 insertions(+)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index aea686dce3d5..a41d2b593899 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -86,6 +86,7 @@ config ARM64
select ARCH_SUPPORTS_SCHED_SMT
select ARCH_SUPPORTS_SCHED_CLUSTER
select ARCH_SUPPORTS_SCHED_MC
+ select ARCH_SUPPORTS_SYSCALL_USER_DISPATCH
select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH
select ARCH_WANT_COMPAT_IPC_PARSE_VERSION if COMPAT
select ARCH_WANT_DEFAULT_BPF_JIT
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index d2779d604c7b..a8b232c5c6d9 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -293,6 +293,7 @@ static inline int arch_check_elf(void *ehdr, bool has_interp,
return 0;
}
+extern bool arch_syscall_is_vdso_sigreturn(struct pt_regs *regs);
#endif /* !__ASSEMBLER__ */
#endif
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index 592dd8668de4..37cdc7c72e15 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 landing_pad;
+
+#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
+ landing_pad = (unsigned long)VDSO_SYMBOL(current->mm->context.vdso, sigreturn_landing_pad);
+
+ return regs->pc == landing_pad;
+}
diff --git a/arch/arm64/kernel/vdso/sigreturn.S b/arch/arm64/kernel/vdso/sigreturn.S
index 0e18729abc3b..8d2d413ff45e 100644
--- a/arch/arm64/kernel/vdso/sigreturn.S
+++ b/arch/arm64/kernel/vdso/sigreturn.S
@@ -73,6 +73,7 @@ SYM_CODE_START(__kernel_rt_sigreturn)
mov x8, #__NR_rt_sigreturn
// PLEASE DO NOT MODIFY
svc #0
+ SYM_INNER_LABEL(__sigreturn_landing_pad, SYM_L_GLOBAL)
// PLEASE DO NOT MODIFY
// .cfi_endproc
SYM_CODE_END(__kernel_rt_sigreturn)
diff --git a/arch/arm64/kernel/vdso/vdso.lds.S b/arch/arm64/kernel/vdso/vdso.lds.S
index 52314be29191..da61d6fc6fe9 100644
--- a/arch/arm64/kernel/vdso/vdso.lds.S
+++ b/arch/arm64/kernel/vdso/vdso.lds.S
@@ -112,3 +112,4 @@ VERSION
* Make the sigreturn code visible to the kernel.
*/
VDSO_sigtramp = __kernel_rt_sigreturn;
+VDSO_sigreturn_landing_pad = __sigreturn_landing_pad;
--
2.34.1
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v17 04/15] arm64: ptrace: Rename and clean up syscall_trace_enter()
2026-07-21 8:18 ` [PATCH v17 04/15] arm64: ptrace: Rename and clean up syscall_trace_enter() Jinjie Ruan
@ 2026-07-21 8:39 ` Linus Walleij
0 siblings, 0 replies; 31+ messages in thread
From: Linus Walleij @ 2026-07-21 8:39 UTC (permalink / raw)
To: Jinjie Ruan
Cc: catalin.marinas, will, kees, oleg, luto, wad, thuth, peterz,
mark.rutland, ada.coupriediaz, kevin.brodsky, yeoreum.yun,
anshuman.khandual, james.morse, tglx, broonie, pengcan,
ryan.roberts, liqiang01, linux-arm-kernel, linux-kernel,
linux-mm
On Tue, Jul 21, 2026 at 10:19 AM Jinjie Ruan <ruanjinjie@huawei.com> wrote:
> Rename syscall_trace_enter() to arm64_syscall_trace_enter() to avoid
> name collisions and clarify the boundary when arm64 eventually switches
> to the generic entry infrastructure.
>
> In addition, replace direct accesses to regs->syscallno with the standard
> syscall_get_nr() helper for both trace_sys_enter() and the return value.
> This decouples the tracing logic from architecture-specific struct pt_regs
> layouts, aligning the implementation with the generic entry pattern.
>
> No functional changes intended; this is a preparation step for
> converting arm64 to the generic entry infrastructure.
>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Will Deacon <will@kernel.org>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v17 06/15] arm64: syscall: Rework the syscall exit path in el0_svc_common()
2026-07-21 8:18 ` [PATCH v17 06/15] arm64: syscall: Rework the syscall exit path in el0_svc_common() Jinjie Ruan
@ 2026-07-21 8:43 ` Linus Walleij
2026-07-21 8:45 ` Linus Walleij
0 siblings, 1 reply; 31+ messages in thread
From: Linus Walleij @ 2026-07-21 8:43 UTC (permalink / raw)
To: Jinjie Ruan
Cc: catalin.marinas, will, kees, oleg, luto, wad, thuth, peterz,
mark.rutland, ada.coupriediaz, kevin.brodsky, yeoreum.yun,
anshuman.khandual, james.morse, tglx, broonie, pengcan,
ryan.roberts, liqiang01, linux-arm-kernel, linux-kernel,
linux-mm
On Tue, Jul 21, 2026 at 10:19 AM Jinjie Ruan <ruanjinjie@huawei.com> wrote:
> In preparation for moving arm64 over to the generic entry,
> invert the nested conditional flags check within el0_svc_common().
>
> No functional changes.
(...)
> 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)
> + syscall_trace_exit(regs);
> + return;
What about just:
if (...)
goto trace_exit;
This is easier to follow IMO.
With that:
Reviewed-by: Linus Walleij <linusw@kernel.org>
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v17 06/15] arm64: syscall: Rework the syscall exit path in el0_svc_common()
2026-07-21 8:43 ` Linus Walleij
@ 2026-07-21 8:45 ` Linus Walleij
0 siblings, 0 replies; 31+ messages in thread
From: Linus Walleij @ 2026-07-21 8:45 UTC (permalink / raw)
To: Jinjie Ruan
Cc: catalin.marinas, will, kees, oleg, luto, wad, thuth, peterz,
mark.rutland, ada.coupriediaz, kevin.brodsky, yeoreum.yun,
anshuman.khandual, james.morse, tglx, broonie, pengcan,
ryan.roberts, liqiang01, linux-arm-kernel, linux-kernel,
linux-mm
On Tue, Jul 21, 2026 at 10:43 AM Linus Walleij <linusw@kernel.org> wrote:
> On Tue, Jul 21, 2026 at 10:19 AM Jinjie Ruan <ruanjinjie@huawei.com> wrote:
>
>
> > In preparation for moving arm64 over to the generic entry,
> > invert the nested conditional flags check within el0_svc_common().
> >
> > No functional changes.
> (...)
> > 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)
> > + syscall_trace_exit(regs);
> > + return;
>
> What about just:
>
> if (...)
> goto trace_exit;
>
> This is easier to follow IMO.
>
> With that:
> Reviewed-by: Linus Walleij <linusw@kernel.org>
Aha I see you refactor it again in patch 8, no big deal then.
This is fine, add the Reviewed-by.
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v17 08/15] arm64: ptrace: Extract arm64_syscall_exit_to_user_mode_work() helper
2026-07-21 8:18 ` [PATCH v17 08/15] arm64: ptrace: Extract arm64_syscall_exit_to_user_mode_work() helper Jinjie Ruan
@ 2026-07-21 8:45 ` Linus Walleij
0 siblings, 0 replies; 31+ messages in thread
From: Linus Walleij @ 2026-07-21 8:45 UTC (permalink / raw)
To: Jinjie Ruan
Cc: catalin.marinas, will, kees, oleg, luto, wad, thuth, peterz,
mark.rutland, ada.coupriediaz, kevin.brodsky, yeoreum.yun,
anshuman.khandual, james.morse, tglx, broonie, pengcan,
ryan.roberts, liqiang01, linux-arm-kernel, linux-kernel,
linux-mm
On Tue, Jul 21, 2026 at 10:19 AM Jinjie Ruan <ruanjinjie@huawei.com> wrote:
> Introduce a helper arm64_syscall_exit_to_user_mode_work() that
> encapsulates the re-reading of thread flags and the call to
> syscall_trace_exit(). Use it in el0_svc_common() to replace
> the open-coded instances, removing the duplicated flags read
> and making the control flow simpler.
>
> This aligns the arm64 exit path with the pattern expected by the
> generic entry infrastructure, which uses a similar
> syscall_exit_to_user_mode_work() callback.
>
> No functional changes intended; this is a preparation step for converting
> arm64 to the generic entry infrastructure.
>
> 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>
Looks right to me!
Reviewed-by: Linus Walleij <linusw@kernel.org>
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v17 09/15] arm64: ptrace: Align syscall exit work semantics with generic entry
2026-07-21 8:18 ` [PATCH v17 09/15] arm64: ptrace: Align syscall exit work semantics with generic entry Jinjie Ruan
@ 2026-07-21 8:46 ` Linus Walleij
0 siblings, 0 replies; 31+ messages in thread
From: Linus Walleij @ 2026-07-21 8:46 UTC (permalink / raw)
To: Jinjie Ruan
Cc: catalin.marinas, will, kees, oleg, luto, wad, thuth, peterz,
mark.rutland, ada.coupriediaz, kevin.brodsky, yeoreum.yun,
anshuman.khandual, james.morse, tglx, broonie, pengcan,
ryan.roberts, liqiang01, linux-arm-kernel, linux-kernel,
linux-mm
On Tue, Jul 21, 2026 at 10:19 AM Jinjie Ruan <ruanjinjie@huawei.com> wrote:
> Refactor the syscall exit path to better match the generic entry
> framework. Specifically:
>
> - Introduce `_TIF_SYSCALL_EXIT_WORK` to aggregate exit-time thread
> flags (trace, audit, tracepoint).
>
> - Rename `syscall_trace_exit()` to `arm64_syscall_exit_work()` to
> better reflect its role.
>
> - Move `rseq_syscall()` out of `arm64_syscall_exit_work()` and into
> `arm64_syscall_exit_to_user_mode_work()` so that it runs
> unconditionally on all exits, consistent with generic entry.
>
> - Gate `arm64_syscall_exit_work()` behind the new flag check,
> mirroring the generic entry exit's pattern.
>
> Gating audit on `_TIF_SYSCALL_AUDIT` is equivalent to the previous
> `audit_context()` check: the audit context and flag are statically
> allocated at fork and freed at exit, remaining stable throughout
> syscall execution.
>
> 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>
It does indeed align to generic entry AFAICT.
Reviewed-by: Linus Walleij <linusw@kernel.org>
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v17 15/15] arm64: vdso: Expose sigreturn address on vdso to the kernel
2026-07-21 8:18 ` [PATCH v17 15/15] arm64: vdso: Expose sigreturn address on vdso to the kernel Jinjie Ruan
@ 2026-07-21 8:51 ` Thomas Weißschuh
2026-07-21 9:23 ` Jinjie Ruan
2026-07-21 8:55 ` Linus Walleij
1 sibling, 1 reply; 31+ messages in thread
From: Thomas Weißschuh @ 2026-07-21 8:51 UTC (permalink / raw)
To: Jinjie Ruan
Cc: catalin.marinas, will, kees, oleg, luto, wad, thuth, peterz,
mark.rutland, linusw, ada.coupriediaz, kevin.brodsky,
yeoreum.yun, anshuman.khandual, james.morse, tglx, broonie,
pengcan, ryan.roberts, liqiang01, linux-arm-kernel, linux-kernel,
linux-mm
On Tue, Jul 21, 2026 at 04:18:58PM +0800, Jinjie Ruan wrote:
> Syscall User Dispatch (SUD) must not intercept the signal trampoline
> code, otherwise returning from a signal with a locked selector may
> cause infinite recursion into the signal handler.
>
> Provide an arm64 implementation of arch_syscall_is_vdso_sigreturn()
> to exclude these sigreturn syscalls from dispatch.
>
> For native 64-bit tasks, check whether the current PC matches the 'svc #0'
> instruction inside the vDSO sigreturn trampoline (defined in
> arch/arm64/kernel/vdso/sigreturn.S as below).
>
> SYM_CODE_START(__kernel_rt_sigreturn)
> mov x8, #__NR_rt_sigreturn
> svc #0
> SYM_CODE_END(__kernel_rt_sigreturn)
With the new label this code snippet here shouldnt be needed anymore.
> For COMPAT tasks, verify that the instruction falls within the dedicated
> 'sigpage' range, since compat signal handlers use this architecture-
> specific page (not the vDSO) for their return trampoline. This prevents
> SUD from incorrectly dispatching syscalls issued during signal return.
>
> Suggested-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
> Suggested-by: Kevin Brodsky <kevin.brodsky@arm.com>
> Suggested-by: kemal <kmal@cock.li>
> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
> ---
> arch/arm64/Kconfig | 1 +
> arch/arm64/include/asm/elf.h | 1 +
> arch/arm64/kernel/vdso.c | 16 ++++++++++++++++
> arch/arm64/kernel/vdso/sigreturn.S | 1 +
> arch/arm64/kernel/vdso/vdso.lds.S | 1 +
> 5 files changed, 20 insertions(+)
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index aea686dce3d5..a41d2b593899 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -86,6 +86,7 @@ config ARM64
> select ARCH_SUPPORTS_SCHED_SMT
> select ARCH_SUPPORTS_SCHED_CLUSTER
> select ARCH_SUPPORTS_SCHED_MC
> + select ARCH_SUPPORTS_SYSCALL_USER_DISPATCH
From the subject and description I would not have expected this to be in here.
Split into its own patch?
> select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH
> select ARCH_WANT_COMPAT_IPC_PARSE_VERSION if COMPAT
> select ARCH_WANT_DEFAULT_BPF_JIT
(...)
For the rest:
Reviewed-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Thomas
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v17 11/15] arm64: syscall: Simplify el0_svc_common() syscall exit path
2026-07-21 8:18 ` [PATCH v17 11/15] arm64: syscall: Simplify el0_svc_common() syscall exit path Jinjie Ruan
@ 2026-07-21 8:51 ` Linus Walleij
2026-07-21 9:30 ` Jinjie Ruan
0 siblings, 1 reply; 31+ messages in thread
From: Linus Walleij @ 2026-07-21 8:51 UTC (permalink / raw)
To: Jinjie Ruan
Cc: catalin.marinas, will, kees, oleg, luto, wad, thuth, peterz,
mark.rutland, ada.coupriediaz, kevin.brodsky, yeoreum.yun,
anshuman.khandual, james.morse, tglx, broonie, pengcan,
ryan.roberts, liqiang01, linux-arm-kernel, linux-kernel,
linux-mm
On Tue, Jul 21, 2026 at 10:19 AM Jinjie Ruan <ruanjinjie@huawei.com> wrote:
> 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 so the call of rseq_syscall() is a no-op.
Please explain why this is guaranteed.
> Under this constraint,
> the code logic inside the block becomes completely identical to what
> the arm64_syscall_exit_to_user_mode_work() helper already does. Replace
> that nested logic with a direct invocation of the helper, eliminating
> redundant code.
>
> Before:
>
> | if (... && !IS_ENABLED(CONFIG_DEBUG_RSEQ)) {
> | flags = read_thread_flags();
> | if (unlikely(flags & _TIF_SYSCALL_EXIT_WORK) || flags & _TIF_SINGLESTEP)
> | arm64_syscall_exit_to_user_mode_work(regs);
> | return;
> | }
> | trace_exit:
> | arm64_syscall_exit_to_user_mode_work(regs);
>
> After simplify:
>
> | if (... && !IS_ENABLED(CONFIG_DEBUG_RSEQ)) {
> | arm64_syscall_exit_to_user_mode_work(regs);
> | return;
> | }
> | trace_exit:
> | arm64_syscall_exit_to_user_mode_work(regs);
>
> Furthermore, Since both the conditional fast-path and the fallback
> slow-path now uniformly invoke arm64_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>
After looking at it for a while I conclude you are right, provided
the reasoning about !CONFIG_DEBUG_RSEQ holds. So with
that explained:
Reviewed-by: Linus Walleij <linusw@kernel.org>
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v17 12/15] arm64: ptrace: Make return type of arm64_syscall_trace_enter() bool
2026-07-21 8:18 ` [PATCH v17 12/15] arm64: ptrace: Make return type of arm64_syscall_trace_enter() bool Jinjie Ruan
@ 2026-07-21 8:52 ` Linus Walleij
0 siblings, 0 replies; 31+ messages in thread
From: Linus Walleij @ 2026-07-21 8:52 UTC (permalink / raw)
To: Jinjie Ruan
Cc: catalin.marinas, will, kees, oleg, luto, wad, thuth, peterz,
mark.rutland, ada.coupriediaz, kevin.brodsky, yeoreum.yun,
anshuman.khandual, james.morse, tglx, broonie, pengcan,
ryan.roberts, liqiang01, linux-arm-kernel, linux-kernel,
linux-mm
On Tue, Jul 21, 2026 at 10:19 AM Jinjie Ruan <ruanjinjie@huawei.com> wrote:
> In preparation for migrating arm64 to the generic entry infrastructure,
> decouple the decision to execute the syscall from the syscall number
> itself. The ptrace and seccomp now returns a boolean flag rather than
> overloading NO_SYSCALL (-1).
>
> Changes:
> - arm64_syscall_trace_enter() returns bool:
> - false: abort syscall execution
> - true: proceed, with syscall number reread from regs
> - If we decide to execute the syscall, reread the syscall number
> and check if it is NO_SYSCALL again. Because when a tracer sets
> the syscall number to -1 and provides a custom return value in x0,
> this avoids calling invoke_syscall() which would overwrite the custom
> value with -ENOSYS by sys_ni_syscall().
>
> Behavioral impact (unchanged):
> - User-issued syscall(-1): unchanged, returns -ENOSYS.
> - Tracer skip with custom x0: unchanged, returns custom x0
> - Tracer skip without setting x0: unchanged, returns original
> argument (garbage)
> - Normal syscalls and seccomp rejects: unaffected
>
> 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>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v17 15/15] arm64: vdso: Expose sigreturn address on vdso to the kernel
2026-07-21 8:18 ` [PATCH v17 15/15] arm64: vdso: Expose sigreturn address on vdso to the kernel Jinjie Ruan
2026-07-21 8:51 ` Thomas Weißschuh
@ 2026-07-21 8:55 ` Linus Walleij
2026-07-21 9:27 ` Jinjie Ruan
2026-07-22 18:18 ` Mark Rutland
1 sibling, 2 replies; 31+ messages in thread
From: Linus Walleij @ 2026-07-21 8:55 UTC (permalink / raw)
To: Jinjie Ruan
Cc: catalin.marinas, will, kees, oleg, luto, wad, thuth, peterz,
mark.rutland, ada.coupriediaz, kevin.brodsky, yeoreum.yun,
anshuman.khandual, james.morse, tglx, broonie, pengcan,
ryan.roberts, liqiang01, linux-arm-kernel, linux-kernel,
linux-mm
On Tue, Jul 21, 2026 at 10:19 AM Jinjie Ruan <ruanjinjie@huawei.com> wrote:
> Syscall User Dispatch (SUD) must not intercept the signal trampoline
> code, otherwise returning from a signal with a locked selector may
> cause infinite recursion into the signal handler.
>
> Provide an arm64 implementation of arch_syscall_is_vdso_sigreturn()
> to exclude these sigreturn syscalls from dispatch.
>
> For native 64-bit tasks, check whether the current PC matches the 'svc #0'
> instruction inside the vDSO sigreturn trampoline (defined in
> arch/arm64/kernel/vdso/sigreturn.S as below).
>
> SYM_CODE_START(__kernel_rt_sigreturn)
> mov x8, #__NR_rt_sigreturn
> svc #0
> SYM_CODE_END(__kernel_rt_sigreturn)
>
> For COMPAT tasks, verify that the instruction falls within the dedicated
> 'sigpage' range, since compat signal handlers use this architecture-
> specific page (not the vDSO) for their return trampoline. This prevents
> SUD from incorrectly dispatching syscalls issued during signal return.
>
> Suggested-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
> Suggested-by: Kevin Brodsky <kevin.brodsky@arm.com>
> Suggested-by: kemal <kmal@cock.li>
> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
I'm a bit scared about SUD.
Certainly we can merge patches 1-14 first and iron out
any trouble related to that and split this off so a separate
series to be applied lated?
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v17 15/15] arm64: vdso: Expose sigreturn address on vdso to the kernel
2026-07-21 8:51 ` Thomas Weißschuh
@ 2026-07-21 9:23 ` Jinjie Ruan
2026-07-21 9:55 ` Thomas Weißschuh
0 siblings, 1 reply; 31+ messages in thread
From: Jinjie Ruan @ 2026-07-21 9:23 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: catalin.marinas, will, kees, oleg, luto, wad, thuth, peterz,
mark.rutland, linusw, ada.coupriediaz, kevin.brodsky,
yeoreum.yun, anshuman.khandual, james.morse, tglx, broonie,
pengcan, ryan.roberts, liqiang01, linux-arm-kernel, linux-kernel,
linux-mm
On 7/21/2026 4:51 PM, Thomas Weißschuh wrote:
> On Tue, Jul 21, 2026 at 04:18:58PM +0800, Jinjie Ruan wrote:
>> Syscall User Dispatch (SUD) must not intercept the signal trampoline
>> code, otherwise returning from a signal with a locked selector may
>> cause infinite recursion into the signal handler.
>>
>> Provide an arm64 implementation of arch_syscall_is_vdso_sigreturn()
>> to exclude these sigreturn syscalls from dispatch.
>>
>> For native 64-bit tasks, check whether the current PC matches the 'svc #0'
>> instruction inside the vDSO sigreturn trampoline (defined in
>> arch/arm64/kernel/vdso/sigreturn.S as below).
>>
>> SYM_CODE_START(__kernel_rt_sigreturn)
>> mov x8, #__NR_rt_sigreturn
>> svc #0
>> SYM_CODE_END(__kernel_rt_sigreturn)
>
> With the new label this code snippet here shouldnt be needed anymore.
You're right, the code itself is already clear.
>
>> For COMPAT tasks, verify that the instruction falls within the dedicated
>> 'sigpage' range, since compat signal handlers use this architecture-
>> specific page (not the vDSO) for their return trampoline. This prevents
>> SUD from incorrectly dispatching syscalls issued during signal return.
>>
>> Suggested-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
>> Suggested-by: Kevin Brodsky <kevin.brodsky@arm.com>
>> Suggested-by: kemal <kmal@cock.li>
>> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
>> ---
>> arch/arm64/Kconfig | 1 +
>> arch/arm64/include/asm/elf.h | 1 +
>> arch/arm64/kernel/vdso.c | 16 ++++++++++++++++
>> arch/arm64/kernel/vdso/sigreturn.S | 1 +
>> arch/arm64/kernel/vdso/vdso.lds.S | 1 +
>> 5 files changed, 20 insertions(+)
>>
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index aea686dce3d5..a41d2b593899 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -86,6 +86,7 @@ config ARM64
>> select ARCH_SUPPORTS_SCHED_SMT
>> select ARCH_SUPPORTS_SCHED_CLUSTER
>> select ARCH_SUPPORTS_SCHED_MC
>> + select ARCH_SUPPORTS_SYSCALL_USER_DISPATCH
>
> From the subject and description I would not have expected this to be in here.
> Split into its own patch?
If ARCH_SUPPORTS_SYSCALL_USER_DISPATCH is not implemented, then it seems
pointless to implement arch_syscall_is_vdso_sigreturn() separately, or
perhaps we should revise the title to indicate support for SUD on arm64?
>
>> select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH
>> select ARCH_WANT_COMPAT_IPC_PARSE_VERSION if COMPAT
>> select ARCH_WANT_DEFAULT_BPF_JIT
>
> (...)
>
> For the rest:
>
> Reviewed-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Thanks for the review.
>
>
> Thomas
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v17 15/15] arm64: vdso: Expose sigreturn address on vdso to the kernel
2026-07-21 8:55 ` Linus Walleij
@ 2026-07-21 9:27 ` Jinjie Ruan
2026-07-22 18:18 ` Mark Rutland
1 sibling, 0 replies; 31+ messages in thread
From: Jinjie Ruan @ 2026-07-21 9:27 UTC (permalink / raw)
To: Linus Walleij
Cc: catalin.marinas, will, kees, oleg, luto, wad, thuth, peterz,
mark.rutland, ada.coupriediaz, kevin.brodsky, yeoreum.yun,
anshuman.khandual, james.morse, tglx, broonie, pengcan,
ryan.roberts, liqiang01, linux-arm-kernel, linux-kernel,
linux-mm
On 7/21/2026 4:55 PM, Linus Walleij wrote:
> On Tue, Jul 21, 2026 at 10:19 AM Jinjie Ruan <ruanjinjie@huawei.com> wrote:
>
>> Syscall User Dispatch (SUD) must not intercept the signal trampoline
>> code, otherwise returning from a signal with a locked selector may
>> cause infinite recursion into the signal handler.
>>
>> Provide an arm64 implementation of arch_syscall_is_vdso_sigreturn()
>> to exclude these sigreturn syscalls from dispatch.
>>
>> For native 64-bit tasks, check whether the current PC matches the 'svc #0'
>> instruction inside the vDSO sigreturn trampoline (defined in
>> arch/arm64/kernel/vdso/sigreturn.S as below).
>>
>> SYM_CODE_START(__kernel_rt_sigreturn)
>> mov x8, #__NR_rt_sigreturn
>> svc #0
>> SYM_CODE_END(__kernel_rt_sigreturn)
>>
>> For COMPAT tasks, verify that the instruction falls within the dedicated
>> 'sigpage' range, since compat signal handlers use this architecture-
>> specific page (not the vDSO) for their return trampoline. This prevents
>> SUD from incorrectly dispatching syscalls issued during signal return.
>>
>> Suggested-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
>> Suggested-by: Kevin Brodsky <kevin.brodsky@arm.com>
>> Suggested-by: kemal <kmal@cock.li>
>> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
>
> I'm a bit scared about SUD.
>
> Certainly we can merge patches 1-14 first and iron out
> any trouble related to that and split this off so a separate
> series to be applied lated?
Yes, Mark's idea is the same. We can place the SUD patch here separately
and wait for thorough testing and review.
Link:
https://lore.kernel.org/all/akZgV0Y4YAmB43_g@J2N7QTR9R3.cambridge.arm.com/
>
> Yours,
> Linus Walleij
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v17 11/15] arm64: syscall: Simplify el0_svc_common() syscall exit path
2026-07-21 8:51 ` Linus Walleij
@ 2026-07-21 9:30 ` Jinjie Ruan
0 siblings, 0 replies; 31+ messages in thread
From: Jinjie Ruan @ 2026-07-21 9:30 UTC (permalink / raw)
To: Linus Walleij
Cc: catalin.marinas, will, kees, oleg, luto, wad, thuth, peterz,
mark.rutland, ada.coupriediaz, kevin.brodsky, yeoreum.yun,
anshuman.khandual, james.morse, tglx, broonie, pengcan,
ryan.roberts, liqiang01, linux-arm-kernel, linux-kernel,
linux-mm
On 7/21/2026 4:51 PM, Linus Walleij wrote:
> On Tue, Jul 21, 2026 at 10:19 AM Jinjie Ruan <ruanjinjie@huawei.com> wrote:
>
>> 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 so the call of rseq_syscall() is a no-op.
>
> Please explain why this is guaranteed.
Yes, there is a little unclear.
The expression "!IS_ENABLED(CONFIG_DEBUG_RSEQ)" evaluates to true only
when CONFIG_DEBUG_RSEQ is not set; with the guarantee that it is
disabled, the condition is always satisfied.
>
>> Under this constraint,
>> the code logic inside the block becomes completely identical to what
>> the arm64_syscall_exit_to_user_mode_work() helper already does. Replace
>> that nested logic with a direct invocation of the helper, eliminating
>> redundant code.
>>
>> Before:
>>
>> | if (... && !IS_ENABLED(CONFIG_DEBUG_RSEQ)) {
>> | flags = read_thread_flags();
>> | if (unlikely(flags & _TIF_SYSCALL_EXIT_WORK) || flags & _TIF_SINGLESTEP)
>> | arm64_syscall_exit_to_user_mode_work(regs);
>> | return;
>> | }
>> | trace_exit:
>> | arm64_syscall_exit_to_user_mode_work(regs);
>>
>> After simplify:
>>
>> | if (... && !IS_ENABLED(CONFIG_DEBUG_RSEQ)) {
>> | arm64_syscall_exit_to_user_mode_work(regs);
>> | return;
>> | }
>> | trace_exit:
>> | arm64_syscall_exit_to_user_mode_work(regs);
>>
>> Furthermore, Since both the conditional fast-path and the fallback
>> slow-path now uniformly invoke arm64_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>
>
> After looking at it for a while I conclude you are right, provided
> the reasoning about !CONFIG_DEBUG_RSEQ holds. So with
> that explained:
> Reviewed-by: Linus Walleij <linusw@kernel.org>
>
> Yours,
> Linus Walleij
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v17 15/15] arm64: vdso: Expose sigreturn address on vdso to the kernel
2026-07-21 9:23 ` Jinjie Ruan
@ 2026-07-21 9:55 ` Thomas Weißschuh
0 siblings, 0 replies; 31+ messages in thread
From: Thomas Weißschuh @ 2026-07-21 9:55 UTC (permalink / raw)
To: Jinjie Ruan
Cc: catalin.marinas, will, kees, oleg, luto, wad, thuth, peterz,
mark.rutland, linusw, ada.coupriediaz, kevin.brodsky,
yeoreum.yun, anshuman.khandual, james.morse, tglx, broonie,
pengcan, ryan.roberts, liqiang01, linux-arm-kernel, linux-kernel,
linux-mm
On Tue, Jul 21, 2026 at 05:23:38PM +0800, Jinjie Ruan wrote:
(...)
> >> arch/arm64/Kconfig | 1 +
> >> arch/arm64/include/asm/elf.h | 1 +
> >> arch/arm64/kernel/vdso.c | 16 ++++++++++++++++
> >> arch/arm64/kernel/vdso/sigreturn.S | 1 +
> >> arch/arm64/kernel/vdso/vdso.lds.S | 1 +
> >> 5 files changed, 20 insertions(+)
> >>
> >> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> >> index aea686dce3d5..a41d2b593899 100644
> >> --- a/arch/arm64/Kconfig
> >> +++ b/arch/arm64/Kconfig
> >> @@ -86,6 +86,7 @@ config ARM64
> >> select ARCH_SUPPORTS_SCHED_SMT
> >> select ARCH_SUPPORTS_SCHED_CLUSTER
> >> select ARCH_SUPPORTS_SCHED_MC
> >> + select ARCH_SUPPORTS_SYSCALL_USER_DISPATCH
> >
> > From the subject and description I would not have expected this to be in here.
> > Split into its own patch?
>
> If ARCH_SUPPORTS_SYSCALL_USER_DISPATCH is not implemented, then it seems
> pointless to implement arch_syscall_is_vdso_sigreturn() separately,
Absolutely. Although a preparatory patch can introduce infrastructure like this.
> or perhaps we should revise the title to indicate support for SUD on arm64?
That works, too.
> >> select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH
> >> select ARCH_WANT_COMPAT_IPC_PARSE_VERSION if COMPAT
> >> select ARCH_WANT_DEFAULT_BPF_JIT
> >
> > (...)
> >
> > For the rest:
> >
> > Reviewed-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
>
> Thanks for the review.
You're welcome!
Just to make it clear: This is only for this patch, not the whole series.
Thomas
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v17 15/15] arm64: vdso: Expose sigreturn address on vdso to the kernel
2026-07-21 8:55 ` Linus Walleij
2026-07-21 9:27 ` Jinjie Ruan
@ 2026-07-22 18:18 ` Mark Rutland
2026-07-23 1:54 ` Jinjie Ruan
1 sibling, 1 reply; 31+ messages in thread
From: Mark Rutland @ 2026-07-22 18:18 UTC (permalink / raw)
To: Linus Walleij, Jinjie Ruan
Cc: catalin.marinas, will, kees, oleg, luto, wad, thuth, peterz,
ada.coupriediaz, kevin.brodsky, yeoreum.yun, anshuman.khandual,
james.morse, tglx, broonie, pengcan, ryan.roberts, liqiang01,
linux-arm-kernel, linux-kernel, linux-mm
On Tue, Jul 21, 2026 at 10:55:03AM +0200, Linus Walleij wrote:
> On Tue, Jul 21, 2026 at 10:19 AM Jinjie Ruan <ruanjinjie@huawei.com> wrote:
>
> > Syscall User Dispatch (SUD) must not intercept the signal trampoline
> > code, otherwise returning from a signal with a locked selector may
> > cause infinite recursion into the signal handler.
> >
> > Provide an arm64 implementation of arch_syscall_is_vdso_sigreturn()
> > to exclude these sigreturn syscalls from dispatch.
> >
> > For native 64-bit tasks, check whether the current PC matches the 'svc #0'
> > instruction inside the vDSO sigreturn trampoline (defined in
> > arch/arm64/kernel/vdso/sigreturn.S as below).
> >
> > SYM_CODE_START(__kernel_rt_sigreturn)
> > mov x8, #__NR_rt_sigreturn
> > svc #0
> > SYM_CODE_END(__kernel_rt_sigreturn)
> >
> > For COMPAT tasks, verify that the instruction falls within the dedicated
> > 'sigpage' range, since compat signal handlers use this architecture-
> > specific page (not the vDSO) for their return trampoline. This prevents
> > SUD from incorrectly dispatching syscalls issued during signal return.
> >
> > Suggested-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
> > Suggested-by: Kevin Brodsky <kevin.brodsky@arm.com>
> > Suggested-by: kemal <kmal@cock.li>
> > Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
>
> I'm a bit scared about SUD.
>
> Certainly we can merge patches 1-14 first and iron out
> any trouble related to that and split this off so a separate
> series to be applied lated?
I had already asked Jinie to drop SUD back in v14, and he had agreed:
https://lore.kernel.org/lkml/akegeU59jSK9t7FX@J2N7QTR9R3/
https://lore.kernel.org/lkml/3ac6d4be-7c57-44c2-80a0-408e2c6f8136@huawei.com/
Jinjie, please drop this for now, as we had _already_ agreed.
I will look over the rest of the series soon.
Mark.
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v17 15/15] arm64: vdso: Expose sigreturn address on vdso to the kernel
2026-07-22 18:18 ` Mark Rutland
@ 2026-07-23 1:54 ` Jinjie Ruan
0 siblings, 0 replies; 31+ messages in thread
From: Jinjie Ruan @ 2026-07-23 1:54 UTC (permalink / raw)
To: Mark Rutland, Linus Walleij
Cc: catalin.marinas, will, kees, oleg, luto, wad, thuth, peterz,
ada.coupriediaz, kevin.brodsky, yeoreum.yun, anshuman.khandual,
james.morse, tglx, broonie, pengcan, ryan.roberts, liqiang01,
linux-arm-kernel, linux-kernel, linux-mm
在 2026/7/23 2:18, Mark Rutland 写道:
> On Tue, Jul 21, 2026 at 10:55:03AM +0200, Linus Walleij wrote:
>> On Tue, Jul 21, 2026 at 10:19 AM Jinjie Ruan <ruanjinjie@huawei.com> wrote:
>>
>>> Syscall User Dispatch (SUD) must not intercept the signal trampoline
>>> code, otherwise returning from a signal with a locked selector may
>>> cause infinite recursion into the signal handler.
>>>
>>> Provide an arm64 implementation of arch_syscall_is_vdso_sigreturn()
>>> to exclude these sigreturn syscalls from dispatch.
>>>
>>> For native 64-bit tasks, check whether the current PC matches the 'svc #0'
>>> instruction inside the vDSO sigreturn trampoline (defined in
>>> arch/arm64/kernel/vdso/sigreturn.S as below).
>>>
>>> SYM_CODE_START(__kernel_rt_sigreturn)
>>> mov x8, #__NR_rt_sigreturn
>>> svc #0
>>> SYM_CODE_END(__kernel_rt_sigreturn)
>>>
>>> For COMPAT tasks, verify that the instruction falls within the dedicated
>>> 'sigpage' range, since compat signal handlers use this architecture-
>>> specific page (not the vDSO) for their return trampoline. This prevents
>>> SUD from incorrectly dispatching syscalls issued during signal return.
>>>
>>> Suggested-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
>>> Suggested-by: Kevin Brodsky <kevin.brodsky@arm.com>
>>> Suggested-by: kemal <kmal@cock.li>
>>> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
>>
>> I'm a bit scared about SUD.
>>
>> Certainly we can merge patches 1-14 first and iron out
>> any trouble related to that and split this off so a separate
>> series to be applied lated?
>
> I had already asked Jinie to drop SUD back in v14, and he had agreed:
>
> https://lore.kernel.org/lkml/akegeU59jSK9t7FX@J2N7QTR9R3/
> https://lore.kernel.org/lkml/3ac6d4be-7c57-44c2-80a0-408e2c6f8136@huawei.com/
>
> Jinjie, please drop this for now, as we had _already_ agreed.
Ah, sorry about that.I will drop this SUD patch in the next revision.
>
> I will look over the rest of the series soon.
Thank you! I look forward to your review and feedback on the rest of the
patches.
Thanks,
Jinjie
>
> Mark.
>
^ permalink raw reply [flat|nested] 31+ messages in thread
end of thread, other threads:[~2026-07-23 1:54 UTC | newest]
Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-21 8:18 [PATCH v17 00/15] arm64: entry: Convert to Generic Entry Jinjie Ruan
2026-07-21 8:18 ` [PATCH v17 01/15] arm64: ptrace: Skip syscall exit reporting for PTRACE_SYSEMU_SINGLESTEP Jinjie Ruan
2026-07-21 8:18 ` [PATCH v17 02/15] arm64: ptrace: Rework audit_syscall_entry() Jinjie Ruan
2026-07-21 8:18 ` [PATCH v17 03/15] arm64: ptrace: Open-code seccomp check in syscall_trace_enter() Jinjie Ruan
2026-07-21 8:18 ` [PATCH v17 04/15] arm64: ptrace: Rename and clean up syscall_trace_enter() Jinjie Ruan
2026-07-21 8:39 ` Linus Walleij
2026-07-21 8:18 ` [PATCH v17 05/15] arm64: ptrace: Protect rseq_syscall() from tracer PC modifications Jinjie Ruan
2026-07-21 8:18 ` [PATCH v17 06/15] arm64: syscall: Rework the syscall exit path in el0_svc_common() Jinjie Ruan
2026-07-21 8:43 ` Linus Walleij
2026-07-21 8:45 ` Linus Walleij
2026-07-21 8:18 ` [PATCH v17 07/15] arm64: ptrace: Pass thread flags to trace enter/exit Jinjie Ruan
2026-07-21 8:18 ` [PATCH v17 08/15] arm64: ptrace: Extract arm64_syscall_exit_to_user_mode_work() helper Jinjie Ruan
2026-07-21 8:45 ` Linus Walleij
2026-07-21 8:18 ` [PATCH v17 09/15] arm64: ptrace: Align syscall exit work semantics with generic entry Jinjie Ruan
2026-07-21 8:46 ` Linus Walleij
2026-07-21 8:18 ` [PATCH v17 10/15] arm64: syscall: Use exit-specific flags check in el0_svc_common() Jinjie Ruan
2026-07-21 8:18 ` [PATCH v17 11/15] arm64: syscall: Simplify el0_svc_common() syscall exit path Jinjie Ruan
2026-07-21 8:51 ` Linus Walleij
2026-07-21 9:30 ` Jinjie Ruan
2026-07-21 8:18 ` [PATCH v17 12/15] arm64: ptrace: Make return type of arm64_syscall_trace_enter() bool Jinjie Ruan
2026-07-21 8:52 ` Linus Walleij
2026-07-21 8:18 ` [PATCH v17 13/15] arm64: entry: Convert to generic entry Jinjie Ruan
2026-07-21 8:18 ` [PATCH v17 14/15] arm64: Inline el0_svc_common() Jinjie Ruan
2026-07-21 8:18 ` [PATCH v17 15/15] arm64: vdso: Expose sigreturn address on vdso to the kernel Jinjie Ruan
2026-07-21 8:51 ` Thomas Weißschuh
2026-07-21 9:23 ` Jinjie Ruan
2026-07-21 9:55 ` Thomas Weißschuh
2026-07-21 8:55 ` Linus Walleij
2026-07-21 9:27 ` Jinjie Ruan
2026-07-22 18:18 ` Mark Rutland
2026-07-23 1:54 ` Jinjie Ruan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®