[PATCH v21 00/15] arm64: entry: Convert to Generic Entry

From: Jinjie Ruan

Date: Wed Nov 11 2026 - 06:45:04 EST


This series converts arm64 to the generic entry infrastructure.

Currently, architectures such as x86, RISC-V, LoongArch, PowerPC and
S390 use generic entry, which significantly reduces maintenance burden
and improves code elegance. arm64 already adopted generic IRQ entry
in commit b3cf07851b6c ("arm64: entry: Switch to generic IRQ entry"),
making it the right time to complete the conversion.

This work brings arm64 in line with other major architectures,
reducing duplicated code and enabling future improvements like
Syscall User Dispatch and rseq time slice extension optimizations.

What this series does
=====================

Patch 1-2: Fix two issues related to rseq and pseudo single-step.
Patch 3-12: Do some minor refactoring to gradually align the generic
entry code, without functional changes intended.
Patch 13: Officially switch ARM64 to the generic entry, used the
functions provided by the framework, and deleted the
duplicate code corresponding to ARM64.
Patch 14: Inline el0_svc_common() function to prevent performance
regression.
Patch 15: Add related ptrace test cases and rseq test cases for two
bug fixes.

Testing
========

Observable (non-ABI) changes worth calling out:

- The traceable functions on the syscall path change: syscall_trace_enter,
syscall_trace_exit and el0_svc_common.constprop.0 are replaced by
trace_syscall_enter, trace_syscall_exit and syscall_enter_audit, the
same names x86, RISC-V, LoongArch already expose.

- CONFIG_DEBUG_RSEQ becomes unselectable on arm64 once GENERIC_ENTRY is
set (rseq_syscall() becomes a no-op stub). The equivalent check is
done by __rseq_debug_syscall_return(), enabled with the "rseq_debug="
boot option.

The new added selftests pass, and the rseq test also passes with
"rseq_debug=1" after the conversion.

On a KVM VM (2 vCPU pinned, LOCKDEP off), with the same config, the
syscall hot path shows no measurable regression. Each row below is
the mean of 10 runs:

| Benchmark | baseline | generic entry |
| --------------------------------- | -------- | ------------- |
| UnixBench System Call Overhead | 879982 | 877908 |
| perf bench syscall basic 1M (ns) | 197.29 | 197.37 |

Both differences are within the noise, so there is no measurable impact
on syscall overhead.

Stress-ng (syscall and cpu) and the kselftests (breakpoints, arm64/abi,
arm64/fp, vDSO) were also run and all pass.

The hackbench, ptrace stress, Pseudo-NMI and rr test suite [1] reported
for v20 were not repeated as the code unchanged apart from the rebase.

On gVisor with systrap mode, the Syscall User Dispatch (SUD) feature
yields a slightly lower performance gain on arm64 (3% ~ 5%), similar to
that on x86 [2].

Result: the average over 1M getpid calls, ns/op

| KVM VM Configuration | SUD | no-SUD | Savings % |
| ------------------- | ----- | -------| --------- |
| 2 vCPU, pinned | 4269.8 | 4509.5 | 5.3% |
| 4 vCPU, pinned | 4175.4 | 4369.1 | 4.4% |
| 8 vCPU, pinned | 4352.6 | 4485.4 | 3.0% |

Note that this series does not yet enable SUD or the rseq time slice
extension on arm64: SUD additionally needs
ARCH_SUPPORTS_SYSCALL_USER_DISPATCH [3] and the rseq slice extension
needs HAVE_GENERIC_TIF_BITS [4], neither of which arm64 selects today.
The numbers above are the motivation for enabling them in a follow-up.

The new selftests and tests are helped by an agent.

Testing follow-up that still requires real hardware:

- MTE: run the MTE selftests on real hardware; part of them do not run
under QEMU.

[1]: https://github.com/rr-debugger/rr/wiki/Building-And-Installing#tests
[2]: https://github.com/google/gvisor/commit/a45d6227b521012109cde9a942d644d778eb773b
[3]: https://lore.kernel.org/all/20260721081858.1169276-16-ruanjinjie@xxxxxxxxxx/
[4]: https://lore.kernel.org/all/20260320104222.1381274-1-ruanjinjie@xxxxxxxxxx/

The series is rebased on v7.4-rc1 and also available at:
https://github.com/ruanjinjie-eng/linux/commits/arm64_generic_entry_v21

Changes in v21:
- Rebased on v7.4-rc1.
- Pseudo-single-step patch rewritten as a bugfix.
- Rseq patch rewritten as a bugfix and moved to the front.
- Retitle and update the commit message.
- Selftests: replace the 2 SYSEMU tests with 5 tests that reproduce
the problems fixed by the commit ac2081cdc4d99 ("arm64: ptrace:
Consistently use pseudo-singlestep exceptions") series and the rseq
issue.
- Solve the sashiko commit message issue.
- Link to v20: https://lore.kernel.org/all/20260930101805.1770358-1-ruanjinjie@xxxxxxxxxx/

Changes in v20:
- Add a kselftest covering the syscall-exit pseudo-step
and single-step behaviour.
- Reword the first patch: it skips the pseudo-step for the emulated
syscall rather than "fixing a redundant exit stop", and drop the
Fixes: tag and Reviewed-by.
- Add Tested-by.
- Cover letter: document the observable changes and the testing
follow-ups.
- Link to v19: https://lore.kernel.org/all/20260922035510.1090299-1-ruanjinjie@xxxxxxxxxx/

Changes in v19:
- Rebased on v7.3-rc4.
- Fix build problem as Karl pointed out.
- Remove has_syscall_work() later to make it more clear.
- Add gvisor test data.
- Link to v18: https://lore.kernel.org/all/20260902095537.602517-2-ruanjinjie@xxxxxxxxxx/

For changes in v7 to v17, please refer to the individual patch threads:
- v17: https://lore.kernel.org/all/20260721081858.1169276-1-ruanjinjie@xxxxxxxxxx/
- v16: https://lore.kernel.org/all/20260629130616.642022-1-ruanjinjie@xxxxxxxxxx/
- v15: https://lore.kernel.org/all/20260511092103.1974980-1-ruanjinjie@xxxxxxxxxx/
- v14: https://lore.kernel.org/all/20260320102620.1336796-1-ruanjinjie@xxxxxxxxxx/
- v13: https://lore.kernel.org/all/20260317082020.737779-1-ruanjinjie@xxxxxxxxxx/
- v12: https://lore.kernel.org/all/20260203133728.848283-1-ruanjinjie@xxxxxxxxxx/
- v11: https://lore.kernel.org/all/20260128031934.3906955-1-ruanjinjie@xxxxxxxxxx/
- v10: https://lore.kernel.org/all/20251222114737.1334364-1-ruanjinjie@xxxxxxxxxx/
- v9: https://lore.kernel.org/all/20251204082123.2792067-1-ruanjinjie@xxxxxxxxxx/
- v8: https://lore.kernel.org/all/20251126071446.3234218-1-ruanjinjie@xxxxxxxxxx/
- v7: https://lore.kernel.org/all/20251117133048.53182-1-ruanjinjie@xxxxxxxxxx/

Jinjie Ruan (15):
arm64: ptrace: Fix spurious pseudo-single-step for
PTRACE_SYSEMU_SINGLESTEP
arm64: ptrace: Check rseq critical section before reporting syscall
exit
arm64: ptrace: Add syscall_enter_audit() helper
arm64: ptrace: Open-code seccomp check in syscall_trace_enter()
arm64: ptrace: Rename and clean up syscall_trace_enter()
arm64: syscall: Invert the exit-path flags check 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: Only run syscall exit work when exit work flags are set
arm64: syscall: Use exit-specific flags check in el0_svc_common()
arm64: syscall: Simplify el0_svc_common() syscall exit path
arm64: ptrace: Return bool from arm64_syscall_trace_enter()
arm64: entry: Convert to generic entry
arm64: Inline el0_svc_common()
selftests/arm64: Add ptrace single-step and rseq syscall-exit tests

arch/arm64/Kconfig | 2 +-
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 ++--
tools/testing/selftests/arm64/Makefile | 2 +-
tools/testing/selftests/arm64/ptrace/Makefile | 12 ++
.../selftests/arm64/ptrace/ptrace_common.h | 101 ++++++++++
.../selftests/arm64/ptrace/rseq_syscall_pc.c | 130 +++++++++++++
.../selftests/arm64/ptrace/rseq_syscall_pc.h | 22 +++
.../arm64/ptrace/rseq_syscall_pc_asm.S | 45 +++++
.../arm64/ptrace/single_step_signal_handler.c | 121 ++++++++++++
.../arm64/ptrace/single_step_spsr_ss.c | 79 ++++++++
.../arm64/ptrace/single_step_syscall_stop.c | 138 ++++++++++++++
.../arm64/ptrace/sysemu_singlestep.c | 172 ++++++++++++++++++
19 files changed, 923 insertions(+), 160 deletions(-)
create mode 100644 tools/testing/selftests/arm64/ptrace/Makefile
create mode 100644 tools/testing/selftests/arm64/ptrace/ptrace_common.h
create mode 100644 tools/testing/selftests/arm64/ptrace/rseq_syscall_pc.c
create mode 100644 tools/testing/selftests/arm64/ptrace/rseq_syscall_pc.h
create mode 100644 tools/testing/selftests/arm64/ptrace/rseq_syscall_pc_asm.S
create mode 100644 tools/testing/selftests/arm64/ptrace/single_step_signal_handler.c
create mode 100644 tools/testing/selftests/arm64/ptrace/single_step_spsr_ss.c
create mode 100644 tools/testing/selftests/arm64/ptrace/single_step_syscall_stop.c
create mode 100644 tools/testing/selftests/arm64/ptrace/sysemu_singlestep.c

--
2.34.1