2008-04-17 20:05:36 +02:00
/*
* Access kernel memory without faulting .
*/
2011-10-16 02:01:52 -04:00
# include <linux/export.h>
2008-04-17 20:05:36 +02:00
# include <linux/mm.h>
2010-10-27 17:29:01 +01:00
# include <linux/uaccess.h>
2008-04-17 20:05:36 +02:00
/**
* probe_kernel_read ( ) : safely attempt to read from a location
* @ dst : pointer to the buffer that shall take the data
* @ src : address to read from
* @ size : size of the data chunk
*
* Safely read from address @ src to the buffer at @ dst . If a kernel fault
* happens , handle that and return - EFAULT .
*/
2010-01-07 11:58:36 -06:00
2011-05-19 14:35:33 -04:00
long __weak probe_kernel_read ( void * dst , const void * src , size_t size )
2010-01-07 11:58:36 -06:00
__attribute__ ( ( alias ( " __probe_kernel_read " ) ) ) ;
2011-05-19 14:35:33 -04:00
long __probe_kernel_read ( void * dst , const void * src , size_t size )
2008-04-17 20:05:36 +02:00
{
long ret ;
2008-02-20 13:33:38 -06:00
mm_segment_t old_fs = get_fs ( ) ;
2008-04-17 20:05:36 +02:00
2008-02-20 13:33:38 -06:00
set_fs ( KERNEL_DS ) ;
2008-04-17 20:05:36 +02:00
pagefault_disable ( ) ;
ret = __copy_from_user_inatomic ( dst ,
( __force const void __user * ) src , size ) ;
pagefault_enable ( ) ;
2008-02-20 13:33:38 -06:00
set_fs ( old_fs ) ;
2008-04-17 20:05:36 +02:00
return ret ? - EFAULT : 0 ;
}
EXPORT_SYMBOL_GPL ( probe_kernel_read ) ;
/**
* probe_kernel_write ( ) : safely attempt to write to a location
* @ dst : address to write to
* @ src : pointer to the data that shall be written
* @ size : size of the data chunk
*
* Safely write to address @ dst from the buffer at @ src . If a kernel fault
* happens , handle that and return - EFAULT .
*/
2011-05-19 14:35:33 -04:00
long __weak probe_kernel_write ( void * dst , const void * src , size_t size )
2010-01-07 11:58:36 -06:00
__attribute__ ( ( alias ( " __probe_kernel_write " ) ) ) ;
2011-05-19 14:35:33 -04:00
long __probe_kernel_write ( void * dst , const void * src , size_t size )
2008-04-17 20:05:36 +02:00
{
long ret ;
2008-02-20 13:33:38 -06:00
mm_segment_t old_fs = get_fs ( ) ;
2008-04-17 20:05:36 +02:00
2008-02-20 13:33:38 -06:00
set_fs ( KERNEL_DS ) ;
2008-04-17 20:05:36 +02:00
pagefault_disable ( ) ;
ret = __copy_to_user_inatomic ( ( __force void __user * ) dst , src , size ) ;
pagefault_enable ( ) ;
2008-02-20 13:33:38 -06:00
set_fs ( old_fs ) ;
2008-04-17 20:05:36 +02:00
return ret ? - EFAULT : 0 ;
}
EXPORT_SYMBOL_GPL ( probe_kernel_write ) ;