2008-10-10 21:33:20 +02:00
/*
* Access to user system call parameters and results
*
* Copyright IBM Corp . 2008
* Author ( s ) : Martin Schwidefsky ( schwidefsky @ de . ibm . com )
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License ( version 2 only )
* as published by the Free Software Foundation .
*/
# ifndef _ASM_SYSCALL_H
# define _ASM_SYSCALL_H 1
2012-07-31 15:37:13 +02:00
# include <linux/audit.h>
2009-06-12 10:26:47 +02:00
# include <linux/sched.h>
2011-10-30 15:16:47 +01:00
# include <linux/err.h>
2008-10-10 21:33:20 +02:00
# include <asm/ptrace.h>
2010-01-26 04:40:03 -05:00
/*
* The syscall table always contains 32 bit pointers since we know that the
* address of the function to be called is ( way ) below 4 GB . So the " int "
* type here is what we want [ need ] for both 32 bit and 64 bit systems .
*/
extern const unsigned int sys_call_table [ ] ;
2013-04-24 12:58:39 +02:00
extern const unsigned int sys_call_table_emu [ ] ;
2010-01-26 04:40:03 -05:00
2008-10-10 21:33:20 +02:00
static inline long syscall_get_nr ( struct task_struct * task ,
struct pt_regs * regs )
{
2011-10-30 15:16:49 +01:00
return test_tsk_thread_flag ( task , TIF_SYSCALL ) ?
2011-12-27 11:27:18 +01:00
( regs - > int_code & 0xffff ) : - 1 ;
2008-10-10 21:33:20 +02:00
}
static inline void syscall_rollback ( struct task_struct * task ,
struct pt_regs * regs )
{
regs - > gprs [ 2 ] = regs - > orig_gpr2 ;
}
static inline long syscall_get_error ( struct task_struct * task ,
struct pt_regs * regs )
{
2011-10-30 15:16:47 +01:00
return IS_ERR_VALUE ( regs - > gprs [ 2 ] ) ? regs - > gprs [ 2 ] : 0 ;
2008-10-10 21:33:20 +02:00
}
static inline long syscall_get_return_value ( struct task_struct * task ,
struct pt_regs * regs )
{
return regs - > gprs [ 2 ] ;
}
static inline void syscall_set_return_value ( struct task_struct * task ,
struct pt_regs * regs ,
int error , long val )
{
regs - > gprs [ 2 ] = error ? - error : val ;
}
static inline void syscall_get_arguments ( struct task_struct * task ,
struct pt_regs * regs ,
unsigned int i , unsigned int n ,
unsigned long * args )
{
2008-11-27 11:05:55 +01:00
unsigned long mask = - 1UL ;
2008-10-10 21:33:20 +02:00
BUG_ON ( i + n > 6 ) ;
# ifdef CONFIG_COMPAT
2008-11-27 11:05:55 +01:00
if ( test_tsk_thread_flag ( task , TIF_31BIT ) )
mask = 0xffffffff ;
2008-10-10 21:33:20 +02:00
# endif
2008-11-27 11:05:55 +01:00
while ( n - - > 0 )
if ( i + n > 0 )
args [ n ] = regs - > gprs [ 2 + i + n ] & mask ;
if ( i = = 0 )
args [ 0 ] = regs - > orig_gpr2 & mask ;
2008-10-10 21:33:20 +02:00
}
static inline void syscall_set_arguments ( struct task_struct * task ,
struct pt_regs * regs ,
unsigned int i , unsigned int n ,
const unsigned long * args )
{
BUG_ON ( i + n > 6 ) ;
2008-11-27 11:05:55 +01:00
while ( n - - > 0 )
if ( i + n > 0 )
regs - > gprs [ 2 + i + n ] = args [ n ] ;
if ( i = = 0 )
regs - > orig_gpr2 = args [ 0 ] ;
2008-10-10 21:33:20 +02:00
}
2012-07-31 15:37:13 +02:00
static inline int syscall_get_arch ( struct task_struct * task ,
struct pt_regs * regs )
{
# ifdef CONFIG_COMPAT
if ( test_tsk_thread_flag ( task , TIF_31BIT ) )
return AUDIT_ARCH_S390 ;
# endif
return sizeof ( long ) = = 8 ? AUDIT_ARCH_S390X : AUDIT_ARCH_S390 ;
}
2008-10-10 21:33:20 +02:00
# endif /* _ASM_SYSCALL_H */