1caab277bSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */ 2f27bb139SMarc Zyngier /* 3f27bb139SMarc Zyngier * Copyright (C) 2012 ARM Ltd. 4f27bb139SMarc Zyngier */ 5f27bb139SMarc Zyngier #ifndef __ASM_SYSCALL_H 6f27bb139SMarc Zyngier #define __ASM_SYSCALL_H 7f27bb139SMarc Zyngier 8875cbf3eSAKASHI Takahiro #include <uapi/linux/audit.h> 9875cbf3eSAKASHI Takahiro #include <linux/compat.h> 10f27bb139SMarc Zyngier #include <linux/err.h> 11f27bb139SMarc Zyngier 128ef8f368SSami Tolvanen typedef long (*syscall_fn_t)(const struct pt_regs *regs); 1327d83e68SMark Rutland 1427d83e68SMark Rutland extern const syscall_fn_t sys_call_table[]; 15f27bb139SMarc Zyngier 163b714275SMark Rutland #ifdef CONFIG_COMPAT 173b714275SMark Rutland extern const syscall_fn_t compat_sys_call_table[]; 183b714275SMark Rutland #endif 193b714275SMark Rutland 20f27bb139SMarc Zyngier static inline int syscall_get_nr(struct task_struct *task, 21f27bb139SMarc Zyngier struct pt_regs *regs) 22f27bb139SMarc Zyngier { 23f27bb139SMarc Zyngier return regs->syscallno; 24f27bb139SMarc Zyngier } 25f27bb139SMarc Zyngier 26f27bb139SMarc Zyngier static inline void syscall_rollback(struct task_struct *task, 27f27bb139SMarc Zyngier struct pt_regs *regs) 28f27bb139SMarc Zyngier { 29f27bb139SMarc Zyngier regs->regs[0] = regs->orig_x0; 30f27bb139SMarc Zyngier } 31f27bb139SMarc Zyngier 32f27bb139SMarc Zyngier 33f27bb139SMarc Zyngier static inline long syscall_get_error(struct task_struct *task, 34f27bb139SMarc Zyngier struct pt_regs *regs) 35f27bb139SMarc Zyngier { 36f27bb139SMarc Zyngier unsigned long error = regs->regs[0]; 37f27bb139SMarc Zyngier return IS_ERR_VALUE(error) ? error : 0; 38f27bb139SMarc Zyngier } 39f27bb139SMarc Zyngier 40f27bb139SMarc Zyngier static inline long syscall_get_return_value(struct task_struct *task, 41f27bb139SMarc Zyngier struct pt_regs *regs) 42f27bb139SMarc Zyngier { 43f27bb139SMarc Zyngier return regs->regs[0]; 44f27bb139SMarc Zyngier } 45f27bb139SMarc Zyngier 46f27bb139SMarc Zyngier static inline void syscall_set_return_value(struct task_struct *task, 47f27bb139SMarc Zyngier struct pt_regs *regs, 48f27bb139SMarc Zyngier int error, long val) 49f27bb139SMarc Zyngier { 50f27bb139SMarc Zyngier regs->regs[0] = (long) error ? error : val; 51f27bb139SMarc Zyngier } 52f27bb139SMarc Zyngier 53f27bb139SMarc Zyngier #define SYSCALL_MAX_ARGS 6 54f27bb139SMarc Zyngier 55f27bb139SMarc Zyngier static inline void syscall_get_arguments(struct task_struct *task, 56f27bb139SMarc Zyngier struct pt_regs *regs, 57f27bb139SMarc Zyngier unsigned long *args) 58f27bb139SMarc Zyngier { 59f27bb139SMarc Zyngier args[0] = regs->orig_x0; 60f27bb139SMarc Zyngier args++; 61f27bb139SMarc Zyngier 62b35f549dSSteven Rostedt (Red Hat) memcpy(args, ®s->regs[1], 5 * sizeof(args[0])); 63f27bb139SMarc Zyngier } 64f27bb139SMarc Zyngier 65f27bb139SMarc Zyngier static inline void syscall_set_arguments(struct task_struct *task, 66f27bb139SMarc Zyngier struct pt_regs *regs, 67f27bb139SMarc Zyngier const unsigned long *args) 68f27bb139SMarc Zyngier { 69f27bb139SMarc Zyngier regs->orig_x0 = args[0]; 70f27bb139SMarc Zyngier args++; 71f27bb139SMarc Zyngier 7232d92586SSteven Rostedt (VMware) memcpy(®s->regs[1], args, 5 * sizeof(args[0])); 73f27bb139SMarc Zyngier } 74f27bb139SMarc Zyngier 75875cbf3eSAKASHI Takahiro /* 76875cbf3eSAKASHI Takahiro * We don't care about endianness (__AUDIT_ARCH_LE bit) here because 77875cbf3eSAKASHI Takahiro * AArch64 has the same system calls both on little- and big- endian. 78875cbf3eSAKASHI Takahiro */ 7916add411SDmitry V. Levin static inline int syscall_get_arch(struct task_struct *task) 80875cbf3eSAKASHI Takahiro { 8116add411SDmitry V. Levin if (is_compat_thread(task_thread_info(task))) 82875cbf3eSAKASHI Takahiro return AUDIT_ARCH_ARM; 83875cbf3eSAKASHI Takahiro 84875cbf3eSAKASHI Takahiro return AUDIT_ARCH_AARCH64; 85875cbf3eSAKASHI Takahiro } 86875cbf3eSAKASHI Takahiro 87f27bb139SMarc Zyngier #endif /* __ASM_SYSCALL_H */ 88