linux/arch/sh/include/asm/syscall_32.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef __ASM_SH_SYSCALL_32_H
   3#define __ASM_SH_SYSCALL_32_H
   4
   5#include <uapi/linux/audit.h>
   6#include <linux/kernel.h>
   7#include <linux/sched.h>
   8#include <linux/err.h>
   9#include <asm/ptrace.h>
  10
  11/* The system call number is given by the user in R3 */
  12static inline long syscall_get_nr(struct task_struct *task,
  13                                  struct pt_regs *regs)
  14{
  15        return (regs->tra >= 0) ? regs->regs[3] : -1L;
  16}
  17
  18static inline void syscall_rollback(struct task_struct *task,
  19                                    struct pt_regs *regs)
  20{
  21        /*
  22         * XXX: This needs some thought. On SH we don't
  23         * save away the original r0 value anywhere.
  24         */
  25}
  26
  27static inline long syscall_get_error(struct task_struct *task,
  28                                     struct pt_regs *regs)
  29{
  30        return IS_ERR_VALUE(regs->regs[0]) ? regs->regs[0] : 0;
  31}
  32
  33static inline long syscall_get_return_value(struct task_struct *task,
  34                                            struct pt_regs *regs)
  35{
  36        return regs->regs[0];
  37}
  38
  39static inline void syscall_set_return_value(struct task_struct *task,
  40                                            struct pt_regs *regs,
  41                                            int error, long val)
  42{
  43        if (error)
  44                regs->regs[0] = -error;
  45        else
  46                regs->regs[0] = val;
  47}
  48
  49static inline void syscall_get_arguments(struct task_struct *task,
  50                                         struct pt_regs *regs,
  51                                         unsigned int i, unsigned int n,
  52                                         unsigned long *args)
  53{
  54        /*
  55         * Do this simply for now. If we need to start supporting
  56         * fetching arguments from arbitrary indices, this will need some
  57         * extra logic. Presently there are no in-tree users that depend
  58         * on this behaviour.
  59         */
  60        BUG_ON(i);
  61
  62        /* Argument pattern is: R4, R5, R6, R7, R0, R1 */
  63        switch (n) {
  64        case 6: args[5] = regs->regs[1];
  65        case 5: args[4] = regs->regs[0];
  66        case 4: args[3] = regs->regs[7];
  67        case 3: args[2] = regs->regs[6];
  68        case 2: args[1] = regs->regs[5];
  69        case 1: args[0] = regs->regs[4];
  70        case 0:
  71                break;
  72        default:
  73                BUG();
  74        }
  75}
  76
  77static inline void syscall_set_arguments(struct task_struct *task,
  78                                         struct pt_regs *regs,
  79                                         unsigned int i, unsigned int n,
  80                                         const unsigned long *args)
  81{
  82        /* Same note as above applies */
  83        BUG_ON(i);
  84
  85        switch (n) {
  86        case 6: regs->regs[1] = args[5];
  87        case 5: regs->regs[0] = args[4];
  88        case 4: regs->regs[7] = args[3];
  89        case 3: regs->regs[6] = args[2];
  90        case 2: regs->regs[5] = args[1];
  91        case 1: regs->regs[4] = args[0];
  92                break;
  93        default:
  94                BUG();
  95        }
  96}
  97
  98static inline int syscall_get_arch(void)
  99{
 100        int arch = AUDIT_ARCH_SH;
 101
 102#ifdef CONFIG_CPU_LITTLE_ENDIAN
 103        arch |= __AUDIT_ARCH_LE;
 104#endif
 105        return arch;
 106}
 107#endif /* __ASM_SH_SYSCALL_32_H */
 108