Skip to content

Commit b00d4c3

Browse files
authored
Merge pull request #359 from nbdd0121/helper
rust: generate bindings for helpers
2 parents c4d17fc + 4aa4dd5 commit b00d4c3

21 files changed

+131
-241
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1834,6 +1834,7 @@ rustfmt:
18341834
-o -path $(abs_objtree)/rust/test -prune \
18351835
| grep -Fv $(abs_srctree)/rust/alloc \
18361836
| grep -Fv $(abs_objtree)/rust/test \
1837+
| grep -Fv generated \
18371838
| xargs $(RUSTFMT) $(rustfmt_flags)
18381839

18391840
rustfmtcheck: rustfmt_flags = --check

rust/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# SPDX-License-Identifier: GPL-2.0
22

33
bindings_generated.rs
4+
bindings_helpers_generated.rs
45
exports_*_generated.h
56
doc/
67
test/

rust/Makefile

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ extra-$(CONFIG_RUST) += exports_core_generated.h
55

66
extra-$(CONFIG_RUST) += libmacros.so
77

8-
extra-$(CONFIG_RUST) += bindings_generated.rs
8+
extra-$(CONFIG_RUST) += bindings_generated.rs bindings_helpers_generated.rs
99
obj-$(CONFIG_RUST) += alloc.o kernel.o
1010
extra-$(CONFIG_RUST) += exports_alloc_generated.h exports_kernel_generated.h
1111

@@ -30,7 +30,7 @@ endif
3030

3131
quiet_cmd_rustdoc = RUSTDOC $(if $(rustdoc_host),H, ) $<
3232
cmd_rustdoc = \
33-
RUST_BINDINGS_FILE=$(abspath $(objtree)/rust/bindings_generated.rs) \
33+
OBJTREE=$(abspath $(objtree)) \
3434
$(RUSTDOC) $(if $(rustdoc_host),,$(rust_cross_flags)) \
3535
$(filter-out -Cpanic=abort, $(filter-out --emit=%, $(rust_flags))) \
3636
$(rustc_target_flags) -L $(objtree)/rust \
@@ -73,12 +73,13 @@ rustdoc-kernel: private rustc_target_flags = --extern alloc \
7373
--extern macros=$(objtree)/rust/libmacros.so
7474
rustdoc-kernel: $(srctree)/rust/kernel/lib.rs rustdoc-core \
7575
rustdoc-macros rustdoc-compiler_builtins rustdoc-alloc \
76-
$(objtree)/rust/libmacros.so $(objtree)/rust/bindings_generated.rs FORCE
76+
$(objtree)/rust/libmacros.so $(objtree)/rust/bindings_generated.rs \
77+
$(objtree)/rust/bindings_helpers_generated.rs FORCE
7778
$(call if_changed,rustdoc)
7879

7980
quiet_cmd_rustc_test_library = RUSTC TL $<
8081
cmd_rustc_test_library = \
81-
RUST_BINDINGS_FILE=$(abspath $(objtree)/rust/bindings_generated.rs) \
82+
OBJTREE=$(abspath $(objtree)) \
8283
$(RUSTC) $(filter-out --sysroot=%, $(filter-out -Cpanic=abort, $(filter-out --emit=%, $(rust_flags)))) \
8384
$(rustc_target_flags) --crate-type $(if $(rustc_test_library_proc),proc-macro,rlib) \
8485
--out-dir $(objtree)/rust/test/ --cfg testlib \
@@ -95,7 +96,7 @@ rusttestlib-macros: $(srctree)/rust/macros/lib.rs rusttest-prepare FORCE
9596

9697
quiet_cmd_rustdoc_test = RUSTDOC T $<
9798
cmd_rustdoc_test = \
98-
RUST_BINDINGS_FILE=$(abspath $(objtree)/rust/bindings_generated.rs) \
99+
OBJTREE=$(abspath $(objtree)) \
99100
$(RUSTDOC) --test $(filter-out --sysroot=%, $(filter-out -Cpanic=abort, $(filter-out --emit=%, $(rust_flags)))) \
100101
$(rustc_target_flags) $(rustdoc_test_target_flags) \
101102
--sysroot $(objtree)/rust/test/sysroot $(rustdoc_test_quiet) \
@@ -107,7 +108,7 @@ quiet_cmd_rustdoc_test = RUSTDOC T $<
107108
# so for the moment we skip `-Cpanic=abort`.
108109
quiet_cmd_rustc_test = RUSTC T $<
109110
cmd_rustc_test = \
110-
RUST_BINDINGS_FILE=$(abspath $(objtree)/rust/bindings_generated.rs) \
111+
OBJTREE=$(abspath $(objtree)) \
111112
$(RUSTC) --test $(filter-out --sysroot=%, $(filter-out -Cpanic=abort, $(filter-out --emit=%, $(rust_flags)))) \
112113
$(rustc_target_flags) --out-dir $(objtree)/rust/test \
113114
--sysroot $(objtree)/rust/test/sysroot \
@@ -230,6 +231,19 @@ $(objtree)/rust/bindings_generated.rs: $(srctree)/rust/kernel/bindings_helper.h
230231
$(srctree)/rust/bindgen_parameters FORCE
231232
$(call if_changed_dep,bindgen)
232233

234+
quiet_cmd_bindgen_helper = BINDGEN $@
235+
cmd_bindgen_helper = \
236+
$(BINDGEN) $< --blacklist-type '.*' --whitelist-var '' \
237+
--whitelist-function 'rust_helper_.*' \
238+
--use-core --with-derive-default --ctypes-prefix c_types \
239+
--no-debug '.*' \
240+
--size_t-is-usize -o $@ -- $(bindgen_c_flags_final) \
241+
-I$(objtree)/rust/ -DMODULE; \
242+
sed -Ei 's/pub fn rust_helper_([a-zA-Z0-9_]*)/\#[link_name="rust_helper_\1"]\n pub fn \1/g' $@
243+
244+
$(objtree)/rust/bindings_helpers_generated.rs: $(srctree)/rust/helpers.c FORCE
245+
$(call if_changed_dep,bindgen_helper)
246+
233247
quiet_cmd_exports = EXPORTS $@
234248
cmd_exports = \
235249
$(NM) -p --defined-only $< \
@@ -267,7 +281,7 @@ $(objtree)/rust/libmacros.so: $(srctree)/rust/macros/lib.rs \
267281

268282
quiet_cmd_rustc_library = $(if $(skip_clippy),RUSTC,$(RUSTC_OR_CLIPPY_QUIET)) L $@
269283
cmd_rustc_library = \
270-
RUST_BINDINGS_FILE=$(abspath $(objtree)/rust/bindings_generated.rs) \
284+
OBJTREE=$(abspath $(objtree)) \
271285
$(if $(skip_clippy),$(RUSTC),$(RUSTC_OR_CLIPPY)) \
272286
$(rust_flags) $(rust_cross_flags) $(rustc_target_flags) \
273287
--crate-type rlib --out-dir $(objtree)/rust/ -L $(objtree)/rust/ \
@@ -305,7 +319,8 @@ $(objtree)/rust/kernel.o: private rustc_target_flags = --extern alloc \
305319
--extern macros=$(objtree)/rust/libmacros.so
306320
$(objtree)/rust/kernel.o: $(srctree)/rust/kernel/lib.rs $(objtree)/rust/alloc.o \
307321
$(objtree)/rust/build_error.o \
308-
$(objtree)/rust/libmacros.so $(objtree)/rust/bindings_generated.rs FORCE
322+
$(objtree)/rust/libmacros.so $(objtree)/rust/bindings_generated.rs \
323+
$(objtree)/rust/bindings_helpers_generated.rs FORCE
309324
$(call if_changed_dep,rustc_library)
310325

311326
# Targets that need to expand twice

rust/helpers.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#include <linux/security.h>
1414
#include <asm/io.h>
1515

16-
void rust_helper_BUG(void)
16+
__noreturn void rust_helper_BUG(void)
1717
{
1818
BUG();
1919
}
@@ -91,16 +91,16 @@ void rust_helper_writeq(u64 value, volatile void __iomem *addr)
9191
EXPORT_SYMBOL_GPL(rust_helper_writeq);
9292
#endif
9393

94-
void rust_helper_spin_lock_init(spinlock_t *lock, const char *name,
95-
struct lock_class_key *key)
94+
void rust_helper___spin_lock_init(spinlock_t *lock, const char *name,
95+
struct lock_class_key *key)
9696
{
9797
#ifdef CONFIG_DEBUG_SPINLOCK
9898
__spin_lock_init(lock, name, key);
9999
#else
100100
spin_lock_init(lock);
101101
#endif
102102
}
103-
EXPORT_SYMBOL_GPL(rust_helper_spin_lock_init);
103+
EXPORT_SYMBOL_GPL(rust_helper___spin_lock_init);
104104

105105
void rust_helper_spin_lock(spinlock_t *lock)
106106
{
@@ -162,22 +162,23 @@ size_t rust_helper_copy_to_iter(const void *addr, size_t bytes, struct iov_iter
162162
}
163163
EXPORT_SYMBOL_GPL(rust_helper_copy_to_iter);
164164

165-
bool rust_helper_is_err(__force const void *ptr)
165+
bool rust_helper_IS_ERR(__force const void *ptr)
166166
{
167167
return IS_ERR(ptr);
168168
}
169-
EXPORT_SYMBOL_GPL(rust_helper_is_err);
169+
EXPORT_SYMBOL_GPL(rust_helper_IS_ERR);
170170

171-
long rust_helper_ptr_err(__force const void *ptr)
171+
long rust_helper_PTR_ERR(__force const void *ptr)
172172
{
173173
return PTR_ERR(ptr);
174174
}
175-
EXPORT_SYMBOL_GPL(rust_helper_ptr_err);
175+
EXPORT_SYMBOL_GPL(rust_helper_PTR_ERR);
176176

177177
const char *rust_helper_errname(int err)
178178
{
179179
return errname(err);
180180
}
181+
EXPORT_SYMBOL_GPL(rust_helper_errname);
181182

182183
void rust_helper_mutex_lock(struct mutex *lock)
183184
{
@@ -200,11 +201,11 @@ rust_helper_platform_set_drvdata(struct platform_device *pdev,
200201
}
201202
EXPORT_SYMBOL_GPL(rust_helper_platform_set_drvdata);
202203

203-
refcount_t rust_helper_refcount_new(void)
204+
refcount_t rust_helper_REFCOUNT_INIT(int n)
204205
{
205-
return (refcount_t)REFCOUNT_INIT(1);
206+
return (refcount_t)REFCOUNT_INIT(n);
206207
}
207-
EXPORT_SYMBOL_GPL(rust_helper_refcount_new);
208+
EXPORT_SYMBOL_GPL(rust_helper_REFCOUNT_INIT);
208209

209210
void rust_helper_refcount_inc(refcount_t *r)
210211
{

rust/kernel/bindings.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,37 @@
88
#![cfg_attr(test, allow(deref_nullptr))]
99
#![cfg_attr(test, allow(unaligned_references))]
1010
#![cfg_attr(test, allow(unsafe_op_in_unsafe_fn))]
11-
12-
#[allow(
11+
#![allow(
1312
clippy::all,
1413
non_camel_case_types,
1514
non_upper_case_globals,
1615
non_snake_case,
1716
improper_ctypes,
1817
unsafe_op_in_unsafe_fn
1918
)]
19+
2020
mod bindings_raw {
21+
// Use glob import here to expose all helpers.
22+
// Symbols defined within the module will take precedence to the glob import.
23+
pub use super::bindings_helper::*;
24+
use crate::c_types;
25+
include!(concat!(env!("OBJTREE"), "/rust/bindings_generated.rs"));
26+
}
27+
28+
// When both a directly exposed symbol and a helper exists for the same function,
29+
// the directly exposed symbol is preferred and the helper becomes dead code, so
30+
// ignore the warning here.
31+
#[allow(dead_code)]
32+
mod bindings_helper {
33+
// Import the generated bindings for types.
34+
use super::bindings_raw::*;
2135
use crate::c_types;
22-
include!(env!("RUST_BINDINGS_FILE"));
36+
include!(concat!(
37+
env!("OBJTREE"),
38+
"/rust/bindings_helpers_generated.rs"
39+
));
2340
}
41+
2442
pub use bindings_raw::*;
2543

2644
pub const GFP_KERNEL: gfp_t = BINDINGS_GFP_KERNEL;

rust/kernel/error.rs

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -351,11 +351,8 @@ impl Error {
351351

352352
impl fmt::Debug for Error {
353353
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
354-
extern "C" {
355-
fn rust_helper_errname(err: c_types::c_int) -> *const c_types::c_char;
356-
}
357354
// SAFETY: FFI call.
358-
let name = unsafe { rust_helper_errname(-self.0) };
355+
let name = unsafe { bindings::errname(-self.0) };
359356

360357
if name.is_null() {
361358
// Print out number if no name can be found.
@@ -452,7 +449,7 @@ where
452449
/// ) -> c_types::c_int {
453450
/// from_kernel_result! {
454451
/// let ptr = devm_alloc(pdev)?;
455-
/// rust_helper_platform_set_drvdata(pdev, ptr);
452+
/// bindings::platform_set_drvdata(pdev, ptr);
456453
/// Ok(0)
457454
/// }
458455
/// }
@@ -496,28 +493,20 @@ macro_rules! from_kernel_result {
496493
// TODO: remove `dead_code` marker once an in-kernel client is available.
497494
#[allow(dead_code)]
498495
pub(crate) fn from_kernel_err_ptr<T>(ptr: *mut T) -> Result<*mut T> {
499-
extern "C" {
500-
#[allow(improper_ctypes)]
501-
fn rust_helper_is_err(ptr: *const c_types::c_void) -> bool;
502-
503-
#[allow(improper_ctypes)]
504-
fn rust_helper_ptr_err(ptr: *const c_types::c_void) -> c_types::c_long;
505-
}
506-
507496
// CAST: casting a pointer to `*const c_types::c_void` is always valid.
508497
let const_ptr: *const c_types::c_void = ptr.cast();
509498
// SAFETY: the FFI function does not deref the pointer.
510-
if unsafe { rust_helper_is_err(const_ptr) } {
499+
if unsafe { bindings::IS_ERR(const_ptr) } {
511500
// SAFETY: the FFI function does not deref the pointer.
512-
let err = unsafe { rust_helper_ptr_err(const_ptr) };
513-
// CAST: if `rust_helper_is_err()` returns `true`,
514-
// then `rust_helper_ptr_err()` is guaranteed to return a
501+
let err = unsafe { bindings::PTR_ERR(const_ptr) };
502+
// CAST: if `IS_ERR()` returns `true`,
503+
// then `PTR_ERR()` is guaranteed to return a
515504
// negative value greater-or-equal to `-bindings::MAX_ERRNO`,
516505
// which always fits in an `i16`, as per the invariant above.
517506
// And an `i16` always fits in an `i32`. So casting `err` to
518507
// an `i32` can never overflow, and is always valid.
519508
//
520-
// SAFETY: `rust_helper_is_err()` ensures `err` is a
509+
// SAFETY: `IS_ERR()` ensures `err` is a
521510
// negative value greater-or-equal to `-bindings::MAX_ERRNO`
522511
return Err(unsafe { Error::from_kernel_errno_unchecked(err as i32) });
523512
}

0 commit comments

Comments
 (0)