projects/linux·blob master · refs

122 lines · 3.1 KiB

1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _ASM_ALPHA_SYSCALL_H
3#define _ASM_ALPHA_SYSCALL_H
4
5#include <uapi/linux/audit.h>
6#include <linux/audit.h>
7#include <linux/sched.h>
8#include <linux/types.h>
9#include <asm/ptrace.h>
10
11extern void *sys_call_table[];
12
13static inline int syscall_get_arch(struct task_struct *task)
14{
15 return AUDIT_ARCH_ALPHA;
16}
17
18static inline long syscall_get_return_value(struct task_struct *task,
19 struct pt_regs *regs)
20{
21 return regs->r19 ? -(long)regs->r0 : (long)regs->r0;
22}
23
24static inline long syscall_get_error(struct task_struct *task,
25 struct pt_regs *regs)
26{
27 return regs->r19 ? -(long)regs->r0 : 0;
28}
29
30
31/*
32 * Alpha syscall ABI / kernel conventions:
33 * - PAL provides syscall number in r0 on entry.
34 * - The kernel tracks the active syscall number in regs->r1 (mutable) and
35 * preserves the original syscall number in regs->r2 for rollback/restart.
36 * - Return value is in regs->r0, with regs->r19 ("a3") as the error flag
37 * (0=success, 1=error; on error regs->r0 holds positive errno).
38 */
39
40static inline long syscall_get_nr(struct task_struct *task,
41 struct pt_regs *regs)
42{
43 return (long)regs->r1;
44}
45
46static inline void syscall_set_nr(struct task_struct *task,
47 struct pt_regs *regs,
48 long nr)
49{
50 regs->r1 = (unsigned long)nr;
51}
52
53/*
54 * Syscall arguments:
55 * regs->r16..regs->r21 carry up to 6 syscall arguments on entry.
56 * Note: regs->r19 is also used as "a3" (error flag) on syscall return.
57 */
58
59static inline void syscall_get_arguments(struct task_struct *task,
60 struct pt_regs *regs,
61 unsigned long *args)
62{
63 args[0] = regs->r16;
64 args[1] = regs->r17;
65 args[2] = regs->r18;
66 args[3] = regs->r19;
67 args[4] = regs->r20;
68 args[5] = regs->r21;
69}
70
71static inline void syscall_set_arguments(struct task_struct *task,
72 struct pt_regs *regs,
73 const unsigned long *args)
74{
75 regs->r16 = args[0];
76 regs->r17 = args[1];
77 regs->r18 = args[2];
78 regs->r19 = args[3];
79 regs->r20 = args[4];
80 regs->r21 = args[5];
81}
82/*
83 * Set return value for a syscall.
84 * Alpha uses r0 for return value and r19 ("a3") as the error indicator:
85 * a3 = 0 => success
86 * a3 = 1 => error, and userspace interprets r0 as errno (positive).
87 *
88 * The kernel reports errors to userspace by setting a3=1 and placing a
89 * positive errno value in r0. Some syscall paths do this in entry.S,
90 * while others (e.g. seccomp/ptrace helpers) use syscall_set_return_value().
91 */
92
93static inline void syscall_set_return_value(struct task_struct *task,
94 struct pt_regs *regs,
95 int error, long val)
96{
97
98 if (error) {
99 /* error is negative errno in this tree */
100 regs->r0 = (unsigned long)(-error); /* positive errno */
101 regs->r19 = 1; /* a3 = error */
102 } else {
103 regs->r0 = (unsigned long)val;
104 regs->r19 = 0; /* a3 = success */
105 }
106}
107
108/* Restore the original syscall nr after seccomp/ptrace modified regs->r1. */
109
110static inline void syscall_rollback(struct task_struct *task,
111 struct pt_regs *regs)
112{
113 unsigned long nr = task_thread_info(task)->syscall_saved_nr;
114
115 regs->r1 = nr;
116}
117
118static inline bool arch_syscall_is_vdso_sigreturn(struct pt_regs *regs)
119{
120 return false;
121}
122#endif /* _ASM_ALPHA_SYSCALL_H */