2005-04-16 15:20:36 -07:00
/*
* include / asm - s390 / uaccess . h
*
* S390 version
* Copyright ( C ) 1999 , 2000 IBM Deutschland Entwicklung GmbH , IBM Corporation
* Author ( s ) : Hartmut Penner ( hp @ de . ibm . com ) ,
* Martin Schwidefsky ( schwidefsky @ de . ibm . com )
*
* Derived from " include/asm-i386/uaccess.h "
*/
# ifndef __S390_UACCESS_H
# define __S390_UACCESS_H
/*
* User space memory access functions
*/
# include <linux/sched.h>
# include <linux/errno.h>
2012-03-28 18:30:02 +01:00
# include <asm/ctl_reg.h>
2005-04-16 15:20:36 -07:00
# define VERIFY_READ 0
# define VERIFY_WRITE 1
/*
* The fs value determines whether argument validity checking should be
* performed or not . If get_fs ( ) = = USER_DS , checking is performed , with
* get_fs ( ) = = KERNEL_DS , checking is bypassed .
*
* For historical reasons , these macros are grossly misnamed .
*/
# define MAKE_MM_SEG(a) ((mm_segment_t) { (a) })
# define KERNEL_DS MAKE_MM_SEG(0)
# define USER_DS MAKE_MM_SEG(1)
# define get_ds() (KERNEL_DS)
# define get_fs() (current->thread.mm_segment)
# define set_fs(x) \
( { \
unsigned long __pto ; \
current - > thread . mm_segment = ( x ) ; \
__pto = current - > thread . mm_segment . ar4 ? \
S390_lowcore . user_asce : S390_lowcore . kernel_asce ; \
2006-09-28 16:56:43 +02:00
__ctl_load ( __pto , 7 , 7 ) ; \
2005-04-16 15:20:36 -07:00
} )
# define segment_eq(a,b) ((a).ar4 == (b).ar4)
2011-05-26 09:48:25 +02:00
# define __access_ok(addr, size) \
( { \
__chk_user_ptr ( addr ) ; \
1 ; \
} )
2005-04-16 15:20:36 -07:00
2011-05-26 09:48:25 +02:00
# define access_ok(type, addr, size) __access_ok(addr, size)
2005-04-16 15:20:36 -07:00
/*
* The exception table consists of pairs of addresses : the first is the
* address of an instruction that is allowed to fault , and the second is
* the address at which the program should continue . No registers are
* modified , so it is entirely up to the continuation code to figure out
* what to do .
*
* All the routines below use bits of fixup code that are out of line
* with the main instruction path . This means when everything is well ,
* we don ' t even have to jump over them . Further , they do not intrude
* on our cache or tlb entries .
*/
struct exception_table_entry
{
unsigned long insn , fixup ;
} ;
2006-09-20 15:59:42 +02:00
struct uaccess_ops {
size_t ( * copy_from_user ) ( size_t , const void __user * , void * ) ;
size_t ( * copy_from_user_small ) ( size_t , const void __user * , void * ) ;
size_t ( * copy_to_user ) ( size_t , void __user * , const void * ) ;
size_t ( * copy_to_user_small ) ( size_t , void __user * , const void * ) ;
size_t ( * copy_in_user ) ( size_t , void __user * , const void __user * ) ;
size_t ( * clear_user ) ( size_t , void __user * ) ;
size_t ( * strnlen_user ) ( size_t , const char __user * ) ;
size_t ( * strncpy_from_user ) ( size_t , const char __user * , char * ) ;
2011-03-10 18:50:58 -08:00
int ( * futex_atomic_op ) ( int op , u32 __user * , int oparg , int * old ) ;
int ( * futex_atomic_cmpxchg ) ( u32 * , u32 __user * , u32 old , u32 new ) ;
2006-09-20 15:59:42 +02:00
} ;
extern struct uaccess_ops uaccess ;
extern struct uaccess_ops uaccess_std ;
2006-09-20 15:59:44 +02:00
extern struct uaccess_ops uaccess_mvcos ;
2007-02-05 21:18:17 +01:00
extern struct uaccess_ops uaccess_mvcos_switch ;
extern struct uaccess_ops uaccess_pt ;
2006-09-20 15:59:42 +02:00
2009-12-07 12:51:47 +01:00
extern int __handle_fault ( unsigned long , unsigned long , int ) ;
2006-09-20 15:59:42 +02:00
static inline int __put_user_fn ( size_t size , void __user * ptr , void * x )
{
size = uaccess . copy_to_user_small ( size , ptr , x ) ;
return size ? - EFAULT : size ;
}
static inline int __get_user_fn ( size_t size , const void __user * ptr , void * x )
{
size = uaccess . copy_from_user_small ( size , ptr , x ) ;
return size ? - EFAULT : size ;
}
2005-04-16 15:20:36 -07:00
/*
* These are the main single - value transfer routines . They automatically
* use the right size if we just have the right pointer type .
*/
# define __put_user(x, ptr) \
( { \
__typeof__ ( * ( ptr ) ) __x = ( x ) ; \
2006-09-20 15:59:42 +02:00
int __pu_err = - EFAULT ; \
2005-08-23 22:48:22 +01:00
__chk_user_ptr ( ptr ) ; \
2005-04-16 15:20:36 -07:00
switch ( sizeof ( * ( ptr ) ) ) { \
case 1 : \
case 2 : \
case 4 : \
case 8 : \
2006-09-20 15:59:42 +02:00
__pu_err = __put_user_fn ( sizeof ( * ( ptr ) ) , \
ptr , & __x ) ; \
2005-04-16 15:20:36 -07:00
break ; \
default : \
__put_user_bad ( ) ; \
break ; \
} \
__pu_err ; \
} )
# define put_user(x, ptr) \
( { \
2009-06-12 10:26:32 +02:00
might_fault ( ) ; \
2005-04-16 15:20:36 -07:00
__put_user ( x , ptr ) ; \
} )
extern int __put_user_bad ( void ) __attribute__ ( ( noreturn ) ) ;
# define __get_user(x, ptr) \
( { \
2006-09-20 15:59:42 +02:00
int __gu_err = - EFAULT ; \
__chk_user_ptr ( ptr ) ; \
2005-04-16 15:20:36 -07:00
switch ( sizeof ( * ( ptr ) ) ) { \
2005-11-07 00:59:11 -08:00
case 1 : { \
unsigned char __x ; \
2006-09-20 15:59:42 +02:00
__gu_err = __get_user_fn ( sizeof ( * ( ptr ) ) , \
ptr , & __x ) ; \
2006-02-03 20:11:52 -05:00
( x ) = * ( __force __typeof__ ( * ( ptr ) ) * ) & __x ; \
2005-11-07 00:59:11 -08:00
break ; \
} ; \
case 2 : { \
unsigned short __x ; \
2006-09-20 15:59:42 +02:00
__gu_err = __get_user_fn ( sizeof ( * ( ptr ) ) , \
ptr , & __x ) ; \
2006-02-03 20:11:52 -05:00
( x ) = * ( __force __typeof__ ( * ( ptr ) ) * ) & __x ; \
2005-11-07 00:59:11 -08:00
break ; \
} ; \
case 4 : { \
unsigned int __x ; \
2006-09-20 15:59:42 +02:00
__gu_err = __get_user_fn ( sizeof ( * ( ptr ) ) , \
ptr , & __x ) ; \
2006-02-03 20:11:52 -05:00
( x ) = * ( __force __typeof__ ( * ( ptr ) ) * ) & __x ; \
2005-11-07 00:59:11 -08:00
break ; \
} ; \
case 8 : { \
unsigned long long __x ; \
2006-09-20 15:59:42 +02:00
__gu_err = __get_user_fn ( sizeof ( * ( ptr ) ) , \
ptr , & __x ) ; \
2006-02-03 20:11:52 -05:00
( x ) = * ( __force __typeof__ ( * ( ptr ) ) * ) & __x ; \
2005-04-16 15:20:36 -07:00
break ; \
2005-11-07 00:59:11 -08:00
} ; \
2005-04-16 15:20:36 -07:00
default : \
__get_user_bad ( ) ; \
break ; \
} \
__gu_err ; \
} )
# define get_user(x, ptr) \
( { \
2009-06-12 10:26:32 +02:00
might_fault ( ) ; \
2005-04-16 15:20:36 -07:00
__get_user ( x , ptr ) ; \
} )
extern int __get_user_bad ( void ) __attribute__ ( ( noreturn ) ) ;
# define __put_user_unaligned __put_user
# define __get_user_unaligned __get_user
/**
* __copy_to_user : - Copy a block of data into user space , with less checking .
* @ to : Destination address , in user space .
* @ from : Source address , in kernel space .
* @ n : Number of bytes to copy .
*
* Context : User context only . This function may sleep .
*
* Copy data from kernel space to user space . Caller must check
* the specified block with access_ok ( ) before calling this function .
*
* Returns number of bytes that could not be copied .
* On success , this will be zero .
*/
2006-12-04 15:39:55 +01:00
static inline unsigned long __must_check
2005-04-16 15:20:36 -07:00
__copy_to_user ( void __user * to , const void * from , unsigned long n )
{
2006-09-20 15:59:42 +02:00
if ( __builtin_constant_p ( n ) & & ( n < = 256 ) )
return uaccess . copy_to_user_small ( n , to , from ) ;
else
return uaccess . copy_to_user ( n , to , from ) ;
2005-04-16 15:20:36 -07:00
}
# define __copy_to_user_inatomic __copy_to_user
# define __copy_from_user_inatomic __copy_from_user
/**
* copy_to_user : - Copy a block of data into user space .
* @ to : Destination address , in user space .
* @ from : Source address , in kernel space .
* @ n : Number of bytes to copy .
*
* Context : User context only . This function may sleep .
*
* Copy data from kernel space to user space .
*
* Returns number of bytes that could not be copied .
* On success , this will be zero .
*/
2006-12-04 15:39:55 +01:00
static inline unsigned long __must_check
2005-04-16 15:20:36 -07:00
copy_to_user ( void __user * to , const void * from , unsigned long n )
{
2009-06-12 10:26:32 +02:00
might_fault ( ) ;
2005-04-16 15:20:36 -07:00
if ( access_ok ( VERIFY_WRITE , to , n ) )
n = __copy_to_user ( to , from , n ) ;
return n ;
}
/**
* __copy_from_user : - Copy a block of data from user space , with less checking .
* @ to : Destination address , in kernel space .
* @ from : Source address , in user space .
* @ n : Number of bytes to copy .
*
* Context : User context only . This function may sleep .
*
* Copy data from user space to kernel space . Caller must check
* the specified block with access_ok ( ) before calling this function .
*
* Returns number of bytes that could not be copied .
* On success , this will be zero .
*
* If some data could not be copied , this function will pad the copied
* data to the requested size using zero bytes .
*/
2006-12-04 15:39:55 +01:00
static inline unsigned long __must_check
2005-04-16 15:20:36 -07:00
__copy_from_user ( void * to , const void __user * from , unsigned long n )
{
2006-09-20 15:59:42 +02:00
if ( __builtin_constant_p ( n ) & & ( n < = 256 ) )
return uaccess . copy_from_user_small ( n , from , to ) ;
else
return uaccess . copy_from_user ( n , from , to ) ;
2005-04-16 15:20:36 -07:00
}
2010-02-26 22:37:22 +01:00
extern void copy_from_user_overflow ( void )
# ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS
__compiletime_warning ( " copy_from_user() buffer size is not provably correct " )
# endif
;
2005-04-16 15:20:36 -07:00
/**
* copy_from_user : - Copy a block of data from user space .
* @ to : Destination address , in kernel space .
* @ from : Source address , in user space .
* @ n : Number of bytes to copy .
*
* Context : User context only . This function may sleep .
*
* Copy data from user space to kernel space .
*
* Returns number of bytes that could not be copied .
* On success , this will be zero .
*
* If some data could not be copied , this function will pad the copied
* data to the requested size using zero bytes .
*/
2006-12-04 15:39:55 +01:00
static inline unsigned long __must_check
2005-04-16 15:20:36 -07:00
copy_from_user ( void * to , const void __user * from , unsigned long n )
{
2010-02-26 22:37:22 +01:00
unsigned int sz = __compiletime_object_size ( to ) ;
2009-06-12 10:26:32 +02:00
might_fault ( ) ;
2010-02-26 22:37:22 +01:00
if ( unlikely ( sz ! = - 1 & & sz < n ) ) {
copy_from_user_overflow ( ) ;
return n ;
}
2005-04-16 15:20:36 -07:00
if ( access_ok ( VERIFY_READ , from , n ) )
n = __copy_from_user ( to , from , n ) ;
else
memset ( to , 0 , n ) ;
return n ;
}
2006-12-04 15:39:55 +01:00
static inline unsigned long __must_check
2005-04-16 15:20:36 -07:00
__copy_in_user ( void __user * to , const void __user * from , unsigned long n )
{
2006-09-20 15:59:42 +02:00
return uaccess . copy_in_user ( n , to , from ) ;
2005-04-16 15:20:36 -07:00
}
2006-12-04 15:39:55 +01:00
static inline unsigned long __must_check
2005-04-16 15:20:36 -07:00
copy_in_user ( void __user * to , const void __user * from , unsigned long n )
{
2009-06-12 10:26:32 +02:00
might_fault ( ) ;
2005-04-16 15:20:36 -07:00
if ( __access_ok ( from , n ) & & __access_ok ( to , n ) )
2006-09-20 15:59:42 +02:00
n = __copy_in_user ( to , from , n ) ;
2005-04-16 15:20:36 -07:00
return n ;
}
/*
* Copy a null terminated string from userspace .
*/
2006-12-04 15:39:55 +01:00
static inline long __must_check
2005-04-16 15:20:36 -07:00
strncpy_from_user ( char * dst , const char __user * src , long count )
{
long res = - EFAULT ;
2009-06-12 10:26:32 +02:00
might_fault ( ) ;
2005-04-16 15:20:36 -07:00
if ( access_ok ( VERIFY_READ , src , 1 ) )
2006-09-20 15:59:42 +02:00
res = uaccess . strncpy_from_user ( count , src , dst ) ;
2005-04-16 15:20:36 -07:00
return res ;
}
static inline unsigned long
strnlen_user ( const char __user * src , unsigned long n )
{
2009-06-12 10:26:32 +02:00
might_fault ( ) ;
2006-09-20 15:59:42 +02:00
return uaccess . strnlen_user ( n , src ) ;
2005-04-16 15:20:36 -07:00
}
/**
* strlen_user : - Get the size of a string in user space .
* @ str : The string to measure .
*
* Context : User context only . This function may sleep .
*
* Get the size of a NUL - terminated string in user space .
*
* Returns the size of the string INCLUDING the terminating NUL .
* On exception , returns 0.
*
* If there is a limit on the length of a valid string , you may wish to
* consider using strnlen_user ( ) instead .
*/
# define strlen_user(str) strnlen_user(str, ~0UL)
/*
* Zero Userspace
*/
2006-12-04 15:39:55 +01:00
static inline unsigned long __must_check
2005-04-16 15:20:36 -07:00
__clear_user ( void __user * to , unsigned long n )
{
2006-09-20 15:59:42 +02:00
return uaccess . clear_user ( n , to ) ;
2005-04-16 15:20:36 -07:00
}
2006-12-04 15:39:55 +01:00
static inline unsigned long __must_check
2005-04-16 15:20:36 -07:00
clear_user ( void __user * to , unsigned long n )
{
2009-06-12 10:26:32 +02:00
might_fault ( ) ;
2005-04-16 15:20:36 -07:00
if ( access_ok ( VERIFY_WRITE , to , n ) )
2006-09-20 15:59:42 +02:00
n = uaccess . clear_user ( n , to ) ;
2005-04-16 15:20:36 -07:00
return n ;
}
2012-03-28 18:30:02 +01:00
extern int memcpy_real ( void * , void * , size_t ) ;
2012-05-24 14:35:16 +02:00
extern void memcpy_absolute ( void * , void * , size_t ) ;
2012-03-28 18:30:02 +01:00
extern int copy_to_user_real ( void __user * dest , void * src , size_t count ) ;
extern int copy_from_user_real ( void * dest , void __user * src , size_t count ) ;
2005-04-16 15:20:36 -07:00
# endif /* __S390_UACCESS_H */