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