[PATCH v3 0/2] powerpc/syscall: Fix the return value of skipped syscalls

From: Renzo Davoli

Date: Fri Oct 30 2026 - 04:51:38 EST


When ptrace or seccomp skip a system call on powerpc, the return value
they set is lost or the tracer is affected:

- syscall_set_return_value() sets TIF_SYSCALL_RET on current, which is
the tracer when called through PTRACE_SET_SYSCALL_INFO, so the next
system call of the tracer is silently skipped (1/2);

- system_call_exception() returns syscall_get_error() for a skipped
system call, which is 0 for any non-error value, so a success value
set by a tracer or by a SECCOMP_RET_USER_NOTIF listener is replaced
with 0 (2/2).

Both problems are in v7.3. 1/2 does not apply as is to v7.3, which
still has the two separate TIF_SYSCALL_RET checks from before commit
66236558dfac ("powerpc/syscall: Avoid atomic test_and_clear_thread_flag
on fast path"); the code it leaves behind is the same, and 2/2 then
applies on top.

Tested on QEMU pseries (TCG, -cpu power9), ppc64le guest config, on
mainline 734bef548a96, with ppc_skip_repro.c [1] (a tracer sets the
return value with PTRACE_SET_SYSCALL_INFO and then makes a system call;
a tracer skips a system call at a PTRACE_EVENT_SECCOMP stop with
PTRACE_POKEUSER, with both "sc" and "scv 0") and with the ptrace and
seccomp selftests:

mainline + 1/2 + 2/2
tracer syscall after SET_SYSCALL_INFO not run correct correct
skipped syscall, success value, sc/scv returns 0 returns 0 correct
skipped syscall, error value, sc/scv correct correct correct
selftests/ptrace set_syscall_info FAIL pass pass
selftests/seccomp/seccomp_bpf (*) 14 FAIL 14 FAIL all pass

failing in mainline and with 1/2 only:
user_notification_{basic,child_pid_ns,sibling_pid_ns,fault_recv,addfd,
addfd_opath,addfd_rlimit,addfd_send_interrupted,sync,fifo,
wait_killable}, TRACE_syscall.seccomp.syscall_faked,
notification_restart.{killable,both}.after_receive

(*) not counting user_notification_wait_killable_after_reply (100000
notifications with a 1 ms itimer), which hits the 30 s harness
timeout under emulation on all three kernels.

Build-tested with W=1: ppc64le guest config, ppc64_defconfig (BE),
pmac32_defconfig.

Changes in v3:
- Split in two patches, one per Fixes: tag: 1/2 removes TIF_SYSCALL_RET
(suggested by Michal), 2/2 fixes the return value.
- 2/2 returns syscall_get_error() ?: regs->gpr[3] instead of
regs->gpr[3], so the error path is unchanged (suggested by Mukesh).
- Applies unchanged to current mainline (d89e1d186ec9).
- Link to v2:
https://lore.kernel.org/lkml/20261023180735.853655-1-renzo@xxxxxxxxxxx/

Changes in v2:
- Rebased on mainline 734bef548a96, after commit 66236558dfac.
- Link to v1:
https://lore.kernel.org/lkml/20261018151539.440213-1-renzo@xxxxxxxxxxx/

[1] https://lore.kernel.org/lkml/ato6Tq0aKdqqdqyJ@xxxxxxxxxxx/

Renzo Davoli (2):
powerpc/syscall: Remove TIF_SYSCALL_RET
powerpc/syscall: Return the preset value of skipped syscalls

arch/powerpc/include/asm/syscall.h | 6 ------
arch/powerpc/include/asm/thread_info.h | 1 -
arch/powerpc/kernel/syscall.c | 13 +++++++++----
3 files changed, 9 insertions(+), 11 deletions(-)


base-commit: d89e1d186ec9271bf78e62771779e9fc03bf0fc3
--
2.55.0