162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Non-trivial C macros cannot be used in Rust. Similarly, inlined C functions
462306a36Sopenharmony_ci * cannot be called either. This file explicitly creates functions ("helpers")
562306a36Sopenharmony_ci * that wrap those so that they can be called from Rust.
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Even though Rust kernel modules should never use directly the bindings, some
862306a36Sopenharmony_ci * of these helpers need to be exported because Rust generics and inlined
962306a36Sopenharmony_ci * functions may not get their code generated in the crate where they are
1062306a36Sopenharmony_ci * defined. Other helpers, called from non-inline functions, may not be
1162306a36Sopenharmony_ci * exported, in principle. However, in general, the Rust compiler does not
1262306a36Sopenharmony_ci * guarantee codegen will be performed for a non-inline function either.
1362306a36Sopenharmony_ci * Therefore, this file exports all the helpers. In the future, this may be
1462306a36Sopenharmony_ci * revisited to reduce the number of exports after the compiler is informed
1562306a36Sopenharmony_ci * about the places codegen is required.
1662306a36Sopenharmony_ci *
1762306a36Sopenharmony_ci * All symbols are exported as GPL-only to guarantee no GPL-only feature is
1862306a36Sopenharmony_ci * accidentally exposed.
1962306a36Sopenharmony_ci *
2062306a36Sopenharmony_ci * Sorted alphabetically.
2162306a36Sopenharmony_ci */
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci#include <kunit/test-bug.h>
2462306a36Sopenharmony_ci#include <linux/bug.h>
2562306a36Sopenharmony_ci#include <linux/build_bug.h>
2662306a36Sopenharmony_ci#include <linux/err.h>
2762306a36Sopenharmony_ci#include <linux/errname.h>
2862306a36Sopenharmony_ci#include <linux/mutex.h>
2962306a36Sopenharmony_ci#include <linux/refcount.h>
3062306a36Sopenharmony_ci#include <linux/sched/signal.h>
3162306a36Sopenharmony_ci#include <linux/spinlock.h>
3262306a36Sopenharmony_ci#include <linux/wait.h>
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci__noreturn void rust_helper_BUG(void)
3562306a36Sopenharmony_ci{
3662306a36Sopenharmony_ci	BUG();
3762306a36Sopenharmony_ci}
3862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(rust_helper_BUG);
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_civoid rust_helper_mutex_lock(struct mutex *lock)
4162306a36Sopenharmony_ci{
4262306a36Sopenharmony_ci	mutex_lock(lock);
4362306a36Sopenharmony_ci}
4462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(rust_helper_mutex_lock);
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_civoid rust_helper___spin_lock_init(spinlock_t *lock, const char *name,
4762306a36Sopenharmony_ci				  struct lock_class_key *key)
4862306a36Sopenharmony_ci{
4962306a36Sopenharmony_ci#ifdef CONFIG_DEBUG_SPINLOCK
5062306a36Sopenharmony_ci	__raw_spin_lock_init(spinlock_check(lock), name, key, LD_WAIT_CONFIG);
5162306a36Sopenharmony_ci#else
5262306a36Sopenharmony_ci	spin_lock_init(lock);
5362306a36Sopenharmony_ci#endif
5462306a36Sopenharmony_ci}
5562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(rust_helper___spin_lock_init);
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_civoid rust_helper_spin_lock(spinlock_t *lock)
5862306a36Sopenharmony_ci{
5962306a36Sopenharmony_ci	spin_lock(lock);
6062306a36Sopenharmony_ci}
6162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(rust_helper_spin_lock);
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_civoid rust_helper_spin_unlock(spinlock_t *lock)
6462306a36Sopenharmony_ci{
6562306a36Sopenharmony_ci	spin_unlock(lock);
6662306a36Sopenharmony_ci}
6762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(rust_helper_spin_unlock);
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_civoid rust_helper_init_wait(struct wait_queue_entry *wq_entry)
7062306a36Sopenharmony_ci{
7162306a36Sopenharmony_ci	init_wait(wq_entry);
7262306a36Sopenharmony_ci}
7362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(rust_helper_init_wait);
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ciint rust_helper_signal_pending(struct task_struct *t)
7662306a36Sopenharmony_ci{
7762306a36Sopenharmony_ci	return signal_pending(t);
7862306a36Sopenharmony_ci}
7962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(rust_helper_signal_pending);
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_cirefcount_t rust_helper_REFCOUNT_INIT(int n)
8262306a36Sopenharmony_ci{
8362306a36Sopenharmony_ci	return (refcount_t)REFCOUNT_INIT(n);
8462306a36Sopenharmony_ci}
8562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(rust_helper_REFCOUNT_INIT);
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_civoid rust_helper_refcount_inc(refcount_t *r)
8862306a36Sopenharmony_ci{
8962306a36Sopenharmony_ci	refcount_inc(r);
9062306a36Sopenharmony_ci}
9162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(rust_helper_refcount_inc);
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_cibool rust_helper_refcount_dec_and_test(refcount_t *r)
9462306a36Sopenharmony_ci{
9562306a36Sopenharmony_ci	return refcount_dec_and_test(r);
9662306a36Sopenharmony_ci}
9762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(rust_helper_refcount_dec_and_test);
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci__force void *rust_helper_ERR_PTR(long err)
10062306a36Sopenharmony_ci{
10162306a36Sopenharmony_ci	return ERR_PTR(err);
10262306a36Sopenharmony_ci}
10362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(rust_helper_ERR_PTR);
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_cibool rust_helper_IS_ERR(__force const void *ptr)
10662306a36Sopenharmony_ci{
10762306a36Sopenharmony_ci	return IS_ERR(ptr);
10862306a36Sopenharmony_ci}
10962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(rust_helper_IS_ERR);
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_cilong rust_helper_PTR_ERR(__force const void *ptr)
11262306a36Sopenharmony_ci{
11362306a36Sopenharmony_ci	return PTR_ERR(ptr);
11462306a36Sopenharmony_ci}
11562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(rust_helper_PTR_ERR);
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ciconst char *rust_helper_errname(int err)
11862306a36Sopenharmony_ci{
11962306a36Sopenharmony_ci	return errname(err);
12062306a36Sopenharmony_ci}
12162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(rust_helper_errname);
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_cistruct task_struct *rust_helper_get_current(void)
12462306a36Sopenharmony_ci{
12562306a36Sopenharmony_ci	return current;
12662306a36Sopenharmony_ci}
12762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(rust_helper_get_current);
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_civoid rust_helper_get_task_struct(struct task_struct *t)
13062306a36Sopenharmony_ci{
13162306a36Sopenharmony_ci	get_task_struct(t);
13262306a36Sopenharmony_ci}
13362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(rust_helper_get_task_struct);
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_civoid rust_helper_put_task_struct(struct task_struct *t)
13662306a36Sopenharmony_ci{
13762306a36Sopenharmony_ci	put_task_struct(t);
13862306a36Sopenharmony_ci}
13962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(rust_helper_put_task_struct);
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_cistruct kunit *rust_helper_kunit_get_current_test(void)
14262306a36Sopenharmony_ci{
14362306a36Sopenharmony_ci	return kunit_get_current_test();
14462306a36Sopenharmony_ci}
14562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(rust_helper_kunit_get_current_test);
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci/*
14862306a36Sopenharmony_ci * `bindgen` binds the C `size_t` type as the Rust `usize` type, so we can
14962306a36Sopenharmony_ci * use it in contexts where Rust expects a `usize` like slice (array) indices.
15062306a36Sopenharmony_ci * `usize` is defined to be the same as C's `uintptr_t` type (can hold any
15162306a36Sopenharmony_ci * pointer) but not necessarily the same as `size_t` (can hold the size of any
15262306a36Sopenharmony_ci * single object). Most modern platforms use the same concrete integer type for
15362306a36Sopenharmony_ci * both of them, but in case we find ourselves on a platform where
15462306a36Sopenharmony_ci * that's not true, fail early instead of risking ABI or
15562306a36Sopenharmony_ci * integer-overflow issues.
15662306a36Sopenharmony_ci *
15762306a36Sopenharmony_ci * If your platform fails this assertion, it means that you are in
15862306a36Sopenharmony_ci * danger of integer-overflow bugs (even if you attempt to add
15962306a36Sopenharmony_ci * `--no-size_t-is-usize`). It may be easiest to change the kernel ABI on
16062306a36Sopenharmony_ci * your platform such that `size_t` matches `uintptr_t` (i.e., to increase
16162306a36Sopenharmony_ci * `size_t`, because `uintptr_t` has to be at least as big as `size_t`).
16262306a36Sopenharmony_ci */
16362306a36Sopenharmony_cistatic_assert(
16462306a36Sopenharmony_ci	sizeof(size_t) == sizeof(uintptr_t) &&
16562306a36Sopenharmony_ci	__alignof__(size_t) == __alignof__(uintptr_t),
16662306a36Sopenharmony_ci	"Rust code expects C `size_t` to match Rust `usize`"
16762306a36Sopenharmony_ci);
168