2012-07-13 23:38:17 +02:00
/*
2012-08-17 08:22:04 +02:00
* Access to user system call parameters and results
*
2012-07-13 23:38:17 +02:00
* This file is subject to the terms and conditions of the GNU General Public
* License . See the file " COPYING " in the main directory of this archive
* for more details .
*
2012-08-17 08:22:04 +02:00
* See asm - generic / syscall . h for descriptions of what we must do here .
*
2012-07-13 23:38:17 +02:00
* Copyright ( C ) 2012 Ralf Baechle < ralf @ linux - mips . org >
*/
# ifndef __ASM_MIPS_SYSCALL_H
# define __ASM_MIPS_SYSCALL_H
2014-02-10 18:00:17 +01:00
# include <linux/compiler.h>
2014-03-11 12:55:42 -04:00
# include <uapi/linux/audit.h>
2012-09-26 20:16:47 +02:00
# include <linux/elf-em.h>
2012-08-17 08:22:04 +02:00
# include <linux/kernel.h>
# include <linux/sched.h>
# include <linux/uaccess.h>
# include <asm/ptrace.h>
2014-01-22 14:40:03 +00:00
# include <asm/unistd.h>
# ifndef __NR_syscall /* Only defined if _MIPS_SIM == _MIPS_SIM_ABI32 */
# define __NR_syscall 4000
# endif
2012-08-17 08:22:04 +02:00
static inline long syscall_get_nr ( struct task_struct * task ,
struct pt_regs * regs )
{
2015-02-03 17:08:17 +01:00
return current_thread_info ( ) - > syscall ;
2012-08-17 08:22:04 +02:00
}
static inline unsigned long mips_get_syscall_arg ( unsigned long * arg ,
struct task_struct * task , struct pt_regs * regs , unsigned int n )
{
2013-11-25 15:21:00 -08:00
unsigned long usp __maybe_unused = regs - > regs [ 29 ] ;
2012-08-17 08:22:04 +02:00
switch ( n ) {
case 0 : case 1 : case 2 : case 3 :
* arg = regs - > regs [ 4 + n ] ;
return 0 ;
# ifdef CONFIG_32BIT
case 4 : case 5 : case 6 : case 7 :
2014-03-17 12:14:13 +01:00
return get_user ( * arg , ( int * ) usp + n ) ;
2012-08-17 08:22:04 +02:00
# endif
# ifdef CONFIG_64BIT
case 4 : case 5 : case 6 : case 7 :
# ifdef CONFIG_MIPS32_O32
if ( test_thread_flag ( TIF_32BIT_REGS ) )
2014-03-17 12:14:13 +01:00
return get_user ( * arg , ( int * ) usp + n ) ;
2012-08-17 08:22:04 +02:00
else
# endif
* arg = regs - > regs [ 4 + n ] ;
return 0 ;
# endif
default :
BUG ( ) ;
}
2014-02-10 18:00:17 +01:00
unreachable ( ) ;
2012-08-17 08:22:04 +02:00
}
2013-09-06 20:24:48 +02:00
static inline long syscall_get_return_value ( struct task_struct * task ,
struct pt_regs * regs )
{
return regs - > regs [ 2 ] ;
}
2014-01-22 14:39:58 +00:00
static inline void syscall_rollback ( struct task_struct * task ,
struct pt_regs * regs )
{
/* Do nothing */
}
2013-09-06 20:24:48 +02:00
static inline void syscall_set_return_value ( struct task_struct * task ,
struct pt_regs * regs ,
int error , long val )
{
if ( error ) {
regs - > regs [ 2 ] = - error ;
regs - > regs [ 7 ] = - 1 ;
} else {
regs - > regs [ 2 ] = val ;
regs - > regs [ 7 ] = 0 ;
}
}
2012-08-17 08:22:04 +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 )
{
int ret ;
2014-01-22 14:40:03 +00:00
/* O32 ABI syscall() - Either 64-bit with O32 or 32-bit */
if ( ( config_enabled ( CONFIG_32BIT ) | |
test_tsk_thread_flag ( task , TIF_32BIT_REGS ) ) & &
( regs - > regs [ 2 ] = = __NR_syscall ) ) {
i + + ;
n + + ;
}
2012-08-17 08:22:04 +02:00
while ( n - - )
2014-01-22 14:39:57 +00:00
ret | = mips_get_syscall_arg ( args + + , task , regs , i + + ) ;
2012-08-17 08:22:04 +02:00
/*
* No way to communicate an error because this is a void function .
*/
#if 0
return ret ;
# endif
}
2012-07-13 23:38:17 +02:00
extern const unsigned long sys_call_table [ ] ;
extern const unsigned long sys32_call_table [ ] ;
extern const unsigned long sysn32_call_table [ ] ;
2014-03-11 12:48:43 -04:00
static inline int syscall_get_arch ( void )
2012-09-26 20:16:47 +02:00
{
2014-03-11 13:50:46 -04:00
int arch = AUDIT_ARCH_MIPS ;
2012-09-26 20:16:47 +02:00
# ifdef CONFIG_64BIT
2014-07-24 12:10:01 +01:00
if ( ! test_thread_flag ( TIF_32BIT_REGS ) ) {
2014-01-22 14:39:59 +00:00
arch | = __AUDIT_ARCH_64BIT ;
2014-07-24 12:10:01 +01:00
/* N32 sets only TIF_32BIT_ADDR */
if ( test_thread_flag ( TIF_32BIT_ADDR ) )
arch | = __AUDIT_ARCH_CONVENTION_MIPS64_N32 ;
}
2012-09-26 20:16:47 +02:00
# endif
# if defined(__LITTLE_ENDIAN)
arch | = __AUDIT_ARCH_LE ;
# endif
return arch ;
}
2012-07-13 23:38:17 +02:00
# endif /* __ASM_MIPS_SYSCALL_H */