diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-04-17 08:34:43 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-04-17 08:34:43 -0700 |
| commit | a10e80be6343cbdaabe80f82cbd640fe3772d102 (patch) | |
| tree | a6d9fd3d5f96dfd01df0dd88753cdae52699c181 /arch/alpha/include | |
| parent | 01f492e1817e858d1712f2489d0afbaa552f417b (diff) | |
| parent | bd39fc81340aed5445c731eb391af9ac9a701658 (diff) | |
Merge tag 'alpha-for-v7.1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/lindholm/alpha
Pull alpha updates from Magnus Lindholm:
"One fix to silence pgprot_modify() compiler warnings, and one patch
adding SECCOMP/SECCOMP_FILTER support together with the syscall and
ptrace fixes needed for it"
* tag 'alpha-for-v7.1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/lindholm/alpha:
alpha: Define pgprot_modify to silence tautological comparison warnings
alpha: add support for SECCOMP and SECCOMP_FILTER
Diffstat (limited to 'arch/alpha/include')
| -rw-r--r-- | arch/alpha/include/asm/pgtable.h | 11 | ||||
| -rw-r--r-- | arch/alpha/include/asm/seccomp.h | 13 | ||||
| -rw-r--r-- | arch/alpha/include/asm/syscall.h | 90 | ||||
| -rw-r--r-- | arch/alpha/include/asm/thread_info.h | 16 |
4 files changed, 128 insertions, 2 deletions
diff --git a/arch/alpha/include/asm/pgtable.h b/arch/alpha/include/asm/pgtable.h index 268ddde33617..8e00cf9dc39d 100644 --- a/arch/alpha/include/asm/pgtable.h +++ b/arch/alpha/include/asm/pgtable.h @@ -127,6 +127,17 @@ struct vm_area_struct; #define pgprot_noncached(prot) (prot) /* + * All caching attribute macros are identity on Alpha, so the generic + * pgprot_modify() degenerates to tautological self-comparisons. + * Override it to just return newprot directly. + */ +#define pgprot_modify pgprot_modify +static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot) +{ + return newprot; +} + +/* * On certain platforms whose physical address space can overlap KSEG, * namely EV6 and above, we must re-twiddle the physaddr to restore the * correct high-order bits. diff --git a/arch/alpha/include/asm/seccomp.h b/arch/alpha/include/asm/seccomp.h new file mode 100644 index 000000000000..311934d20340 --- /dev/null +++ b/arch/alpha/include/asm/seccomp.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_ALPHA_SECCOMP_H +#define _ASM_ALPHA_SECCOMP_H + +#include <asm/unistd.h> +#include <asm-generic/seccomp.h> +#include <uapi/linux/audit.h> + +#define SECCOMP_ARCH_NATIVE AUDIT_ARCH_ALPHA +#define SECCOMP_ARCH_NATIVE_NR NR_syscalls +#define SECCOMP_ARCH_NATIVE_NAME "alpha" + +#endif /* _ASM_ALPHA_SECCOMP_H */ diff --git a/arch/alpha/include/asm/syscall.h b/arch/alpha/include/asm/syscall.h index f21babaeed85..584b1ab2e325 100644 --- a/arch/alpha/include/asm/syscall.h +++ b/arch/alpha/include/asm/syscall.h @@ -3,6 +3,10 @@ #define _ASM_ALPHA_SYSCALL_H #include <uapi/linux/audit.h> +#include <linux/audit.h> +#include <linux/sched.h> +#include <linux/types.h> +#include <asm/ptrace.h> static inline int syscall_get_arch(struct task_struct *task) { @@ -12,7 +16,91 @@ static inline int syscall_get_arch(struct task_struct *task) static inline long syscall_get_return_value(struct task_struct *task, struct pt_regs *regs) { - return regs->r0; + return regs->r19 ? -(long)regs->r0 : (long)regs->r0; +} + +/* + * Alpha syscall ABI / kernel conventions: + * - PAL provides syscall number in r0 on entry. + * - The kernel tracks the active syscall number in regs->r1 (mutable) and + * preserves the original syscall number in regs->r2 for rollback/restart. + * - Return value is in regs->r0, with regs->r19 ("a3") as the error flag + * (0=success, 1=error; on error regs->r0 holds positive errno). + */ + +static inline long syscall_get_nr(struct task_struct *task, + struct pt_regs *regs) +{ + return (long)regs->r1; +} + +static inline void syscall_set_nr(struct task_struct *task, + struct pt_regs *regs, + long nr) +{ + regs->r1 = (unsigned long)nr; +} + +/* + * Syscall arguments: + * regs->r16..regs->r21 carry up to 6 syscall arguments on entry. + * Note: regs->r19 is also used as "a3" (error flag) on syscall return. + */ + +static inline void syscall_get_arguments(struct task_struct *task, + struct pt_regs *regs, + unsigned long *args) +{ + args[0] = regs->r16; + args[1] = regs->r17; + args[2] = regs->r18; + args[3] = regs->r19; + args[4] = regs->r20; + args[5] = regs->r21; +} + +static inline void syscall_set_arguments(struct task_struct *task, + struct pt_regs *regs, + const unsigned long *args) +{ + regs->r16 = args[0]; + regs->r17 = args[1]; + regs->r18 = args[2]; + regs->r19 = args[3]; + regs->r20 = args[4]; + regs->r21 = args[5]; +} +/* + * Set return value for a syscall. + * Alpha uses r0 for return value and r19 ("a3") as the error indicator: + * a3 = 0 => success + * a3 = 1 => error, and userspace interprets r0 as errno (positive). + * + * The kernel reports errors to userspace by setting a3=1 and placing a + * positive errno value in r0. Some syscall paths do this in entry.S, + * while others (e.g. seccomp/ptrace helpers) use syscall_set_return_value(). + */ + +static inline void syscall_set_return_value(struct task_struct *task, + struct pt_regs *regs, + int error, long val) +{ + + if (error) { + /* error is negative errno in this tree */ + regs->r0 = (unsigned long)(-error); /* positive errno */ + regs->r19 = 1; /* a3 = error */ + } else { + regs->r0 = (unsigned long)val; + regs->r19 = 0; /* a3 = success */ + } +} + +/* Restore the original syscall nr after seccomp/ptrace modified regs->r1. */ +static inline void syscall_rollback(struct task_struct *task, + struct pt_regs *regs) +{ + regs->r1 = regs->r2; } #endif /* _ASM_ALPHA_SYSCALL_H */ diff --git a/arch/alpha/include/asm/thread_info.h b/arch/alpha/include/asm/thread_info.h index 98ccbca64984..94ef9cfa30f5 100644 --- a/arch/alpha/include/asm/thread_info.h +++ b/arch/alpha/include/asm/thread_info.h @@ -56,7 +56,8 @@ register unsigned long *current_stack_pointer __asm__ ("$30"); * - pending work-to-be-done flags come first and must be assigned to be * within bits 0 to 7 to fit in and immediate operand. * - * TIF_SYSCALL_TRACE is known to be 0 via blbs. + * (Historically TIF_SYSCALL_TRACE was known to be 0 via blbs, but we may + * also test multiple bits via masks now.) */ #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ #define TIF_NOTIFY_RESUME 1 /* callback before returning to user */ @@ -64,6 +65,7 @@ register unsigned long *current_stack_pointer __asm__ ("$30"); #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_SYSCALL_AUDIT 4 /* syscall audit active */ #define TIF_NOTIFY_SIGNAL 5 /* signal notifications exist */ +#define TIF_SECCOMP 6 /* seccomp syscall filtering active */ #define TIF_DIE_IF_KERNEL 9 /* dik recursion lock */ #define TIF_MEMDIE 13 /* is terminating due to OOM killer */ #define TIF_POLLING_NRFLAG 14 /* idle is polling for TIF_NEED_RESCHED */ @@ -74,8 +76,20 @@ register unsigned long *current_stack_pointer __asm__ ("$30"); #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) #define _TIF_NOTIFY_SIGNAL (1<<TIF_NOTIFY_SIGNAL) +#define _TIF_SECCOMP (1<<TIF_SECCOMP) #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) +/* + * Work to do on syscall entry (in entry.S). + * If you want this to exactly mirror what entry.S checks, keep it aligned + * with the mask used before branching to syscall_trace_enter(). + */ +#ifdef CONFIG_AUDITSYSCALL +# define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP) +#else +# define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SECCOMP) +#endif + /* Work to do on interrupt/exception return. */ #define _TIF_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ _TIF_NOTIFY_RESUME | _TIF_NOTIFY_SIGNAL) |
