root/arch/powerpc/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_get_error
  4. syscall_get_return_value
  5. syscall_set_return_value
  6. syscall_get_arguments
  7. syscall_set_arguments
  8. syscall_get_arch

   1 /* SPDX-License-Identifier: GPL-2.0-only */
   2 /*
   3  * Access to user system call parameters and results
   4  *
   5  * Copyright (C) 2008 Red Hat, Inc.  All rights reserved.
   6  *
   7  * See asm-generic/syscall.h for descriptions of what we must do here.
   8  */
   9 
  10 #ifndef _ASM_SYSCALL_H
  11 #define _ASM_SYSCALL_H  1
  12 
  13 #include <uapi/linux/audit.h>
  14 #include <linux/sched.h>
  15 #include <linux/thread_info.h>
  16 
  17 /* ftrace syscalls requires exporting the sys_call_table */
  18 extern const unsigned long sys_call_table[];
  19 extern const unsigned long compat_sys_call_table[];
  20 
  21 static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
  22 {
  23         /*
  24          * Note that we are returning an int here. That means 0xffffffff, ie.
  25          * 32-bit negative 1, will be interpreted as -1 on a 64-bit kernel.
  26          * This is important for seccomp so that compat tasks can set r0 = -1
  27          * to reject the syscall.
  28          */
  29         return TRAP(regs) == 0xc00 ? regs->gpr[0] : -1;
  30 }
  31 
  32 static inline void syscall_rollback(struct task_struct *task,
  33                                     struct pt_regs *regs)
  34 {
  35         regs->gpr[3] = regs->orig_gpr3;
  36 }
  37 
  38 static inline long syscall_get_error(struct task_struct *task,
  39                                      struct pt_regs *regs)
  40 {
  41         /*
  42          * If the system call failed,
  43          * regs->gpr[3] contains a positive ERRORCODE.
  44          */
  45         return (regs->ccr & 0x10000000UL) ? -regs->gpr[3] : 0;
  46 }
  47 
  48 static inline long syscall_get_return_value(struct task_struct *task,
  49                                             struct pt_regs *regs)
  50 {
  51         return regs->gpr[3];
  52 }
  53 
  54 static inline void syscall_set_return_value(struct task_struct *task,
  55                                             struct pt_regs *regs,
  56                                             int error, long val)
  57 {
  58         /*
  59          * In the general case it's not obvious that we must deal with CCR
  60          * here, as the syscall exit path will also do that for us. However
  61          * there are some places, eg. the signal code, which check ccr to
  62          * decide if the value in r3 is actually an error.
  63          */
  64         if (error) {
  65                 regs->ccr |= 0x10000000L;
  66                 regs->gpr[3] = error;
  67         } else {
  68                 regs->ccr &= ~0x10000000L;
  69                 regs->gpr[3] = val;
  70         }
  71 }
  72 
  73 static inline void syscall_get_arguments(struct task_struct *task,
  74                                          struct pt_regs *regs,
  75                                          unsigned long *args)
  76 {
  77         unsigned long val, mask = -1UL;
  78         unsigned int n = 6;
  79 
  80 #ifdef CONFIG_COMPAT
  81         if (test_tsk_thread_flag(task, TIF_32BIT))
  82                 mask = 0xffffffff;
  83 #endif
  84         while (n--) {
  85                 if (n == 0)
  86                         val = regs->orig_gpr3;
  87                 else
  88                         val = regs->gpr[3 + n];
  89 
  90                 args[n] = val & mask;
  91         }
  92 }
  93 
  94 static inline void syscall_set_arguments(struct task_struct *task,
  95                                          struct pt_regs *regs,
  96                                          const unsigned long *args)
  97 {
  98         memcpy(&regs->gpr[3], args, 6 * sizeof(args[0]));
  99 
 100         /* Also copy the first argument into orig_gpr3 */
 101         regs->orig_gpr3 = args[0];
 102 }
 103 
 104 static inline int syscall_get_arch(struct task_struct *task)
 105 {
 106         int arch;
 107 
 108         if (IS_ENABLED(CONFIG_PPC64) && !test_tsk_thread_flag(task, TIF_32BIT))
 109                 arch = AUDIT_ARCH_PPC64;
 110         else
 111                 arch = AUDIT_ARCH_PPC;
 112 
 113 #ifdef __LITTLE_ENDIAN__
 114         arch |= __AUDIT_ARCH_LE;
 115 #endif
 116         return arch;
 117 }
 118 #endif  /* _ASM_SYSCALL_H */

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