From a4e3b76e4d5c265824e686661a79f75df09c4834 Mon Sep 17 00:00:00 2001 From: Anisse Astier Date: Wed, 22 Jan 2025 14:39:52 +0100 Subject: rust: macros: enable use of hyphens in module names Some modules might need naming that contains hyphens "-" to match the auto-probing by name in the platform devices that comes from the device tree. But Rust identifier cannot contain hyphens, so replace them with underscores. Signed-off-by: Anisse Astier Reviewed-by: Alice Ryhl [ Viresh: Replace "-" with '-', minor commit log fix, rename variable and fix line length checkpatch warnings ] Reviewed-by: Benno Lossin Signed-off-by: Viresh Kumar --- rust/macros/module.rs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'rust/macros/module.rs') diff --git a/rust/macros/module.rs b/rust/macros/module.rs index a9418fbc9b44..6ff34096d7ee 100644 --- a/rust/macros/module.rs +++ b/rust/macros/module.rs @@ -185,7 +185,9 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream { let info = ModuleInfo::parse(&mut it); - let mut modinfo = ModInfoBuilder::new(info.name.as_ref()); + // Rust does not allow hyphens in identifiers, use underscore instead. + let ident = info.name.replace('-', "_"); + let mut modinfo = ModInfoBuilder::new(ident.as_ref()); if let Some(author) = info.author { modinfo.emit("author", &author); } @@ -310,14 +312,15 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream { #[doc(hidden)] #[link_section = \"{initcall_section}\"] #[used] - pub static __{name}_initcall: extern \"C\" fn() -> kernel::ffi::c_int = __{name}_init; + pub static __{ident}_initcall: extern \"C\" fn() -> + kernel::ffi::c_int = __{ident}_init; #[cfg(not(MODULE))] #[cfg(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)] core::arch::global_asm!( r#\".section \"{initcall_section}\", \"a\" - __{name}_initcall: - .long __{name}_init - . + __{ident}_initcall: + .long __{ident}_init - . .previous \"# ); @@ -325,7 +328,7 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream { #[cfg(not(MODULE))] #[doc(hidden)] #[no_mangle] - pub extern \"C\" fn __{name}_init() -> kernel::ffi::c_int {{ + pub extern \"C\" fn __{ident}_init() -> kernel::ffi::c_int {{ // SAFETY: This function is inaccessible to the outside due to the double // module wrapping it. It is called exactly once by the C side via its // placement above in the initcall section. @@ -335,13 +338,13 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream { #[cfg(not(MODULE))] #[doc(hidden)] #[no_mangle] - pub extern \"C\" fn __{name}_exit() {{ + pub extern \"C\" fn __{ident}_exit() {{ // SAFETY: // - This function is inaccessible to the outside due to the double // module wrapping it. It is called exactly once by the C side via its // unique name, - // - furthermore it is only called after `__{name}_init` has returned `0` - // (which delegates to `__init`). + // - furthermore it is only called after `__{ident}_init` has + // returned `0` (which delegates to `__init`). unsafe {{ __exit() }} }} @@ -381,6 +384,7 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream { ", type_ = info.type_, name = info.name, + ident = ident, modinfo = modinfo.buffer, initcall_section = ".initcall6.init" ) -- cgit From 249c3a0e53acefc2b06d3b3e1fc28fb2081f878d Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Sat, 8 Mar 2025 13:45:06 +0900 Subject: rust: module: place cleanup_module() in .exit.text section Place cleanup_module() in .exit.text section. Currently, cleanup_module() is likely placed in the .text section. It's inconsistent with the layout of C modules, where cleanup_module() is placed in .exit.text. [ Boqun asked for an example of how the section changed to be put in the log. Tomonori provided the following examples: C module: $ objdump -t ~/build/x86/drivers/block/loop.o|grep clean 0000000000000000 l O .exit.data 0000000000000008 __UNIQUE_ID___addressable_cleanup_module412 0000000000000000 g F .exit.text 000000000000009c cleanup_module Rust module without this patch: $ objdump -t ~/build/x86/samples/rust/rust_minimal.o|grep clean 00000000000002b0 g F .text 00000000000000c6 cleanup_module 0000000000000000 g O .exit.data 0000000000000008 _R...___UNIQUE_ID___addressable_cleanup_module Rust module with this patch: $ objdump -t ~/build/x86/samples/rust/rust_minimal.o|grep clean 0000000000000000 g F .exit.text 00000000000000c6 cleanup_module 0000000000000000 g O .exit.data 0000000000000008 _R...___UNIQUE_ID___addressable_cleanup_module - Miguel ] Signed-off-by: FUJITA Tomonori Acked-by: Jarkko Sakkinen Link: https://lore.kernel.org/r/20250308044506.14458-1-fujita.tomonori@gmail.com Signed-off-by: Miguel Ojeda --- rust/macros/module.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'rust/macros/module.rs') diff --git a/rust/macros/module.rs b/rust/macros/module.rs index 2f66107847f7..44e5cb108cea 100644 --- a/rust/macros/module.rs +++ b/rust/macros/module.rs @@ -278,6 +278,7 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream { #[cfg(MODULE)] #[doc(hidden)] #[no_mangle] + #[link_section = \".exit.text\"] pub extern \"C\" fn cleanup_module() {{ // SAFETY: // - This function is inaccessible to the outside due to the double -- cgit From de7cd3e4d6387df6a5ae8c4c32ff0479ebe0efb5 Mon Sep 17 00:00:00 2001 From: Igor Korotin Date: Mon, 19 May 2025 17:45:53 +0100 Subject: rust: use absolute paths in macros referencing core and kernel Macros and auto-generated code should use absolute paths, `::core::...` and `::kernel::...`, for core and kernel references. This prevents issues where user-defined modules named `core` or `kernel` could be picked up instead of the `core` or `kernel` crates. Thus clean some references up. Suggested-by: Benno Lossin Closes: https://github.com/Rust-for-Linux/linux/issues/1150 Signed-off-by: Igor Korotin Reviewed-by: Benno Lossin Acked-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20250519164615.3310844-1-igor.korotin.linux@gmail.com [ Applied `rustfmt`. Reworded slightly. - Miguel ] Signed-off-by: Miguel Ojeda --- rust/macros/module.rs | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'rust/macros/module.rs') diff --git a/rust/macros/module.rs b/rust/macros/module.rs index 44e5cb108cea..de9304498a97 100644 --- a/rust/macros/module.rs +++ b/rust/macros/module.rs @@ -215,24 +215,24 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream { // SAFETY: `__this_module` is constructed by the kernel at load time and will not be // freed until the module is unloaded. #[cfg(MODULE)] - static THIS_MODULE: kernel::ThisModule = unsafe {{ + static THIS_MODULE: ::kernel::ThisModule = unsafe {{ extern \"C\" {{ - static __this_module: kernel::types::Opaque; + static __this_module: ::kernel::types::Opaque<::kernel::bindings::module>; }} - kernel::ThisModule::from_ptr(__this_module.get()) + ::kernel::ThisModule::from_ptr(__this_module.get()) }}; #[cfg(not(MODULE))] - static THIS_MODULE: kernel::ThisModule = unsafe {{ - kernel::ThisModule::from_ptr(core::ptr::null_mut()) + static THIS_MODULE: ::kernel::ThisModule = unsafe {{ + ::kernel::ThisModule::from_ptr(::core::ptr::null_mut()) }}; /// The `LocalModule` type is the type of the module created by `module!`, /// `module_pci_driver!`, `module_platform_driver!`, etc. type LocalModule = {type_}; - impl kernel::ModuleMetadata for {type_} {{ - const NAME: &'static kernel::str::CStr = kernel::c_str!(\"{name}\"); + impl ::kernel::ModuleMetadata for {type_} {{ + const NAME: &'static ::kernel::str::CStr = ::kernel::c_str!(\"{name}\"); }} // Double nested modules, since then nobody can access the public items inside. @@ -250,8 +250,8 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream { #[used] static __IS_RUST_MODULE: () = (); - static mut __MOD: core::mem::MaybeUninit<{type_}> = - core::mem::MaybeUninit::uninit(); + static mut __MOD: ::core::mem::MaybeUninit<{type_}> = + ::core::mem::MaybeUninit::uninit(); // Loadable modules need to export the `{{init,cleanup}}_module` identifiers. /// # Safety @@ -262,7 +262,7 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream { #[doc(hidden)] #[no_mangle] #[link_section = \".init.text\"] - pub unsafe extern \"C\" fn init_module() -> kernel::ffi::c_int {{ + pub unsafe extern \"C\" fn init_module() -> ::kernel::ffi::c_int {{ // SAFETY: This function is inaccessible to the outside due to the double // module wrapping it. It is called exactly once by the C side via its // unique name. @@ -302,11 +302,12 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream { #[doc(hidden)] #[link_section = \"{initcall_section}\"] #[used] - pub static __{name}_initcall: extern \"C\" fn() -> kernel::ffi::c_int = __{name}_init; + pub static __{name}_initcall: extern \"C\" fn() -> ::kernel::ffi::c_int = + __{name}_init; #[cfg(not(MODULE))] #[cfg(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)] - core::arch::global_asm!( + ::core::arch::global_asm!( r#\".section \"{initcall_section}\", \"a\" __{name}_initcall: .long __{name}_init - . @@ -317,7 +318,7 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream { #[cfg(not(MODULE))] #[doc(hidden)] #[no_mangle] - pub extern \"C\" fn __{name}_init() -> kernel::ffi::c_int {{ + pub extern \"C\" fn __{name}_init() -> ::kernel::ffi::c_int {{ // SAFETY: This function is inaccessible to the outside due to the double // module wrapping it. It is called exactly once by the C side via its // placement above in the initcall section. @@ -340,9 +341,9 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream { /// # Safety /// /// This function must only be called once. - unsafe fn __init() -> kernel::ffi::c_int {{ + unsafe fn __init() -> ::kernel::ffi::c_int {{ let initer = - <{type_} as kernel::InPlaceModule>::init(&super::super::THIS_MODULE); + <{type_} as ::kernel::InPlaceModule>::init(&super::super::THIS_MODULE); // SAFETY: No data race, since `__MOD` can only be accessed by this module // and there only `__init` and `__exit` access it. These functions are only // called once and `__exit` cannot be called before or during `__init`. -- cgit