Enable the seccomp BPF selftests on Alpha with a fallback seccomp syscall number and architecture-specific syscall register accessors.
Use the NT_PRSTATUS register layout rather than struct pt_regs. The register set contains r0-r30 followed by pc and unique. Read and update the syscall number in r1, and set both r0 and the r19/a3 error flag when synthesizing syscall results. Skip the pre-notification signal test when /proc/self/syscall is absent, rather than unconditionally skipping it on Alpha. Kernel support for seccomp is already upstream for alpha so this is for the tools selftests only. Signed-off-by: Magnus Lindholm <[email protected]> --- Changes in v2: - Use the NT_PRSTATUS layout for PTRACE_GETREGSET/PTRACE_SETREGSET. - Set the Alpha return value and error flag together. - Check for /proc/self/syscall at runtime before creating child processes. Link to v1: https://lore.kernel.org/linux-alpha/[email protected]/ Tested on an AlphaServer ES40 (EV67 Tsunami), running 7.3.0-rc1-00010-g19a47cb46b82, built with GCC 15.2.1: PASSED: 111 / 111 tests passed. Totals: pass:99 fail:0 xfail:0 xpass:0 skip:12 error:0 Applied and built on my alpha/for-next at 29289afbc513df29f0f981d45676980ed8eb13d2. tools/testing/selftests/seccomp/seccomp_bpf.c | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c index 0622bc2..92d3713 100644 --- a/tools/testing/selftests/seccomp/seccomp_bpf.c +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c @@ -136,6 +136,8 @@ struct seccomp_data { # define __NR_seccomp 354 # elif defined(__x86_64__) # define __NR_seccomp 317 +# elif defined(__alpha__) +# define __NR_seccomp 514 # elif defined(__arm__) # define __NR_seccomp 383 # elif defined(__aarch64__) @@ -1754,6 +1756,25 @@ TEST_F(TRACE_poke, getpid_runs_normally) # define ARCH_REGS struct user_regs_struct # define SYSCALL_NUM(_regs) (_regs).orig_eax # define SYSCALL_RET(_regs) (_regs).eax +#elif defined(__alpha__) +/* NT_PRSTATUS contains r0-r30, pc and unique, not struct pt_regs. */ +struct alpha_regs { + unsigned long regs[33]; +}; + +# define ARCH_REGS struct alpha_regs +/* The kernel keeps the mutable syscall number in r1. */ +# define SYSCALL_NUM(_regs) ((_regs).regs[1]) +# define SYSCALL_RET(_regs) ((_regs).regs[0]) +/* Alpha returns positive errno in r0 with the r19/a3 error flag set. */ +# define SYSCALL_RET_SET(_regs, _val) \ + do { \ + struct alpha_regs *__regs = &(_regs); \ + long __ret = (_val); \ + \ + __regs->regs[0] = __ret < 0 ? -__ret : __ret; \ + __regs->regs[19] = __ret < 0; \ + } while (0) #elif defined(__arm__) # define ARCH_REGS struct pt_regs # define SYSCALL_NUM(_regs) (_regs).ARM_r7 @@ -4652,6 +4673,9 @@ TEST(user_notification_wait_killable_pre_notification) /* 100 ms */ struct timespec delay = { .tv_nsec = 100000000 }; + if (access("/proc/self/syscall", R_OK) != 0 && errno == ENOENT) + SKIP(return, "/proc/<pid>/syscall not available on this kernel"); + ASSERT_EQ(sigemptyset(&new_action.sa_mask), 0); ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); -- 2.43.0

