root/arch/sparc/include/asm/syscall.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. syscall_get_nr
  2. syscall_rollback
  3. syscall_has_error
  4. syscall_set_error
  5. syscall_clear_error
  6. syscall_has_error
  7. syscall_set_error
  8. syscall_clear_error
  9. syscall_get_error
  10. syscall_get_return_value
  11. syscall_set_return_value
  12. syscall_get_arguments
  13. syscall_set_arguments
  14. syscall_get_arch

   1 /* SPDX-License-Identifier: GPL-2.0 */
   2 #ifndef __ASM_SPARC_SYSCALL_H
   3 #define __ASM_SPARC_SYSCALL_H
   4 
   5 #include <uapi/linux/audit.h>
   6 #include <linux/kernel.h>
   7 #include <linux/compat.h>
   8 #include <linux/sched.h>
   9 #include <asm/ptrace.h>
  10 #include <asm/thread_info.h>
  11 
  12 /*
  13  * The syscall table always contains 32 bit pointers since we know that the
  14  * address of the function to be called is (way) below 4GB.  So the "int"
  15  * type here is what we want [need] for both 32 bit and 64 bit systems.
  16  */
  17 extern const unsigned int sys_call_table[];
  18 
  19 /* The system call number is given by the user in %g1 */
  20 static inline long syscall_get_nr(struct task_struct *task,
  21                                   struct pt_regs *regs)
  22 {
  23         int syscall_p = pt_regs_is_syscall(regs);
  24 
  25         return (syscall_p ? regs->u_regs[UREG_G1] : -1L);
  26 }
  27 
  28 static inline void syscall_rollback(struct task_struct *task,
  29                                     struct pt_regs *regs)
  30 {
  31         /* XXX This needs some thought.  On Sparc we don't
  32          * XXX save away the original %o0 value somewhere.
  33          * XXX Instead we hold it in register %l5 at the top
  34          * XXX level trap frame and pass this down to the signal
  35          * XXX dispatch code which is the only place that value
  36          * XXX ever was needed.
  37          */
  38 }
  39 
  40 #ifdef CONFIG_SPARC32
  41 static inline bool syscall_has_error(struct pt_regs *regs)
  42 {
  43         return (regs->psr & PSR_C) ? true : false;
  44 }
  45 static inline void syscall_set_error(struct pt_regs *regs)
  46 {
  47         regs->psr |= PSR_C;
  48 }
  49 static inline void syscall_clear_error(struct pt_regs *regs)
  50 {
  51         regs->psr &= ~PSR_C;
  52 }
  53 #else
  54 static inline bool syscall_has_error(struct pt_regs *regs)
  55 {
  56         return (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY)) ? true : false;
  57 }
  58 static inline void syscall_set_error(struct pt_regs *regs)
  59 {
  60         regs->tstate |= (TSTATE_XCARRY | TSTATE_ICARRY);
  61 }
  62 static inline void syscall_clear_error(struct pt_regs *regs)
  63 {
  64         regs->tstate &= ~(TSTATE_XCARRY | TSTATE_ICARRY);
  65 }
  66 #endif
  67 
  68 static inline long syscall_get_error(struct task_struct *task,
  69                                      struct pt_regs *regs)
  70 {
  71         long val = regs->u_regs[UREG_I0];
  72 
  73         return (syscall_has_error(regs) ? -val : 0);
  74 }
  75 
  76 static inline long syscall_get_return_value(struct task_struct *task,
  77                                             struct pt_regs *regs)
  78 {
  79         long val = regs->u_regs[UREG_I0];
  80 
  81         return val;
  82 }
  83 
  84 static inline void syscall_set_return_value(struct task_struct *task,
  85                                             struct pt_regs *regs,
  86                                             int error, long val)
  87 {
  88         if (error) {
  89                 syscall_set_error(regs);
  90                 regs->u_regs[UREG_I0] = -error;
  91         } else {
  92                 syscall_clear_error(regs);
  93                 regs->u_regs[UREG_I0] = val;
  94         }
  95 }
  96 
  97 static inline void syscall_get_arguments(struct task_struct *task,
  98                                          struct pt_regs *regs,
  99                                          unsigned long *args)
 100 {
 101         int zero_extend = 0;
 102         unsigned int j;
 103         unsigned int n = 6;
 104 
 105 #ifdef CONFIG_SPARC64
 106         if (test_tsk_thread_flag(task, TIF_32BIT))
 107                 zero_extend = 1;
 108 #endif
 109 
 110         for (j = 0; j < n; j++) {
 111                 unsigned long val = regs->u_regs[UREG_I0 + j];
 112 
 113                 if (zero_extend)
 114                         args[j] = (u32) val;
 115                 else
 116                         args[j] = val;
 117         }
 118 }
 119 
 120 static inline void syscall_set_arguments(struct task_struct *task,
 121                                          struct pt_regs *regs,
 122                                          const unsigned long *args)
 123 {
 124         unsigned int i;
 125 
 126         for (i = 0; i < 6; i++)
 127                 regs->u_regs[UREG_I0 + i] = args[i];
 128 }
 129 
 130 static inline int syscall_get_arch(struct task_struct *task)
 131 {
 132 #if defined(CONFIG_SPARC64) && defined(CONFIG_COMPAT)
 133         return test_tsk_thread_flag(task, TIF_32BIT)
 134                 ? AUDIT_ARCH_SPARC : AUDIT_ARCH_SPARC64;
 135 #elif defined(CONFIG_SPARC64)
 136         return AUDIT_ARCH_SPARC64;
 137 #else
 138         return AUDIT_ARCH_SPARC;
 139 #endif
 140 }
 141 
 142 #endif /* __ASM_SPARC_SYSCALL_H */

/* [<][>][^][v][top][bottom][index][help] */