2017-11-24 15:00:38 +01:00
/* SPDX-License-Identifier: GPL-2.0 */
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 )
*/
# ifndef _ASM_SYSCALL_H
# define _ASM_SYSCALL_H 1
2014-03-11 12:55:42 -04:00
# include <uapi/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 )
{
2014-04-15 12:55:07 +02:00
return test_pt_regs_flag ( regs , PIF_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 )
{
2014-07-22 16:50:57 +02:00
regs - > gprs [ 2 ] = error ? error : val ;
2008-10-10 21:33:20 +02:00
}
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 ;
2017-06-29 11:38:11 +02:00
/*
* No arguments for this syscall , there ' s nothing to do .
*/
if ( ! n )
return ;
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
}
2014-03-11 12:48:43 -04:00
static inline int syscall_get_arch ( void )
2012-07-31 15:37:13 +02:00
{
# ifdef CONFIG_COMPAT
2014-03-11 12:48:43 -04:00
if ( test_tsk_thread_flag ( current , TIF_31BIT ) )
2012-07-31 15:37:13 +02:00
return AUDIT_ARCH_S390 ;
# endif
2015-03-30 11:11:49 +02:00
return AUDIT_ARCH_S390X ;
2012-07-31 15:37:13 +02:00
}
2008-10-10 21:33:20 +02:00
# endif /* _ASM_SYSCALL_H */