Skip to content

Commit 2c81593

Browse files
committed
Merge tag 'rust-fixes-6.9' of https://github.com/Rust-for-Linux/linux
Pull Rust fixes from Miguel Ojeda: - Soundness: make internal functions generated by the 'module!' macro inaccessible, do not implement 'Zeroable' for 'Infallible' and require 'Send' for the 'Module' trait. - Build: avoid errors with "empty" files and workaround 'rustdoc' ICE. - Kconfig: depend on '!CFI_CLANG' and avoid selecting 'CONSTRUCTORS'. - Code docs: remove non-existing key from 'module!' macro example. - Docs: trivial rendering fix in arch table. * tag 'rust-fixes-6.9' of https://github.com/Rust-for-Linux/linux: rust: remove `params` from `module` macro example kbuild: rust: force `alloc` extern to allow "empty" Rust files kbuild: rust: remove unneeded `@rustc_cfg` to avoid ICE rust: kernel: require `Send` for `Module` implementations rust: phy: implement `Send` for `Registration` rust: make mutually exclusive with CFI_CLANG rust: macros: fix soundness issue in `module!` macro rust: init: remove impl Zeroable for Infallible docs: rust: fix improper rendering in Arch Support page rust: don't select CONSTRUCTORS
2 parents 57865f3 + 1984345 commit 2c81593

File tree

9 files changed

+132
-94
lines changed

9 files changed

+132
-94
lines changed

Documentation/rust/arch-support.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ support corresponds to ``S`` values in the ``MAINTAINERS`` file.
1616
Architecture Level of support Constraints
1717
============= ================ ==============================================
1818
``arm64`` Maintained Little Endian only.
19-
``loongarch`` Maintained -
19+
``loongarch`` Maintained \-
2020
``um`` Maintained ``x86_64`` only.
2121
``x86`` Maintained ``x86_64`` only.
2222
============= ================ ==============================================

init/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1899,11 +1899,11 @@ config RUST
18991899
bool "Rust support"
19001900
depends on HAVE_RUST
19011901
depends on RUST_IS_AVAILABLE
1902+
depends on !CFI_CLANG
19021903
depends on !MODVERSIONS
19031904
depends on !GCC_PLUGINS
19041905
depends on !RANDSTRUCT
19051906
depends on !DEBUG_INFO_BTF || PAHOLE_HAS_LANG_EXCLUDE
1906-
select CONSTRUCTORS
19071907
help
19081908
Enables Rust support in the kernel.
19091909

rust/Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,6 @@ quiet_cmd_rustdoc_test_kernel = RUSTDOC TK $<
175175
mkdir -p $(objtree)/$(obj)/test/doctests/kernel; \
176176
OBJTREE=$(abspath $(objtree)) \
177177
$(RUSTDOC) --test $(rust_flags) \
178-
@$(objtree)/include/generated/rustc_cfg \
179178
-L$(objtree)/$(obj) --extern alloc --extern kernel \
180179
--extern build_error --extern macros \
181180
--extern bindings --extern uapi \

rust/kernel/init.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,8 +1292,15 @@ impl_zeroable! {
12921292
i8, i16, i32, i64, i128, isize,
12931293
f32, f64,
12941294

1295-
// SAFETY: These are ZSTs, there is nothing to zero.
1296-
{<T: ?Sized>} PhantomData<T>, core::marker::PhantomPinned, Infallible, (),
1295+
// Note: do not add uninhabited types (such as `!` or `core::convert::Infallible`) to this list;
1296+
// creating an instance of an uninhabited type is immediate undefined behavior. For more on
1297+
// uninhabited/empty types, consult The Rustonomicon:
1298+
// <https://doc.rust-lang.org/stable/nomicon/exotic-sizes.html#empty-types>. The Rust Reference
1299+
// also has information on undefined behavior:
1300+
// <https://doc.rust-lang.org/stable/reference/behavior-considered-undefined.html>.
1301+
//
1302+
// SAFETY: These are inhabited ZSTs; there is nothing to zero and a valid value exists.
1303+
{<T: ?Sized>} PhantomData<T>, core::marker::PhantomPinned, (),
12971304

12981305
// SAFETY: Type is allowed to take any value, including all zeros.
12991306
{<T>} MaybeUninit<T>,

rust/kernel/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ const __LOG_PREFIX: &[u8] = b"rust_kernel\0";
6565
/// The top level entrypoint to implementing a kernel module.
6666
///
6767
/// For any teardown or cleanup operations, your type may implement [`Drop`].
68-
pub trait Module: Sized + Sync {
68+
pub trait Module: Sized + Sync + Send {
6969
/// Called at module initialization time.
7070
///
7171
/// Use this method to perform whatever setup or registration your module

rust/kernel/net/phy.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,10 @@ pub struct Registration {
640640
drivers: Pin<&'static mut [DriverVTable]>,
641641
}
642642

643+
// SAFETY: The only action allowed in a `Registration` instance is dropping it, which is safe to do
644+
// from any thread because `phy_drivers_unregister` can be called from any thread context.
645+
unsafe impl Send for Registration {}
646+
643647
impl Registration {
644648
/// Registers a PHY driver.
645649
pub fn register(

rust/macros/lib.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,6 @@ use proc_macro::TokenStream;
3535
/// author: "Rust for Linux Contributors",
3636
/// description: "My very own kernel module!",
3737
/// license: "GPL",
38-
/// params: {
39-
/// my_i32: i32 {
40-
/// default: 42,
41-
/// permissions: 0o000,
42-
/// description: "Example of i32",
43-
/// },
44-
/// writeable_i32: i32 {
45-
/// default: 42,
46-
/// permissions: 0o644,
47-
/// description: "Example of i32",
48-
/// },
49-
/// },
5038
/// }
5139
///
5240
/// struct MyModule;

rust/macros/module.rs

Lines changed: 115 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -199,17 +199,6 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {
199199
/// Used by the printing macros, e.g. [`info!`].
200200
const __LOG_PREFIX: &[u8] = b\"{name}\\0\";
201201
202-
/// The \"Rust loadable module\" mark.
203-
//
204-
// This may be best done another way later on, e.g. as a new modinfo
205-
// key or a new section. For the moment, keep it simple.
206-
#[cfg(MODULE)]
207-
#[doc(hidden)]
208-
#[used]
209-
static __IS_RUST_MODULE: () = ();
210-
211-
static mut __MOD: Option<{type_}> = None;
212-
213202
// SAFETY: `__this_module` is constructed by the kernel at load time and will not be
214203
// freed until the module is unloaded.
215204
#[cfg(MODULE)]
@@ -221,81 +210,132 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {
221210
kernel::ThisModule::from_ptr(core::ptr::null_mut())
222211
}};
223212
224-
// Loadable modules need to export the `{{init,cleanup}}_module` identifiers.
225-
/// # Safety
226-
///
227-
/// This function must not be called after module initialization, because it may be
228-
/// freed after that completes.
229-
#[cfg(MODULE)]
230-
#[doc(hidden)]
231-
#[no_mangle]
232-
#[link_section = \".init.text\"]
233-
pub unsafe extern \"C\" fn init_module() -> core::ffi::c_int {{
234-
__init()
235-
}}
236-
237-
#[cfg(MODULE)]
238-
#[doc(hidden)]
239-
#[no_mangle]
240-
pub extern \"C\" fn cleanup_module() {{
241-
__exit()
242-
}}
213+
// Double nested modules, since then nobody can access the public items inside.
214+
mod __module_init {{
215+
mod __module_init {{
216+
use super::super::{type_};
217+
218+
/// The \"Rust loadable module\" mark.
219+
//
220+
// This may be best done another way later on, e.g. as a new modinfo
221+
// key or a new section. For the moment, keep it simple.
222+
#[cfg(MODULE)]
223+
#[doc(hidden)]
224+
#[used]
225+
static __IS_RUST_MODULE: () = ();
226+
227+
static mut __MOD: Option<{type_}> = None;
228+
229+
// Loadable modules need to export the `{{init,cleanup}}_module` identifiers.
230+
/// # Safety
231+
///
232+
/// This function must not be called after module initialization, because it may be
233+
/// freed after that completes.
234+
#[cfg(MODULE)]
235+
#[doc(hidden)]
236+
#[no_mangle]
237+
#[link_section = \".init.text\"]
238+
pub unsafe extern \"C\" fn init_module() -> core::ffi::c_int {{
239+
// SAFETY: This function is inaccessible to the outside due to the double
240+
// module wrapping it. It is called exactly once by the C side via its
241+
// unique name.
242+
unsafe {{ __init() }}
243+
}}
243244
244-
// Built-in modules are initialized through an initcall pointer
245-
// and the identifiers need to be unique.
246-
#[cfg(not(MODULE))]
247-
#[cfg(not(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS))]
248-
#[doc(hidden)]
249-
#[link_section = \"{initcall_section}\"]
250-
#[used]
251-
pub static __{name}_initcall: extern \"C\" fn() -> core::ffi::c_int = __{name}_init;
245+
#[cfg(MODULE)]
246+
#[doc(hidden)]
247+
#[no_mangle]
248+
pub extern \"C\" fn cleanup_module() {{
249+
// SAFETY:
250+
// - This function is inaccessible to the outside due to the double
251+
// module wrapping it. It is called exactly once by the C side via its
252+
// unique name,
253+
// - furthermore it is only called after `init_module` has returned `0`
254+
// (which delegates to `__init`).
255+
unsafe {{ __exit() }}
256+
}}
252257
253-
#[cfg(not(MODULE))]
254-
#[cfg(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)]
255-
core::arch::global_asm!(
256-
r#\".section \"{initcall_section}\", \"a\"
257-
__{name}_initcall:
258-
.long __{name}_init - .
259-
.previous
260-
\"#
261-
);
258+
// Built-in modules are initialized through an initcall pointer
259+
// and the identifiers need to be unique.
260+
#[cfg(not(MODULE))]
261+
#[cfg(not(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS))]
262+
#[doc(hidden)]
263+
#[link_section = \"{initcall_section}\"]
264+
#[used]
265+
pub static __{name}_initcall: extern \"C\" fn() -> core::ffi::c_int = __{name}_init;
266+
267+
#[cfg(not(MODULE))]
268+
#[cfg(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)]
269+
core::arch::global_asm!(
270+
r#\".section \"{initcall_section}\", \"a\"
271+
__{name}_initcall:
272+
.long __{name}_init - .
273+
.previous
274+
\"#
275+
);
276+
277+
#[cfg(not(MODULE))]
278+
#[doc(hidden)]
279+
#[no_mangle]
280+
pub extern \"C\" fn __{name}_init() -> core::ffi::c_int {{
281+
// SAFETY: This function is inaccessible to the outside due to the double
282+
// module wrapping it. It is called exactly once by the C side via its
283+
// placement above in the initcall section.
284+
unsafe {{ __init() }}
285+
}}
262286
263-
#[cfg(not(MODULE))]
264-
#[doc(hidden)]
265-
#[no_mangle]
266-
pub extern \"C\" fn __{name}_init() -> core::ffi::c_int {{
267-
__init()
268-
}}
287+
#[cfg(not(MODULE))]
288+
#[doc(hidden)]
289+
#[no_mangle]
290+
pub extern \"C\" fn __{name}_exit() {{
291+
// SAFETY:
292+
// - This function is inaccessible to the outside due to the double
293+
// module wrapping it. It is called exactly once by the C side via its
294+
// unique name,
295+
// - furthermore it is only called after `__{name}_init` has returned `0`
296+
// (which delegates to `__init`).
297+
unsafe {{ __exit() }}
298+
}}
269299
270-
#[cfg(not(MODULE))]
271-
#[doc(hidden)]
272-
#[no_mangle]
273-
pub extern \"C\" fn __{name}_exit() {{
274-
__exit()
275-
}}
300+
/// # Safety
301+
///
302+
/// This function must only be called once.
303+
unsafe fn __init() -> core::ffi::c_int {{
304+
match <{type_} as kernel::Module>::init(&super::super::THIS_MODULE) {{
305+
Ok(m) => {{
306+
// SAFETY: No data race, since `__MOD` can only be accessed by this
307+
// module and there only `__init` and `__exit` access it. These
308+
// functions are only called once and `__exit` cannot be called
309+
// before or during `__init`.
310+
unsafe {{
311+
__MOD = Some(m);
312+
}}
313+
return 0;
314+
}}
315+
Err(e) => {{
316+
return e.to_errno();
317+
}}
318+
}}
319+
}}
276320
277-
fn __init() -> core::ffi::c_int {{
278-
match <{type_} as kernel::Module>::init(&THIS_MODULE) {{
279-
Ok(m) => {{
321+
/// # Safety
322+
///
323+
/// This function must
324+
/// - only be called once,
325+
/// - be called after `__init` has been called and returned `0`.
326+
unsafe fn __exit() {{
327+
// SAFETY: No data race, since `__MOD` can only be accessed by this module
328+
// and there only `__init` and `__exit` access it. These functions are only
329+
// called once and `__init` was already called.
280330
unsafe {{
281-
__MOD = Some(m);
331+
// Invokes `drop()` on `__MOD`, which should be used for cleanup.
332+
__MOD = None;
282333
}}
283-
return 0;
284-
}}
285-
Err(e) => {{
286-
return e.to_errno();
287334
}}
288-
}}
289-
}}
290335
291-
fn __exit() {{
292-
unsafe {{
293-
// Invokes `drop()` on `__MOD`, which should be used for cleanup.
294-
__MOD = None;
336+
{modinfo}
295337
}}
296338
}}
297-
298-
{modinfo}
299339
",
300340
type_ = info.type_,
301341
name = info.name,

scripts/Makefile.build

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ rust_common_cmd = \
273273
-Zallow-features=$(rust_allowed_features) \
274274
-Zcrate-attr=no_std \
275275
-Zcrate-attr='feature($(rust_allowed_features))' \
276-
--extern alloc --extern kernel \
276+
-Zunstable-options --extern force:alloc --extern kernel \
277277
--crate-type rlib -L $(objtree)/rust/ \
278278
--crate-name $(basename $(notdir $@)) \
279279
--sysroot=/dev/null \

0 commit comments

Comments
 (0)