linux/arch/arm/include/asm/syscall.h
<<
>>
Prefs
   1/*
   2 * Access to user system call parameters and results
   3 *
   4 * See asm-generic/syscall.h for descriptions of what we must do here.
   5 */
   6
   7#ifndef _ASM_ARM_SYSCALL_H
   8#define _ASM_ARM_SYSCALL_H
   9
  10#include <uapi/linux/audit.h> /* for AUDIT_ARCH_* */
  11#include <linux/elf.h> /* for ELF_EM */
  12#include <linux/err.h>
  13#include <linux/sched.h>
  14
  15#include <asm/unistd.h>
  16
  17#define NR_syscalls (__NR_syscalls)
  18
  19extern const unsigned long sys_call_table[];
  20
  21static inline int syscall_get_nr(struct task_struct *task,
  22                                 struct pt_regs *regs)
  23{
  24        return task_thread_info(task)->syscall;
  25}
  26
  27static inline void syscall_rollback(struct task_struct *task,
  28                                    struct pt_regs *regs)
  29{
  30        regs->ARM_r0 = regs->ARM_ORIG_r0;
  31}
  32
  33static inline long syscall_get_error(struct task_struct *task,
  34                                     struct pt_regs *regs)
  35{
  36        unsigned long error = regs->ARM_r0;
  37        return IS_ERR_VALUE(error) ? error : 0;
  38}
  39
  40static inline long syscall_get_return_value(struct task_struct *task,
  41                                            struct pt_regs *regs)
  42{
  43        return regs->ARM_r0;
  44}
  45
  46static inline void syscall_set_return_value(struct task_struct *task,
  47                                            struct pt_regs *regs,
  48                                            int error, long val)
  49{
  50        regs->ARM_r0 = (long) error ? error : val;
  51}
  52
  53#define SYSCALL_MAX_ARGS 7
  54
  55static inline void syscall_get_arguments(struct task_struct *task,
  56                                         struct pt_regs *regs,
  57                                         unsigned int i, unsigned int n,
  58                                         unsigned long *args)
  59{
  60        if (n == 0)
  61                return;
  62
  63        if (i + n > SYSCALL_MAX_ARGS) {
  64                unsigned long *args_bad = args + SYSCALL_MAX_ARGS - i;
  65                unsigned int n_bad = n + i - SYSCALL_MAX_ARGS;
  66                pr_warn("%s called with max args %d, handling only %d\n",
  67                        __func__, i + n, SYSCALL_MAX_ARGS);
  68                memset(args_bad, 0, n_bad * sizeof(args[0]));
  69                n = SYSCALL_MAX_ARGS - i;
  70        }
  71
  72        if (i == 0) {
  73                args[0] = regs->ARM_ORIG_r0;
  74                args++;
  75                i++;
  76                n--;
  77        }
  78
  79        memcpy(args, &regs->ARM_r0 + i, n * sizeof(args[0]));
  80}
  81
  82static inline void syscall_set_arguments(struct task_struct *task,
  83                                         struct pt_regs *regs,
  84                                         unsigned int i, unsigned int n,
  85                                         const unsigned long *args)
  86{
  87        if (n == 0)
  88                return;
  89
  90        if (i + n > SYSCALL_MAX_ARGS) {
  91                pr_warn("%s called with max args %d, handling only %d\n",
  92                        __func__, i + n, SYSCALL_MAX_ARGS);
  93                n = SYSCALL_MAX_ARGS - i;
  94        }
  95
  96        if (i == 0) {
  97                regs->ARM_ORIG_r0 = args[0];
  98                args++;
  99                i++;
 100                n--;
 101        }
 102
 103        memcpy(&regs->ARM_r0 + i, args, n * sizeof(args[0]));
 104}
 105
 106static inline int syscall_get_arch(void)
 107{
 108        /* ARM tasks don't change audit architectures on the fly. */
 109        return AUDIT_ARCH_ARM;
 110}
 111
 112#endif /* _ASM_ARM_SYSCALL_H */
 113