Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Copyright (C) 2012 ARM Ltd.
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, &regs->regs[1], 5 * sizeof(args[0]));
0074 }
0075 
0076 /*
0077  * We don't care about endianness (__AUDIT_ARCH_LE bit) here because
0078  * AArch64 has the same system calls both on little- and big- endian.
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  /* __ASM_SYSCALL_H */