2021-07-03 16:52:41 +02:00
// SPDX-License-Identifier: GPL-2.0
/*
* Non - trivial C macros cannot be used in Rust . Similarly , inlined C functions
* cannot be called either . This file explicitly creates functions ( " helpers " )
* that wrap those so that they can be called from Rust .
*
* Even though Rust kernel modules should never use directly the bindings , some
* of these helpers need to be exported because Rust generics and inlined
* functions may not get their code generated in the crate where they are
* defined . Other helpers , called from non - inline functions , may not be
* exported , in principle . However , in general , the Rust compiler does not
* guarantee codegen will be performed for a non - inline function either .
* Therefore , this file exports all the helpers . In the future , this may be
* revisited to reduce the number of exports after the compiler is informed
* about the places codegen is required .
*
* All symbols are exported as GPL - only to guarantee no GPL - only feature is
* accidentally exposed .
*/
# include <linux/bug.h>
# include <linux/build_bug.h>
2023-04-03 18:48:11 +09:00
# include <linux/err.h>
2023-05-31 17:44:50 +00:00
# include <linux/errname.h>
2022-12-28 06:03:40 +00:00
# include <linux/refcount.h>
2023-04-11 02:45:33 -03:00
# include <linux/mutex.h>
2023-04-19 14:44:26 -03:00
# include <linux/spinlock.h>
2023-04-11 02:45:39 -03:00
# include <linux/sched/signal.h>
2023-03-26 00:57:38 -03:00
# include <linux/wait.h>
2021-07-03 16:52:41 +02:00
__noreturn void rust_helper_BUG ( void )
{
BUG ( ) ;
}
EXPORT_SYMBOL_GPL ( rust_helper_BUG ) ;
2023-04-11 02:45:33 -03:00
void rust_helper_mutex_lock ( struct mutex * lock )
{
mutex_lock ( lock ) ;
}
EXPORT_SYMBOL_GPL ( rust_helper_mutex_lock ) ;
2023-04-19 14:44:26 -03:00
void rust_helper___spin_lock_init ( spinlock_t * lock , const char * name ,
struct lock_class_key * key )
{
# ifdef CONFIG_DEBUG_SPINLOCK
__raw_spin_lock_init ( spinlock_check ( lock ) , name , key , LD_WAIT_CONFIG ) ;
# else
spin_lock_init ( lock ) ;
# endif
}
EXPORT_SYMBOL_GPL ( rust_helper___spin_lock_init ) ;
void rust_helper_spin_lock ( spinlock_t * lock )
{
spin_lock ( lock ) ;
}
EXPORT_SYMBOL_GPL ( rust_helper_spin_lock ) ;
void rust_helper_spin_unlock ( spinlock_t * lock )
{
spin_unlock ( lock ) ;
}
EXPORT_SYMBOL_GPL ( rust_helper_spin_unlock ) ;
2023-03-26 00:57:38 -03:00
void rust_helper_init_wait ( struct wait_queue_entry * wq_entry )
{
init_wait ( wq_entry ) ;
}
EXPORT_SYMBOL_GPL ( rust_helper_init_wait ) ;
2023-04-11 02:45:39 -03:00
int rust_helper_signal_pending ( struct task_struct * t )
{
return signal_pending ( t ) ;
}
EXPORT_SYMBOL_GPL ( rust_helper_signal_pending ) ;
2022-12-28 06:03:40 +00:00
refcount_t rust_helper_REFCOUNT_INIT ( int n )
{
return ( refcount_t ) REFCOUNT_INIT ( n ) ;
}
EXPORT_SYMBOL_GPL ( rust_helper_REFCOUNT_INIT ) ;
void rust_helper_refcount_inc ( refcount_t * r )
{
refcount_inc ( r ) ;
}
EXPORT_SYMBOL_GPL ( rust_helper_refcount_inc ) ;
bool rust_helper_refcount_dec_and_test ( refcount_t * r )
{
return refcount_dec_and_test ( r ) ;
}
EXPORT_SYMBOL_GPL ( rust_helper_refcount_dec_and_test ) ;
2023-04-03 18:48:11 +09:00
__force void * rust_helper_ERR_PTR ( long err )
{
return ERR_PTR ( err ) ;
}
EXPORT_SYMBOL_GPL ( rust_helper_ERR_PTR ) ;
2023-04-03 18:48:14 +09:00
bool rust_helper_IS_ERR ( __force const void * ptr )
{
return IS_ERR ( ptr ) ;
}
EXPORT_SYMBOL_GPL ( rust_helper_IS_ERR ) ;
long rust_helper_PTR_ERR ( __force const void * ptr )
{
return PTR_ERR ( ptr ) ;
}
EXPORT_SYMBOL_GPL ( rust_helper_PTR_ERR ) ;
2023-05-31 17:44:50 +00:00
const char * rust_helper_errname ( int err )
{
return errname ( err ) ;
}
EXPORT_SYMBOL_GPL ( rust_helper_errname ) ;
2023-04-11 02:45:40 -03:00
struct task_struct * rust_helper_get_current ( void )
{
return current ;
}
EXPORT_SYMBOL_GPL ( rust_helper_get_current ) ;
2023-04-11 02:45:39 -03:00
void rust_helper_get_task_struct ( struct task_struct * t )
{
get_task_struct ( t ) ;
}
EXPORT_SYMBOL_GPL ( rust_helper_get_task_struct ) ;
void rust_helper_put_task_struct ( struct task_struct * t )
{
put_task_struct ( t ) ;
}
EXPORT_SYMBOL_GPL ( rust_helper_put_task_struct ) ;
2021-07-03 16:52:41 +02:00
/*
* We use ` bindgen ` ' s ` - - size_t - is - usize ` option to bind the C ` size_t ` type
* as the Rust ` usize ` type , so we can use it in contexts where Rust
* expects a ` usize ` like slice ( array ) indices . ` usize ` is defined to be
* the same as C ' s ` uintptr_t ` type ( can hold any pointer ) but not
* necessarily the same as ` size_t ` ( can hold the size of any single
* object ) . Most modern platforms use the same concrete integer type for
* both of them , but in case we find ourselves on a platform where
* that ' s not true , fail early instead of risking ABI or
* integer - overflow issues .
*
* If your platform fails this assertion , it means that you are in
* danger of integer - overflow bugs ( even if you attempt to remove
* ` - - size_t - is - usize ` ) . It may be easiest to change the kernel ABI on
* your platform such that ` size_t ` matches ` uintptr_t ` ( i . e . , to increase
* ` size_t ` , because ` uintptr_t ` has to be at least as big as ` size_t ` ) .
*/
static_assert (
sizeof ( size_t ) = = sizeof ( uintptr_t ) & &
__alignof__ ( size_t ) = = __alignof__ ( uintptr_t ) ,
" Rust code expects C `size_t` to match Rust `usize` "
) ;