Skip to content

Commit d072acd

Browse files
nbdd0121ojeda
authored andcommitted
rust: use custom FFI integer types
Currently FFI integer types are defined in libcore. This commit creates the `ffi` crate and asks bindgen to use that crate for FFI integer types instead of `core::ffi`. This commit is preparatory and no type changes are made in this commit yet. Signed-off-by: Gary Guo <[email protected]> Link: https://lore.kernel.org/r/[email protected] [ Added `rustdoc`, `rusttest` and KUnit tests support. Rebased on top of `rust-next` (e.g. migrated more `core::ffi` cases). Reworded crate docs slightly and formatted. - Miguel ] Signed-off-by: Miguel Ojeda <[email protected]>
1 parent 2fd6f55 commit d072acd

23 files changed

+107
-83
lines changed

rust/Makefile

+26-13
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Where to place rustdoc generated documentation
44
rustdoc_output := $(objtree)/Documentation/output/rust/rustdoc
55

6-
obj-$(CONFIG_RUST) += core.o compiler_builtins.o
6+
obj-$(CONFIG_RUST) += core.o compiler_builtins.o ffi.o
77
always-$(CONFIG_RUST) += exports_core_generated.h
88

99
# Missing prototypes are expected in the helpers since these are exported
@@ -103,10 +103,13 @@ rustdoc-core: $(RUST_LIB_SRC)/core/src/lib.rs FORCE
103103
rustdoc-compiler_builtins: $(src)/compiler_builtins.rs rustdoc-core FORCE
104104
+$(call if_changed,rustdoc)
105105

106-
rustdoc-kernel: private rustc_target_flags = \
106+
rustdoc-ffi: $(src)/ffi.rs rustdoc-core FORCE
107+
+$(call if_changed,rustdoc)
108+
109+
rustdoc-kernel: private rustc_target_flags = --extern ffi \
107110
--extern build_error --extern macros=$(objtree)/$(obj)/libmacros.so \
108111
--extern bindings --extern uapi
109-
rustdoc-kernel: $(src)/kernel/lib.rs rustdoc-core rustdoc-macros \
112+
rustdoc-kernel: $(src)/kernel/lib.rs rustdoc-core rustdoc-ffi rustdoc-macros \
110113
rustdoc-compiler_builtins $(obj)/libmacros.so \
111114
$(obj)/bindings.o FORCE
112115
+$(call if_changed,rustdoc)
@@ -124,23 +127,28 @@ quiet_cmd_rustc_test_library = RUSTC TL $<
124127
rusttestlib-build_error: $(src)/build_error.rs FORCE
125128
+$(call if_changed,rustc_test_library)
126129

130+
rusttestlib-ffi: $(src)/ffi.rs FORCE
131+
+$(call if_changed,rustc_test_library)
132+
127133
rusttestlib-macros: private rustc_target_flags = --extern proc_macro
128134
rusttestlib-macros: private rustc_test_library_proc = yes
129135
rusttestlib-macros: $(src)/macros/lib.rs FORCE
130136
+$(call if_changed,rustc_test_library)
131137

132-
rusttestlib-kernel: private rustc_target_flags = \
138+
rusttestlib-kernel: private rustc_target_flags = --extern ffi \
133139
--extern build_error --extern macros \
134140
--extern bindings --extern uapi
135141
rusttestlib-kernel: $(src)/kernel/lib.rs \
136142
rusttestlib-bindings rusttestlib-uapi rusttestlib-build_error \
137143
$(obj)/libmacros.so $(obj)/bindings.o FORCE
138144
+$(call if_changed,rustc_test_library)
139145

140-
rusttestlib-bindings: $(src)/bindings/lib.rs FORCE
146+
rusttestlib-bindings: private rustc_target_flags = --extern ffi
147+
rusttestlib-bindings: $(src)/bindings/lib.rs rusttestlib-ffi FORCE
141148
+$(call if_changed,rustc_test_library)
142149

143-
rusttestlib-uapi: $(src)/uapi/lib.rs FORCE
150+
rusttestlib-uapi: private rustc_target_flags = --extern ffi
151+
rusttestlib-uapi: $(src)/uapi/lib.rs rusttestlib-ffi FORCE
144152
+$(call if_changed,rustc_test_library)
145153

146154
quiet_cmd_rustdoc_test = RUSTDOC T $<
@@ -160,7 +168,7 @@ quiet_cmd_rustdoc_test_kernel = RUSTDOC TK $<
160168
mkdir -p $(objtree)/$(obj)/test/doctests/kernel; \
161169
OBJTREE=$(abspath $(objtree)) \
162170
$(RUSTDOC) --test $(rust_flags) \
163-
-L$(objtree)/$(obj) --extern kernel \
171+
-L$(objtree)/$(obj) --extern ffi --extern kernel \
164172
--extern build_error --extern macros \
165173
--extern bindings --extern uapi \
166174
--no-run --crate-name kernel -Zunstable-options \
@@ -198,9 +206,9 @@ rusttest-macros: $(src)/macros/lib.rs \
198206
+$(call if_changed,rustc_test)
199207
+$(call if_changed,rustdoc_test)
200208

201-
rusttest-kernel: private rustc_target_flags = \
209+
rusttest-kernel: private rustc_target_flags = --extern ffi \
202210
--extern build_error --extern macros --extern bindings --extern uapi
203-
rusttest-kernel: $(src)/kernel/lib.rs rusttestlib-kernel \
211+
rusttest-kernel: $(src)/kernel/lib.rs rusttestlib-ffi rusttestlib-kernel \
204212
rusttestlib-build_error rusttestlib-macros rusttestlib-bindings \
205213
rusttestlib-uapi FORCE
206214
+$(call if_changed,rustc_test)
@@ -273,7 +281,7 @@ bindgen_c_flags_final = $(bindgen_c_flags_lto) -fno-builtin -D__BINDGEN__
273281
quiet_cmd_bindgen = BINDGEN $@
274282
cmd_bindgen = \
275283
$(BINDGEN) $< $(bindgen_target_flags) \
276-
--use-core --with-derive-default --ctypes-prefix core::ffi --no-layout-tests \
284+
--use-core --with-derive-default --ctypes-prefix ffi --no-layout-tests \
277285
--no-debug '.*' --enable-function-attribute-detection \
278286
-o $@ -- $(bindgen_c_flags_final) -DMODULE \
279287
$(bindgen_target_cflags) $(bindgen_target_extra)
@@ -401,18 +409,23 @@ $(obj)/compiler_builtins.o: $(src)/compiler_builtins.rs $(obj)/core.o FORCE
401409
$(obj)/build_error.o: $(src)/build_error.rs $(obj)/compiler_builtins.o FORCE
402410
+$(call if_changed_rule,rustc_library)
403411

412+
$(obj)/ffi.o: $(src)/ffi.rs $(obj)/compiler_builtins.o FORCE
413+
+$(call if_changed_rule,rustc_library)
414+
415+
$(obj)/bindings.o: private rustc_target_flags = --extern ffi
404416
$(obj)/bindings.o: $(src)/bindings/lib.rs \
405-
$(obj)/compiler_builtins.o \
417+
$(obj)/ffi.o \
406418
$(obj)/bindings/bindings_generated.rs \
407419
$(obj)/bindings/bindings_helpers_generated.rs FORCE
408420
+$(call if_changed_rule,rustc_library)
409421

422+
$(obj)/uapi.o: private rustc_target_flags = --extern ffi
410423
$(obj)/uapi.o: $(src)/uapi/lib.rs \
411-
$(obj)/compiler_builtins.o \
424+
$(obj)/ffi.o \
412425
$(obj)/uapi/uapi_generated.rs FORCE
413426
+$(call if_changed_rule,rustc_library)
414427

415-
$(obj)/kernel.o: private rustc_target_flags = \
428+
$(obj)/kernel.o: private rustc_target_flags = --extern ffi \
416429
--extern build_error --extern macros --extern bindings --extern uapi
417430
$(obj)/kernel.o: $(src)/kernel/lib.rs $(obj)/build_error.o \
418431
$(obj)/libmacros.so $(obj)/bindings.o $(obj)/uapi.o FORCE

rust/ffi.rs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
//! Foreign function interface (FFI) types.
4+
//!
5+
//! This crate provides mapping from C primitive types to Rust ones.
6+
//!
7+
//! The Rust [`core`] crate provides [`core::ffi`], which maps integer types to the platform default
8+
//! C ABI. The kernel does not use [`core::ffi`], so it can customise the mapping that deviates from
9+
//! the platform default.
10+
11+
#![no_std]
12+
13+
pub use core::ffi::*;

rust/kernel/alloc/allocator.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ fn aligned_size(new_layout: Layout) -> usize {
5858
///
5959
/// One of the following: `krealloc`, `vrealloc`, `kvrealloc`.
6060
struct ReallocFunc(
61-
unsafe extern "C" fn(*const core::ffi::c_void, usize, u32) -> *mut core::ffi::c_void,
61+
unsafe extern "C" fn(*const crate::ffi::c_void, usize, u32) -> *mut crate::ffi::c_void,
6262
);
6363

6464
impl ReallocFunc {

rust/kernel/alloc/allocator_test.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ pub type KVmalloc = Kmalloc;
2424

2525
extern "C" {
2626
#[link_name = "aligned_alloc"]
27-
fn libc_aligned_alloc(align: usize, size: usize) -> *mut core::ffi::c_void;
27+
fn libc_aligned_alloc(align: usize, size: usize) -> *mut crate::ffi::c_void;
2828

2929
#[link_name = "free"]
30-
fn libc_free(ptr: *mut core::ffi::c_void);
30+
fn libc_free(ptr: *mut crate::ffi::c_void);
3131
}
3232

3333
// SAFETY:

rust/kernel/alloc/kbox.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -355,17 +355,17 @@ where
355355
{
356356
type Borrowed<'a> = &'a T;
357357

358-
fn into_foreign(self) -> *const core::ffi::c_void {
358+
fn into_foreign(self) -> *const crate::ffi::c_void {
359359
Box::into_raw(self) as _
360360
}
361361

362-
unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self {
362+
unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self {
363363
// SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
364364
// call to `Self::into_foreign`.
365365
unsafe { Box::from_raw(ptr as _) }
366366
}
367367

368-
unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> &'a T {
368+
unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> &'a T {
369369
// SAFETY: The safety requirements of this method ensure that the object remains alive and
370370
// immutable for the duration of 'a.
371371
unsafe { &*ptr.cast() }
@@ -378,18 +378,18 @@ where
378378
{
379379
type Borrowed<'a> = Pin<&'a T>;
380380

381-
fn into_foreign(self) -> *const core::ffi::c_void {
381+
fn into_foreign(self) -> *const crate::ffi::c_void {
382382
// SAFETY: We are still treating the box as pinned.
383383
Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }) as _
384384
}
385385

386-
unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self {
386+
unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self {
387387
// SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
388388
// call to `Self::into_foreign`.
389389
unsafe { Pin::new_unchecked(Box::from_raw(ptr as _)) }
390390
}
391391

392-
unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> Pin<&'a T> {
392+
unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> Pin<&'a T> {
393393
// SAFETY: The safety requirements for this function ensure that the object is still alive,
394394
// so it is safe to dereference the raw pointer.
395395
// The safety requirements of `from_foreign` also ensure that the object remains alive for

rust/kernel/block/mq/operations.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ impl<T: Operations> OperationsVTable<T> {
131131
unsafe extern "C" fn poll_callback(
132132
_hctx: *mut bindings::blk_mq_hw_ctx,
133133
_iob: *mut bindings::io_comp_batch,
134-
) -> core::ffi::c_int {
134+
) -> crate::ffi::c_int {
135135
T::poll().into()
136136
}
137137

@@ -145,9 +145,9 @@ impl<T: Operations> OperationsVTable<T> {
145145
/// for the same context.
146146
unsafe extern "C" fn init_hctx_callback(
147147
_hctx: *mut bindings::blk_mq_hw_ctx,
148-
_tagset_data: *mut core::ffi::c_void,
149-
_hctx_idx: core::ffi::c_uint,
150-
) -> core::ffi::c_int {
148+
_tagset_data: *mut crate::ffi::c_void,
149+
_hctx_idx: crate::ffi::c_uint,
150+
) -> crate::ffi::c_int {
151151
from_result(|| Ok(0))
152152
}
153153

@@ -159,7 +159,7 @@ impl<T: Operations> OperationsVTable<T> {
159159
/// This function may only be called by blk-mq C infrastructure.
160160
unsafe extern "C" fn exit_hctx_callback(
161161
_hctx: *mut bindings::blk_mq_hw_ctx,
162-
_hctx_idx: core::ffi::c_uint,
162+
_hctx_idx: crate::ffi::c_uint,
163163
) {
164164
}
165165

@@ -176,9 +176,9 @@ impl<T: Operations> OperationsVTable<T> {
176176
unsafe extern "C" fn init_request_callback(
177177
_set: *mut bindings::blk_mq_tag_set,
178178
rq: *mut bindings::request,
179-
_hctx_idx: core::ffi::c_uint,
180-
_numa_node: core::ffi::c_uint,
181-
) -> core::ffi::c_int {
179+
_hctx_idx: crate::ffi::c_uint,
180+
_numa_node: crate::ffi::c_uint,
181+
) -> crate::ffi::c_int {
182182
from_result(|| {
183183
// SAFETY: By the safety requirements of this function, `rq` points
184184
// to a valid allocation.
@@ -203,7 +203,7 @@ impl<T: Operations> OperationsVTable<T> {
203203
unsafe extern "C" fn exit_request_callback(
204204
_set: *mut bindings::blk_mq_tag_set,
205205
rq: *mut bindings::request,
206-
_hctx_idx: core::ffi::c_uint,
206+
_hctx_idx: crate::ffi::c_uint,
207207
) {
208208
// SAFETY: The tagset invariants guarantee that all requests are allocated with extra memory
209209
// for the request data.

rust/kernel/block/mq/raw_writer.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ impl<'a> RawWriter<'a> {
2525
}
2626

2727
pub(crate) fn from_array<const N: usize>(
28-
a: &'a mut [core::ffi::c_char; N],
28+
a: &'a mut [crate::ffi::c_char; N],
2929
) -> Result<RawWriter<'a>> {
3030
Self::new(
3131
// SAFETY: the buffer of `a` is valid for read and write as `u8` for

rust/kernel/block/mq/tag_set.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ impl<T: Operations> TagSet<T> {
5353
queue_depth: num_tags,
5454
cmd_size,
5555
flags: bindings::BLK_MQ_F_SHOULD_MERGE,
56-
driver_data: core::ptr::null_mut::<core::ffi::c_void>(),
56+
driver_data: core::ptr::null_mut::<crate::ffi::c_void>(),
5757
nr_maps: num_maps,
5858
..tag_set
5959
}

rust/kernel/error.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ impl Error {
100100
///
101101
/// It is a bug to pass an out-of-range `errno`. `EINVAL` would
102102
/// be returned in such a case.
103-
pub fn from_errno(errno: core::ffi::c_int) -> Error {
103+
pub fn from_errno(errno: crate::ffi::c_int) -> Error {
104104
if errno < -(bindings::MAX_ERRNO as i32) || errno >= 0 {
105105
// TODO: Make it a `WARN_ONCE` once available.
106106
crate::pr_warn!(
@@ -119,7 +119,7 @@ impl Error {
119119
/// Creates an [`Error`] from a kernel error code.
120120
///
121121
/// Returns [`None`] if `errno` is out-of-range.
122-
const fn try_from_errno(errno: core::ffi::c_int) -> Option<Error> {
122+
const fn try_from_errno(errno: crate::ffi::c_int) -> Option<Error> {
123123
if errno < -(bindings::MAX_ERRNO as i32) || errno >= 0 {
124124
return None;
125125
}
@@ -133,15 +133,15 @@ impl Error {
133133
/// # Safety
134134
///
135135
/// `errno` must be within error code range (i.e. `>= -MAX_ERRNO && < 0`).
136-
const unsafe fn from_errno_unchecked(errno: core::ffi::c_int) -> Error {
136+
const unsafe fn from_errno_unchecked(errno: crate::ffi::c_int) -> Error {
137137
// INVARIANT: The contract ensures the type invariant
138138
// will hold.
139139
// SAFETY: The caller guarantees `errno` is non-zero.
140140
Error(unsafe { NonZeroI32::new_unchecked(errno) })
141141
}
142142

143143
/// Returns the kernel error code.
144-
pub fn to_errno(self) -> core::ffi::c_int {
144+
pub fn to_errno(self) -> crate::ffi::c_int {
145145
self.0.get()
146146
}
147147

@@ -259,7 +259,7 @@ pub type Result<T = (), E = Error> = core::result::Result<T, E>;
259259

260260
/// Converts an integer as returned by a C kernel function to an error if it's negative, and
261261
/// `Ok(())` otherwise.
262-
pub fn to_result(err: core::ffi::c_int) -> Result {
262+
pub fn to_result(err: crate::ffi::c_int) -> Result {
263263
if err < 0 {
264264
Err(Error::from_errno(err))
265265
} else {
@@ -282,15 +282,15 @@ pub fn to_result(err: core::ffi::c_int) -> Result {
282282
/// fn devm_platform_ioremap_resource(
283283
/// pdev: &mut PlatformDevice,
284284
/// index: u32,
285-
/// ) -> Result<*mut core::ffi::c_void> {
285+
/// ) -> Result<*mut kernel::ffi::c_void> {
286286
/// // SAFETY: `pdev` points to a valid platform device. There are no safety requirements
287287
/// // on `index`.
288288
/// from_err_ptr(unsafe { bindings::devm_platform_ioremap_resource(pdev.to_ptr(), index) })
289289
/// }
290290
/// ```
291291
pub fn from_err_ptr<T>(ptr: *mut T) -> Result<*mut T> {
292-
// CAST: Casting a pointer to `*const core::ffi::c_void` is always valid.
293-
let const_ptr: *const core::ffi::c_void = ptr.cast();
292+
// CAST: Casting a pointer to `*const crate::ffi::c_void` is always valid.
293+
let const_ptr: *const crate::ffi::c_void = ptr.cast();
294294
// SAFETY: The FFI function does not deref the pointer.
295295
if unsafe { bindings::IS_ERR(const_ptr) } {
296296
// SAFETY: The FFI function does not deref the pointer.
@@ -306,7 +306,7 @@ pub fn from_err_ptr<T>(ptr: *mut T) -> Result<*mut T> {
306306
//
307307
// SAFETY: `IS_ERR()` ensures `err` is a
308308
// negative value greater-or-equal to `-bindings::MAX_ERRNO`.
309-
return Err(unsafe { Error::from_errno_unchecked(err as core::ffi::c_int) });
309+
return Err(unsafe { Error::from_errno_unchecked(err as crate::ffi::c_int) });
310310
}
311311
Ok(ptr)
312312
}
@@ -326,7 +326,7 @@ pub fn from_err_ptr<T>(ptr: *mut T) -> Result<*mut T> {
326326
/// # use kernel::bindings;
327327
/// unsafe extern "C" fn probe_callback(
328328
/// pdev: *mut bindings::platform_device,
329-
/// ) -> core::ffi::c_int {
329+
/// ) -> kernel::ffi::c_int {
330330
/// from_result(|| {
331331
/// let ptr = devm_alloc(pdev)?;
332332
/// bindings::platform_set_drvdata(pdev, ptr);

rust/kernel/init.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@
133133
//! # }
134134
//! # // `Error::from_errno` is `pub(crate)` in the `kernel` crate, thus provide a workaround.
135135
//! # trait FromErrno {
136-
//! # fn from_errno(errno: core::ffi::c_int) -> Error {
136+
//! # fn from_errno(errno: kernel::ffi::c_int) -> Error {
137137
//! # // Dummy error that can be constructed outside the `kernel` crate.
138138
//! # Error::from(core::fmt::Error)
139139
//! # }

rust/kernel/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ compile_error!("Missing kernel configuration for conditional compilation");
2727
// Allow proc-macros to refer to `::kernel` inside the `kernel` crate (this crate).
2828
extern crate self as kernel;
2929

30+
pub use ffi;
31+
3032
pub mod alloc;
3133
#[cfg(CONFIG_BLOCK)]
3234
pub mod block;

0 commit comments

Comments
 (0)