Skip to content

Commit e361044

Browse files
committed
Merge tag 'rust-6.14' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux
Pull rust updates from Miguel Ojeda: "Toolchain and infrastructure: - Finish the move to custom FFI integer types started in the previous cycle and finally map 'long' to 'isize' and 'char' to 'u8'. Do a few cleanups on top thanks to that. - Start to use 'derive(CoercePointee)' on Rust >= 1.84.0. This is a major milestone on the path to build the kernel using only stable Rust features. In particular, previously we were using the unstable features 'coerce_unsized', 'dispatch_from_dyn' and 'unsize', and now we will use the new 'derive_coerce_pointee' one, which is on track to stabilization. This new feature is a macro that essentially expands into code that internally uses the unstable features that we were using before, without having to expose those. With it, stable Rust users, including the kernel, will be able to build custom smart pointers that work with trait objects, e.g.: fn f(p: &Arc<dyn Display>) { pr_info!("{p}\n"); } let a: Arc<dyn Display> = Arc::new(42i32, GFP_KERNEL)?; let b: Arc<dyn Display> = Arc::new("hello there", GFP_KERNEL)?; f(&a); // Prints "42". f(&b); // Prints "hello there". Together with the 'arbitrary_self_types' feature that we started using in the previous cycle, using our custom smart pointers like 'Arc' will eventually only rely in stable Rust. - Introduce 'PROCMACROLDFLAGS' environment variable to allow to link Rust proc macros using different flags than those used for linking Rust host programs (e.g. when 'rustc' uses a different C library than the host programs' one), which Android needs. - Help kernel builds under macOS with Rust enabled by accomodating other naming conventions for dynamic libraries (i.e. '.so' vs. '.dylib') which are used for Rust procedural macros. The actual support for macOS (i.e. the rest of the pieces needed) is provided out-of-tree by others, following the policy used for other parts of the kernel by Kbuild. - Run Clippy for 'rusttest' code too and clean the bits it spotted. - Provide Clippy with the minimum supported Rust version to improve the suggestions it gives. - Document 'bindgen' 0.71.0 regression. 'kernel' crate: - 'build_error!': move users of the hidden function to the documented macro, prevent such uses in the future by moving the function elsewhere and add the macro to the prelude. - 'types' module: add improved version of 'ForeignOwnable::borrow_mut' (which was removed in the past since it was problematic); change 'ForeignOwnable' pointer type to '*mut'. - 'alloc' module: implement 'Display' for 'Box' and align the 'Debug' implementation to it; add example (doctest) for 'ArrayLayout::new()' - 'sync' module: document 'PhantomData' in 'Arc'; use 'NonNull::new_unchecked' in 'ForeignOwnable for Arc' impl. - 'uaccess' module: accept 'Vec's with different allocators in 'UserSliceReader::read_all'. - 'workqueue' module: enable run-testing a couple more doctests. - 'error' module: simplify 'from_errno()'. - 'block' module: fix formatting in code documentation (a lint to catch these is being implemented). - Avoid 'unwrap()'s in doctests, which also improves the examples by showing how kernel code is supposed to be written. - Avoid 'as' casts with 'cast{,_mut}' calls which are a bit safer. And a few other cleanups" * tag 'rust-6.14' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux: (32 commits) kbuild: rust: add PROCMACROLDFLAGS rust: uaccess: generalize userSliceReader to support any Vec rust: kernel: add improved version of `ForeignOwnable::borrow_mut` rust: kernel: reorder `ForeignOwnable` items rust: kernel: change `ForeignOwnable` pointer to mut rust: arc: split unsafe block, add missing comment rust: types: avoid `as` casts rust: arc: use `NonNull::new_unchecked` rust: use derive(CoercePointee) on rustc >= 1.84.0 rust: alloc: add doctest for `ArrayLayout::new()` rust: init: update `stack_try_pin_init` examples rust: error: import `kernel`'s `LayoutError` instead of `core`'s rust: str: replace unwraps with question mark operators rust: page: remove unnecessary helper function from doctest rust: rbtree: remove unwrap in asserts rust: init: replace unwraps with question mark operators rust: use host dylib naming convention to support macOS rust: add `build_error!` to the prelude rust: kernel: move `build_error` hidden function to prevent mistakes rust: use the `build_error!` macro, not the hidden function ...
2 parents 1d6d399 + ceff075 commit e361044

37 files changed

+437
-217
lines changed

.clippy.toml

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

3+
msrv = "1.78.0"
4+
35
check-private-items = true
46

57
disallowed-macros = [

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
*.dtb.S
2323
*.dtbo.S
2424
*.dwo
25+
*.dylib
2526
*.elf
2627
*.gcno
2728
*.gcda

Documentation/kbuild/kbuild.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,17 @@ HOSTRUSTFLAGS
9191
-------------
9292
Additional flags to be passed to $(HOSTRUSTC) when building host programs.
9393

94+
PROCMACROLDFLAGS
95+
----------------
96+
Flags to be passed when linking Rust proc macros. Since proc macros are loaded
97+
by rustc at build time, they must be linked in a way that is compatible with
98+
the rustc toolchain being used.
99+
100+
For instance, it can be useful when rustc uses a different C library than
101+
the one the user wants to use for host programs.
102+
103+
If unset, it defaults to the flags passed when linking host programs.
104+
94105
HOSTLDFLAGS
95106
-----------
96107
Additional flags to be passed when linking host programs.

Makefile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,7 @@ KBUILD_HOSTRUSTFLAGS := $(rust_common_flags) -O -Cstrip=debuginfo \
497497
-Zallow-features= $(HOSTRUSTFLAGS)
498498
KBUILD_HOSTLDFLAGS := $(HOST_LFS_LDFLAGS) $(HOSTLDFLAGS)
499499
KBUILD_HOSTLDLIBS := $(HOST_LFS_LIBS) $(HOSTLDLIBS)
500+
KBUILD_PROCMACROLDFLAGS := $(or $(PROCMACROLDFLAGS),$(KBUILD_HOSTLDFLAGS))
500501

501502
# Make variables (CC, etc...)
502503
CPP = $(CC) -E
@@ -621,7 +622,7 @@ export HOSTRUSTC KBUILD_HOSTRUSTFLAGS
621622
export CPP AR NM STRIP OBJCOPY OBJDUMP READELF PAHOLE RESOLVE_BTFIDS LEX YACC AWK INSTALLKERNEL
622623
export PERL PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX
623624
export KGZIP KBZIP2 KLZOP LZMA LZ4 XZ ZSTD
624-
export KBUILD_HOSTCXXFLAGS KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS LDFLAGS_MODULE
625+
export KBUILD_HOSTCXXFLAGS KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS KBUILD_PROCMACROLDFLAGS LDFLAGS_MODULE
625626
export KBUILD_USERCFLAGS KBUILD_USERLDFLAGS
626627

627628
export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS KBUILD_LDFLAGS
@@ -1571,7 +1572,7 @@ MRPROPER_FILES += include/config include/generated \
15711572
certs/x509.genkey \
15721573
vmlinux-gdb.py \
15731574
rpmbuild \
1574-
rust/libmacros.so
1575+
rust/libmacros.so rust/libmacros.dylib
15751576

15761577
# clean - Delete most, but leave enough to build external modules
15771578
#

drivers/gpu/drm/drm_panic_qr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -931,7 +931,7 @@ impl QrImage<'_> {
931931
/// They must remain valid for the duration of the function call.
932932
#[no_mangle]
933933
pub unsafe extern "C" fn drm_panic_qr_generate(
934-
url: *const i8,
934+
url: *const kernel::ffi::c_char,
935935
data: *mut u8,
936936
data_len: usize,
937937
data_size: usize,

init/Kconfig

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,9 @@ config CC_HAS_COUNTED_BY
129129
# https://github.com/llvm/llvm-project/pull/112636
130130
depends on !(CC_IS_CLANG && CLANG_VERSION < 190103)
131131

132+
config RUSTC_HAS_COERCE_POINTEE
133+
def_bool RUSTC_VERSION >= 108400
134+
132135
config PAHOLE_VERSION
133136
int
134137
default $(shell,$(srctree)/scripts/pahole-version.sh $(PAHOLE))
@@ -2000,8 +2003,10 @@ config BINDGEN_VERSION_TEXT
20002003
string
20012004
depends on RUST
20022005
# The dummy parameter `workaround-for-0.69.0` is required to support 0.69.0
2003-
# (https://github.com/rust-lang/rust-bindgen/pull/2678). It can be removed when
2004-
# the minimum version is upgraded past that (0.69.1 already fixed the issue).
2006+
# (https://github.com/rust-lang/rust-bindgen/pull/2678) and 0.71.0
2007+
# (https://github.com/rust-lang/rust-bindgen/pull/3040). It can be removed
2008+
# when the minimum version is upgraded past the latter (0.69.1 and 0.71.1
2009+
# both fixed the issue).
20052010
default "$(shell,$(BINDGEN) --version workaround-for-0.69.0 2>/dev/null)"
20062011

20072012
#

rust/Makefile

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@ always-$(CONFIG_RUST) += exports_core_generated.h
1111
obj-$(CONFIG_RUST) += helpers/helpers.o
1212
CFLAGS_REMOVE_helpers/helpers.o = -Wmissing-prototypes -Wmissing-declarations
1313

14-
always-$(CONFIG_RUST) += libmacros.so
15-
no-clean-files += libmacros.so
16-
1714
always-$(CONFIG_RUST) += bindings/bindings_generated.rs bindings/bindings_helpers_generated.rs
1815
obj-$(CONFIG_RUST) += bindings.o kernel.o
1916
always-$(CONFIG_RUST) += exports_helpers_generated.h \
@@ -38,9 +35,14 @@ obj-$(CONFIG_RUST_KERNEL_DOCTESTS) += doctests_kernel_generated_kunit.o
3835

3936
always-$(subst y,$(CONFIG_RUST),$(CONFIG_JUMP_LABEL)) += kernel/generated_arch_static_branch_asm.rs
4037

41-
# Avoids running `$(RUSTC)` for the sysroot when it may not be available.
38+
# Avoids running `$(RUSTC)` when it may not be available.
4239
ifdef CONFIG_RUST
4340

41+
libmacros_name := $(shell MAKEFLAGS= $(RUSTC) --print file-names --crate-name macros --crate-type proc-macro - </dev/null)
42+
libmacros_extension := $(patsubst libmacros.%,%,$(libmacros_name))
43+
44+
always-$(CONFIG_RUST) += $(libmacros_name)
45+
4446
# `$(rust_flags)` is passed in case the user added `--sysroot`.
4547
rustc_sysroot := $(shell MAKEFLAGS= $(RUSTC) $(rust_flags) --print sysroot)
4648
rustc_host_target := $(shell $(RUSTC) --version --verbose | grep -F 'host: ' | cut -d' ' -f2)
@@ -109,17 +111,17 @@ rustdoc-ffi: $(src)/ffi.rs rustdoc-core FORCE
109111
+$(call if_changed,rustdoc)
110112

111113
rustdoc-kernel: private rustc_target_flags = --extern ffi \
112-
--extern build_error --extern macros=$(objtree)/$(obj)/libmacros.so \
114+
--extern build_error --extern macros \
113115
--extern bindings --extern uapi
114116
rustdoc-kernel: $(src)/kernel/lib.rs rustdoc-core rustdoc-ffi rustdoc-macros \
115-
rustdoc-compiler_builtins $(obj)/libmacros.so \
117+
rustdoc-compiler_builtins $(obj)/$(libmacros_name) \
116118
$(obj)/bindings.o FORCE
117119
+$(call if_changed,rustdoc)
118120

119-
quiet_cmd_rustc_test_library = RUSTC TL $<
121+
quiet_cmd_rustc_test_library = $(RUSTC_OR_CLIPPY_QUIET) TL $<
120122
cmd_rustc_test_library = \
121123
OBJTREE=$(abspath $(objtree)) \
122-
$(RUSTC) $(rust_common_flags) \
124+
$(RUSTC_OR_CLIPPY) $(rust_common_flags) \
123125
@$(objtree)/include/generated/rustc_cfg $(rustc_target_flags) \
124126
--crate-type $(if $(rustc_test_library_proc),proc-macro,rlib) \
125127
--out-dir $(objtree)/$(obj)/test --cfg testlib \
@@ -187,10 +189,10 @@ quiet_cmd_rustdoc_test_kernel = RUSTDOC TK $<
187189

188190
# We cannot use `-Zpanic-abort-tests` because some tests are dynamic,
189191
# so for the moment we skip `-Cpanic=abort`.
190-
quiet_cmd_rustc_test = RUSTC T $<
192+
quiet_cmd_rustc_test = $(RUSTC_OR_CLIPPY_QUIET) T $<
191193
cmd_rustc_test = \
192194
OBJTREE=$(abspath $(objtree)) \
193-
$(RUSTC) --test $(rust_common_flags) \
195+
$(RUSTC_OR_CLIPPY) --test $(rust_common_flags) \
194196
@$(objtree)/include/generated/rustc_cfg \
195197
$(rustc_target_flags) --out-dir $(objtree)/$(obj)/test \
196198
-L$(objtree)/$(obj)/test \
@@ -359,13 +361,13 @@ quiet_cmd_rustc_procmacro = $(RUSTC_OR_CLIPPY_QUIET) P $@
359361
cmd_rustc_procmacro = \
360362
$(RUSTC_OR_CLIPPY) $(rust_common_flags) \
361363
-Clinker-flavor=gcc -Clinker=$(HOSTCC) \
362-
-Clink-args='$(call escsq,$(KBUILD_HOSTLDFLAGS))' \
364+
-Clink-args='$(call escsq,$(KBUILD_PROCMACROLDFLAGS))' \
363365
--emit=dep-info=$(depfile) --emit=link=$@ --extern proc_macro \
364366
--crate-type proc-macro \
365-
--crate-name $(patsubst lib%.so,%,$(notdir $@)) $<
367+
--crate-name $(patsubst lib%.$(libmacros_extension),%,$(notdir $@)) $<
366368

367369
# Procedural macros can only be used with the `rustc` that compiled it.
368-
$(obj)/libmacros.so: $(src)/macros/lib.rs FORCE
370+
$(obj)/$(libmacros_name): $(src)/macros/lib.rs FORCE
369371
+$(call if_changed_dep,rustc_procmacro)
370372

371373
quiet_cmd_rustc_library = $(if $(skip_clippy),RUSTC,$(RUSTC_OR_CLIPPY_QUIET)) L $@
@@ -382,7 +384,7 @@ quiet_cmd_rustc_library = $(if $(skip_clippy),RUSTC,$(RUSTC_OR_CLIPPY_QUIET)) L
382384
$(cmd_objtool)
383385

384386
rust-analyzer:
385-
$(Q)$(srctree)/scripts/generate_rust_analyzer.py \
387+
$(Q)MAKEFLAGS= $(srctree)/scripts/generate_rust_analyzer.py \
386388
--cfgs='core=$(core-cfgs)' \
387389
$(realpath $(srctree)) $(realpath $(objtree)) \
388390
$(rustc_sysroot) $(RUST_LIB_SRC) $(if $(KBUILD_EXTMOD),$(srcroot)) \
@@ -443,7 +445,7 @@ $(obj)/uapi.o: $(src)/uapi/lib.rs \
443445
$(obj)/kernel.o: private rustc_target_flags = --extern ffi \
444446
--extern build_error --extern macros --extern bindings --extern uapi
445447
$(obj)/kernel.o: $(src)/kernel/lib.rs $(obj)/build_error.o \
446-
$(obj)/libmacros.so $(obj)/bindings.o $(obj)/uapi.o FORCE
448+
$(obj)/$(libmacros_name) $(obj)/bindings.o $(obj)/uapi.o FORCE
447449
+$(call if_changed_rule,rustc_library)
448450

449451
ifdef CONFIG_JUMP_LABEL

rust/ffi.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,39 @@
1010
1111
#![no_std]
1212

13-
pub use core::ffi::*;
13+
macro_rules! alias {
14+
($($name:ident = $ty:ty;)*) => {$(
15+
#[allow(non_camel_case_types, missing_docs)]
16+
pub type $name = $ty;
17+
18+
// Check size compatibility with `core`.
19+
const _: () = assert!(
20+
core::mem::size_of::<$name>() == core::mem::size_of::<core::ffi::$name>()
21+
);
22+
)*}
23+
}
24+
25+
alias! {
26+
// `core::ffi::c_char` is either `i8` or `u8` depending on architecture. In the kernel, we use
27+
// `-funsigned-char` so it's always mapped to `u8`.
28+
c_char = u8;
29+
30+
c_schar = i8;
31+
c_uchar = u8;
32+
33+
c_short = i16;
34+
c_ushort = u16;
35+
36+
c_int = i32;
37+
c_uint = u32;
38+
39+
// In the kernel, `intptr_t` is defined to be `long` in all platforms, so we can map the type to
40+
// `isize`.
41+
c_long = isize;
42+
c_ulong = usize;
43+
44+
c_longlong = i64;
45+
c_ulonglong = u64;
46+
}
47+
48+
pub use core::ffi::c_void;

rust/kernel/alloc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ pub mod flags {
123123
/// [`Allocator`] is designed to be implemented as a ZST; [`Allocator`] functions do not operate on
124124
/// an object instance.
125125
///
126-
/// In order to be able to support `#[derive(SmartPointer)]` later on, we need to avoid a design
126+
/// In order to be able to support `#[derive(CoercePointee)]` later on, we need to avoid a design
127127
/// that requires an `Allocator` to be instantiated, hence its functions must not contain any kind
128128
/// of `self` parameter.
129129
///

rust/kernel/alloc/kbox.rs

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -354,42 +354,51 @@ where
354354
A: Allocator,
355355
{
356356
type Borrowed<'a> = &'a T;
357+
type BorrowedMut<'a> = &'a mut T;
357358

358-
fn into_foreign(self) -> *const crate::ffi::c_void {
359-
Box::into_raw(self) as _
359+
fn into_foreign(self) -> *mut crate::ffi::c_void {
360+
Box::into_raw(self).cast()
360361
}
361362

362-
unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self {
363+
unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self {
363364
// SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
364365
// call to `Self::into_foreign`.
365-
unsafe { Box::from_raw(ptr as _) }
366+
unsafe { Box::from_raw(ptr.cast()) }
366367
}
367368

368-
unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> &'a T {
369+
unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> &'a T {
369370
// SAFETY: The safety requirements of this method ensure that the object remains alive and
370371
// immutable for the duration of 'a.
371372
unsafe { &*ptr.cast() }
372373
}
374+
375+
unsafe fn borrow_mut<'a>(ptr: *mut crate::ffi::c_void) -> &'a mut T {
376+
let ptr = ptr.cast();
377+
// SAFETY: The safety requirements of this method ensure that the pointer is valid and that
378+
// nothing else will access the value for the duration of 'a.
379+
unsafe { &mut *ptr }
380+
}
373381
}
374382

375383
impl<T: 'static, A> ForeignOwnable for Pin<Box<T, A>>
376384
where
377385
A: Allocator,
378386
{
379387
type Borrowed<'a> = Pin<&'a T>;
388+
type BorrowedMut<'a> = Pin<&'a mut T>;
380389

381-
fn into_foreign(self) -> *const crate::ffi::c_void {
390+
fn into_foreign(self) -> *mut crate::ffi::c_void {
382391
// SAFETY: We are still treating the box as pinned.
383-
Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }) as _
392+
Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }).cast()
384393
}
385394

386-
unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self {
395+
unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self {
387396
// SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
388397
// call to `Self::into_foreign`.
389-
unsafe { Pin::new_unchecked(Box::from_raw(ptr as _)) }
398+
unsafe { Pin::new_unchecked(Box::from_raw(ptr.cast())) }
390399
}
391400

392-
unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> Pin<&'a T> {
401+
unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> Pin<&'a T> {
393402
// SAFETY: The safety requirements for this function ensure that the object is still alive,
394403
// so it is safe to dereference the raw pointer.
395404
// The safety requirements of `from_foreign` also ensure that the object remains alive for
@@ -399,6 +408,18 @@ where
399408
// SAFETY: This pointer originates from a `Pin<Box<T>>`.
400409
unsafe { Pin::new_unchecked(r) }
401410
}
411+
412+
unsafe fn borrow_mut<'a>(ptr: *mut crate::ffi::c_void) -> Pin<&'a mut T> {
413+
let ptr = ptr.cast();
414+
// SAFETY: The safety requirements for this function ensure that the object is still alive,
415+
// so it is safe to dereference the raw pointer.
416+
// The safety requirements of `from_foreign` also ensure that the object remains alive for
417+
// the lifetime of the returned value.
418+
let r = unsafe { &mut *ptr };
419+
420+
// SAFETY: This pointer originates from a `Pin<Box<T>>`.
421+
unsafe { Pin::new_unchecked(r) }
422+
}
402423
}
403424

404425
impl<T, A> Deref for Box<T, A>
@@ -427,13 +448,23 @@ where
427448
}
428449
}
429450

451+
impl<T, A> fmt::Display for Box<T, A>
452+
where
453+
T: ?Sized + fmt::Display,
454+
A: Allocator,
455+
{
456+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
457+
<T as fmt::Display>::fmt(&**self, f)
458+
}
459+
}
460+
430461
impl<T, A> fmt::Debug for Box<T, A>
431462
where
432463
T: ?Sized + fmt::Debug,
433464
A: Allocator,
434465
{
435466
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
436-
fmt::Debug::fmt(&**self, f)
467+
<T as fmt::Debug>::fmt(&**self, f)
437468
}
438469
}
439470

0 commit comments

Comments
 (0)