1
0
mirror of https://github.com/torvalds/linux.git synced 2025-04-12 16:47:42 +00:00

Rust fixes for v6.14 (3rd)

Toolchain and infrastructure:
 
  - Disallow BTF generation with Rust + LTO.
 
  - Improve rust-analyzer support.
 
 'kernel' crate:
 
  - 'init' module: remove 'Zeroable' implementation for a couple types
    that should not have it.
 
  - 'alloc' module: fix macOS failure in host test by satisfying POSIX
    alignment requirement.
 
  - Add missing '\n's to 'pr_*!()' calls.
 
 And a couple other minor cleanups.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEPjU5OPd5QIZ9jqqOGXyLc2htIW0FAmfV7lAACgkQGXyLc2ht
 IW3wSg/+KEb8mYb4F/dazuCw5LlX9kM3g/5j5KsY6ClFuOkPyRkIMiTSAlaPs80u
 eX9qM2BErX5pSsh58pxsC6fIMMf1nuZlq9pr+cGTdyo/tL5jhssJobNFD+/fnIAf
 vTdik2+aOCCZZGJ4kWWHSodF0oPQR7GrpvbvLCR9ngwG1TKn2iwDN/9YDzstt3KA
 e+oQpirw0/Ev8Cm9I2NmD1i7rA00YHLNEif9bvm1MJbA9PLFkW2g9Zxz+698Uu+P
 7dmAQYN8LeiMOPKPadQjw4/n4K6IPIiuDPtxYLF6JL3cg7UD0nd4Uy52MA8xSk9D
 Z+wxVSdqTw+tOGFQTMFMAo65+H3zri7ZCjALybYVYgHdWIyZrAN8OGYpTRYYZgqf
 z4JwYxBiyPWhoNlcu1kIWwtMW/Nbi2e44DpReddzdgPewE9XHYi6EXiiKGrlu2vP
 h8BItBwlqsCwiogGKW4+s3VvZmOijrwXvu1XfjlFQ8NCLc2wxaUkcjgsTb2kTOEI
 YWTVhS0Ggxz1CbEoFnpwLjlE0qku6DCWIFeo0WslUEK/XXYm7H7DUPY9hME5sQ/5
 dQ96A/PDP1eLDM375A7ccN6eUNejzWRYpZnGtT9PvQSNmZ24eSzjvrBaUYD3/qDG
 PzbyuSZFBoysNS312mgoCRKYBqzit+GRqgwiuAez0RiJeJV+b6Y=
 =F4QT
 -----END PGP SIGNATURE-----

Merge tag 'rust-fixes-6.14-3' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux

Pull rust fixes from Miguel Ojeda:
 "Toolchain and infrastructure:

   - Disallow BTF generation with Rust + LTO

   - Improve rust-analyzer support

  'kernel' crate:

   - 'init' module: remove 'Zeroable' implementation for a couple types
     that should not have it

   - 'alloc' module: fix macOS failure in host test by satisfying POSIX
     alignment requirement

   - Add missing '\n's to 'pr_*!()' calls

  And a couple other minor cleanups"

* tag 'rust-fixes-6.14-3' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux:
  scripts: generate_rust_analyzer: add uapi crate
  scripts: generate_rust_analyzer: add missing include_dirs
  scripts: generate_rust_analyzer: add missing macros deps
  rust: Disallow BTF generation with Rust + LTO
  rust: task: fix `SAFETY` comment in `Task::wake_up`
  rust: workqueue: add missing newline to pr_info! examples
  rust: sync: add missing newline in locked_by log example
  rust: init: add missing newline to pr_info! calls
  rust: error: add missing newline to pr_warn! calls
  rust: docs: add missing newline to printing macro examples
  rust: alloc: satisfy POSIX alignment requirement
  rust: init: fix `Zeroable` implementation for `Option<NonNull<T>>` and `Option<KBox<T>>`
  rust: remove leftover mentions of the `alloc` crate
This commit is contained in:
Linus Torvalds 2025-03-15 15:40:42 -10:00
commit cd3a56ac2d
13 changed files with 85 additions and 57 deletions

@ -145,7 +145,7 @@ Rust standard library source
****************************
The Rust standard library source is required because the build system will
cross-compile ``core`` and ``alloc``.
cross-compile ``core``.
If ``rustup`` is being used, run::

@ -97,7 +97,7 @@ operator are also supported as usual, e.g.:
/// ```
/// # use kernel::{spawn_work_item, workqueue};
/// spawn_work_item!(workqueue::system(), || pr_info!("x"))?;
/// spawn_work_item!(workqueue::system(), || pr_info!("x\n"))?;
/// # Ok::<(), Error>(())
/// ```

@ -1973,7 +1973,7 @@ config RUST
depends on !MODVERSIONS || GENDWARFKSYMS
depends on !GCC_PLUGIN_RANDSTRUCT
depends on !RANDSTRUCT
depends on !DEBUG_INFO_BTF || PAHOLE_HAS_LANG_EXCLUDE
depends on !DEBUG_INFO_BTF || (PAHOLE_HAS_LANG_EXCLUDE && !LTO)
depends on !CFI_CLANG || HAVE_CFI_ICALL_NORMALIZE_INTEGERS_RUSTC
select CFI_ICALL_NORMALIZE_INTEGERS if CFI_CLANG
depends on !CALL_PADDING || RUSTC_VERSION >= 108100

@ -62,6 +62,24 @@ unsafe impl Allocator for Cmalloc {
));
}
// ISO C (ISO/IEC 9899:2011) defines `aligned_alloc`:
//
// > The value of alignment shall be a valid alignment supported by the implementation
// [...].
//
// As an example of the "supported by the implementation" requirement, POSIX.1-2001 (IEEE
// 1003.1-2001) defines `posix_memalign`:
//
// > The value of alignment shall be a power of two multiple of sizeof (void *).
//
// and POSIX-based implementations of `aligned_alloc` inherit this requirement. At the time
// of writing, this is known to be the case on macOS (but not in glibc).
//
// Satisfy the stricter requirement to avoid spurious test failures on some platforms.
let min_align = core::mem::size_of::<*const crate::ffi::c_void>();
let layout = layout.align_to(min_align).map_err(|_| AllocError)?;
let layout = layout.pad_to_align();
// SAFETY: Returns either NULL or a pointer to a memory allocation that satisfies or
// exceeds the given size and alignment requirements.
let dst = unsafe { libc_aligned_alloc(layout.align(), layout.size()) } as *mut u8;

@ -107,7 +107,7 @@ impl Error {
} else {
// TODO: Make it a `WARN_ONCE` once available.
crate::pr_warn!(
"attempted to create `Error` with out of range `errno`: {}",
"attempted to create `Error` with out of range `errno`: {}\n",
errno
);
code::EINVAL

@ -259,7 +259,7 @@ pub mod macros;
/// },
/// }));
/// let foo: Pin<&mut Foo> = foo;
/// pr_info!("a: {}", &*foo.a.lock());
/// pr_info!("a: {}\n", &*foo.a.lock());
/// ```
///
/// # Syntax
@ -319,7 +319,7 @@ macro_rules! stack_pin_init {
/// }, GFP_KERNEL)?,
/// }));
/// let foo = foo.unwrap();
/// pr_info!("a: {}", &*foo.a.lock());
/// pr_info!("a: {}\n", &*foo.a.lock());
/// ```
///
/// ```rust,ignore
@ -352,7 +352,7 @@ macro_rules! stack_pin_init {
/// x: 64,
/// }, GFP_KERNEL)?,
/// }));
/// pr_info!("a: {}", &*foo.a.lock());
/// pr_info!("a: {}\n", &*foo.a.lock());
/// # Ok::<_, AllocError>(())
/// ```
///
@ -882,7 +882,7 @@ pub unsafe trait PinInit<T: ?Sized, E = Infallible>: Sized {
///
/// impl Foo {
/// fn setup(self: Pin<&mut Self>) {
/// pr_info!("Setting up foo");
/// pr_info!("Setting up foo\n");
/// }
/// }
///
@ -986,7 +986,7 @@ pub unsafe trait Init<T: ?Sized, E = Infallible>: PinInit<T, E> {
///
/// impl Foo {
/// fn setup(&mut self) {
/// pr_info!("Setting up foo");
/// pr_info!("Setting up foo\n");
/// }
/// }
///
@ -1336,7 +1336,7 @@ impl<T> InPlaceWrite<T> for UniqueArc<MaybeUninit<T>> {
/// #[pinned_drop]
/// impl PinnedDrop for Foo {
/// fn drop(self: Pin<&mut Self>) {
/// pr_info!("Foo is being dropped!");
/// pr_info!("Foo is being dropped!\n");
/// }
/// }
/// ```
@ -1418,17 +1418,14 @@ impl_zeroable! {
// SAFETY: `T: Zeroable` and `UnsafeCell` is `repr(transparent)`.
{<T: ?Sized + Zeroable>} UnsafeCell<T>,
// SAFETY: All zeros is equivalent to `None` (option layout optimization guarantee).
// SAFETY: All zeros is equivalent to `None` (option layout optimization guarantee:
// https://doc.rust-lang.org/stable/std/option/index.html#representation).
Option<NonZeroU8>, Option<NonZeroU16>, Option<NonZeroU32>, Option<NonZeroU64>,
Option<NonZeroU128>, Option<NonZeroUsize>,
Option<NonZeroI8>, Option<NonZeroI16>, Option<NonZeroI32>, Option<NonZeroI64>,
Option<NonZeroI128>, Option<NonZeroIsize>,
// SAFETY: All zeros is equivalent to `None` (option layout optimization guarantee).
//
// In this case we are allowed to use `T: ?Sized`, since all zeros is the `None` variant.
{<T: ?Sized>} Option<NonNull<T>>,
{<T: ?Sized>} Option<KBox<T>>,
{<T>} Option<NonNull<T>>,
{<T>} Option<KBox<T>>,
// SAFETY: `null` pointer is valid.
//

@ -45,7 +45,7 @@
//! #[pinned_drop]
//! impl PinnedDrop for Foo {
//! fn drop(self: Pin<&mut Self>) {
//! pr_info!("{self:p} is getting dropped.");
//! pr_info!("{self:p} is getting dropped.\n");
//! }
//! }
//!
@ -412,7 +412,7 @@
//! #[pinned_drop]
//! impl PinnedDrop for Foo {
//! fn drop(self: Pin<&mut Self>) {
//! pr_info!("{self:p} is getting dropped.");
//! pr_info!("{self:p} is getting dropped.\n");
//! }
//! }
//! ```
@ -423,7 +423,7 @@
//! // `unsafe`, full path and the token parameter are added, everything else stays the same.
//! unsafe impl ::kernel::init::PinnedDrop for Foo {
//! fn drop(self: Pin<&mut Self>, _: ::kernel::init::__internal::OnlyCallFromDrop) {
//! pr_info!("{self:p} is getting dropped.");
//! pr_info!("{self:p} is getting dropped.\n");
//! }
//! }
//! ```

@ -6,7 +6,7 @@
//! usage by Rust code in the kernel and is shared by all of them.
//!
//! In other words, all the rest of the Rust code in the kernel (e.g. kernel
//! modules written in Rust) depends on [`core`], [`alloc`] and this crate.
//! modules written in Rust) depends on [`core`] and this crate.
//!
//! If you need a kernel C API that is not ported or wrapped yet here, then
//! do so first instead of bypassing this crate.

@ -55,7 +55,7 @@ use core::{cell::UnsafeCell, mem::size_of, ptr};
/// fn print_bytes_used(dir: &Directory, file: &File) {
/// let guard = dir.inner.lock();
/// let inner_file = file.inner.access(&guard);
/// pr_info!("{} {}", guard.bytes_used, inner_file.bytes_used);
/// pr_info!("{} {}\n", guard.bytes_used, inner_file.bytes_used);
/// }
///
/// /// Increments `bytes_used` for both the directory and file.

@ -320,7 +320,7 @@ impl Task {
/// Wakes up the task.
pub fn wake_up(&self) {
// SAFETY: It's always safe to call `signal_pending` on a valid task, even if the task
// SAFETY: It's always safe to call `wake_up_process` on a valid task, even if the task
// running.
unsafe { bindings::wake_up_process(self.as_ptr()) };
}

@ -60,7 +60,7 @@
//! type Pointer = Arc<MyStruct>;
//!
//! fn run(this: Arc<MyStruct>) {
//! pr_info!("The value is: {}", this.value);
//! pr_info!("The value is: {}\n", this.value);
//! }
//! }
//!
@ -108,7 +108,7 @@
//! type Pointer = Arc<MyStruct>;
//!
//! fn run(this: Arc<MyStruct>) {
//! pr_info!("The value is: {}", this.value_1);
//! pr_info!("The value is: {}\n", this.value_1);
//! }
//! }
//!
@ -116,7 +116,7 @@
//! type Pointer = Arc<MyStruct>;
//!
//! fn run(this: Arc<MyStruct>) {
//! pr_info!("The second value is: {}", this.value_2);
//! pr_info!("The second value is: {}\n", this.value_2);
//! }
//! }
//!

@ -57,14 +57,26 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs):
crates_indexes[display_name] = len(crates)
crates.append(crate)
# First, the ones in `rust/` since they are a bit special.
append_crate(
"core",
sysroot_src / "core" / "src" / "lib.rs",
[],
cfg=crates_cfgs.get("core", []),
is_workspace_member=False,
)
def append_sysroot_crate(
display_name,
deps,
cfg=[],
):
append_crate(
display_name,
sysroot_src / display_name / "src" / "lib.rs",
deps,
cfg,
is_workspace_member=False,
)
# NB: sysroot crates reexport items from one another so setting up our transitive dependencies
# here is important for ensuring that rust-analyzer can resolve symbols. The sources of truth
# for this dependency graph are `(sysroot_src / crate / "Cargo.toml" for crate in crates)`.
append_sysroot_crate("core", [], cfg=crates_cfgs.get("core", []))
append_sysroot_crate("alloc", ["core"])
append_sysroot_crate("std", ["alloc", "core"])
append_sysroot_crate("proc_macro", ["core", "std"])
append_crate(
"compiler_builtins",
@ -75,7 +87,7 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs):
append_crate(
"macros",
srctree / "rust" / "macros" / "lib.rs",
[],
["std", "proc_macro"],
is_proc_macro=True,
)
@ -85,27 +97,28 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs):
["core", "compiler_builtins"],
)
append_crate(
"bindings",
srctree / "rust"/ "bindings" / "lib.rs",
["core"],
cfg=cfg,
)
crates[-1]["env"]["OBJTREE"] = str(objtree.resolve(True))
def append_crate_with_generated(
display_name,
deps,
):
append_crate(
display_name,
srctree / "rust"/ display_name / "lib.rs",
deps,
cfg=cfg,
)
crates[-1]["env"]["OBJTREE"] = str(objtree.resolve(True))
crates[-1]["source"] = {
"include_dirs": [
str(srctree / "rust" / display_name),
str(objtree / "rust")
],
"exclude_dirs": [],
}
append_crate(
"kernel",
srctree / "rust" / "kernel" / "lib.rs",
["core", "macros", "build_error", "bindings"],
cfg=cfg,
)
crates[-1]["source"] = {
"include_dirs": [
str(srctree / "rust" / "kernel"),
str(objtree / "rust")
],
"exclude_dirs": [],
}
append_crate_with_generated("bindings", ["core"])
append_crate_with_generated("uapi", ["core"])
append_crate_with_generated("kernel", ["core", "macros", "build_error", "bindings", "uapi"])
def is_root_crate(build_file, target):
try:

@ -15,8 +15,8 @@
//! - Test code should be able to define functions and call them, without having to carry
//! the context.
//!
//! - Later on, we may want to be able to test non-kernel code (e.g. `core`, `alloc` or
//! third-party crates) which likely use the standard library `assert*!` macros.
//! - Later on, we may want to be able to test non-kernel code (e.g. `core` or third-party
//! crates) which likely use the standard library `assert*!` macros.
//!
//! For this reason, instead of the passed context, `kunit_get_current_test()` is used instead
//! (i.e. `current->kunit_test`).