summaryrefslogtreecommitdiff
path: root/arch/alpha/include/asm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-04-17 08:34:43 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-04-17 08:34:43 -0700
commita10e80be6343cbdaabe80f82cbd640fe3772d102 (patch)
treea6d9fd3d5f96dfd01df0dd88753cdae52699c181 /arch/alpha/include/asm
parent01f492e1817e858d1712f2489d0afbaa552f417b (diff)
parentbd39fc81340aed5445c731eb391af9ac9a701658 (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/asm')
-rw-r--r--arch/alpha/include/asm/pgtable.h11
-rw-r--r--arch/alpha/include/asm/seccomp.h13
-rw-r--r--arch/alpha/include/asm/syscall.h90
-rw-r--r--arch/alpha/include/asm/thread_info.h16
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)