0001
0002
0003
0004
0005 #ifndef __ASM_SYSCALL_H
0006 #define __ASM_SYSCALL_H
0007
0008 #include <uapi/linux/audit.h>
0009 #include <linux/compat.h>
0010 #include <linux/err.h>
0011
0012 typedef long (*syscall_fn_t)(const struct pt_regs *regs);
0013
0014 extern const syscall_fn_t sys_call_table[];
0015
0016 #ifdef CONFIG_COMPAT
0017 extern const syscall_fn_t compat_sys_call_table[];
0018 #endif
0019
0020 static inline int syscall_get_nr(struct task_struct *task,
0021 struct pt_regs *regs)
0022 {
0023 return regs->syscallno;
0024 }
0025
0026 static inline void syscall_rollback(struct task_struct *task,
0027 struct pt_regs *regs)
0028 {
0029 regs->regs[0] = regs->orig_x0;
0030 }
0031
0032 static inline long syscall_get_return_value(struct task_struct *task,
0033 struct pt_regs *regs)
0034 {
0035 unsigned long val = regs->regs[0];
0036
0037 if (is_compat_thread(task_thread_info(task)))
0038 val = sign_extend64(val, 31);
0039
0040 return val;
0041 }
0042
0043 static inline long syscall_get_error(struct task_struct *task,
0044 struct pt_regs *regs)
0045 {
0046 unsigned long error = syscall_get_return_value(task, regs);
0047
0048 return IS_ERR_VALUE(error) ? error : 0;
0049 }
0050
0051 static inline void syscall_set_return_value(struct task_struct *task,
0052 struct pt_regs *regs,
0053 int error, long val)
0054 {
0055 if (error)
0056 val = error;
0057
0058 if (is_compat_thread(task_thread_info(task)))
0059 val = lower_32_bits(val);
0060
0061 regs->regs[0] = val;
0062 }
0063
0064 #define SYSCALL_MAX_ARGS 6
0065
0066 static inline void syscall_get_arguments(struct task_struct *task,
0067 struct pt_regs *regs,
0068 unsigned long *args)
0069 {
0070 args[0] = regs->orig_x0;
0071 args++;
0072
0073 memcpy(args, ®s->regs[1], 5 * sizeof(args[0]));
0074 }
0075
0076
0077
0078
0079
0080 static inline int syscall_get_arch(struct task_struct *task)
0081 {
0082 if (is_compat_thread(task_thread_info(task)))
0083 return AUDIT_ARCH_ARM;
0084
0085 return AUDIT_ARCH_AARCH64;
0086 }
0087
0088 #endif