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>
2022-12-28 06:03:40 +00:00
# include <linux/refcount.h>
2021-07-03 16:52:41 +02:00
__noreturn void rust_helper_BUG ( void )
{
BUG ( ) ;
}
EXPORT_SYMBOL_GPL ( rust_helper_BUG ) ;
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 ) ;
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` "
) ;