Skip to content

module! improvements #278

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: rust
Choose a base branch
from
8 changes: 4 additions & 4 deletions drivers/android/rust_binder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ use {context::Context, thread::Thread};

module! {
type: BinderModule,
name: b"rust_binder",
author: b"Wedson Almeida Filho",
description: b"Android Binder",
license: b"GPL v2",
name: "rust_binder",
author: "Wedson Almeida Filho",
description: "Android Binder",
license: "GPL v2",
}

enum Either<L, R> {
Expand Down
8 changes: 4 additions & 4 deletions drivers/char/hw_random/bcm2835_rng_rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ use kernel::{c_str, platdev};

module! {
type: RngModule,
name: b"bcm2835_rng_rust",
author: b"Rust for Linux Contributors",
description: b"BCM2835 Random Number Generator (RNG) driver",
license: b"GPL v2",
name: "bcm2835_rng_rust",
author: "Rust for Linux Contributors",
description: "BCM2835 Random Number Generator (RNG) driver",
license: "GPL v2",
}

struct RngModule {
Expand Down
22 changes: 11 additions & 11 deletions rust/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
obj-$(CONFIG_RUST) += core.o compiler_builtins.o helpers.o
extra-$(CONFIG_RUST) += exports_core_generated.h

extra-$(CONFIG_RUST) += libmodule.so
extra-$(CONFIG_RUST) += libmacros.so

extra-$(CONFIG_RUST) += bindings_generated.rs
obj-$(CONFIG_RUST) += alloc.o kernel.o
Expand Down Expand Up @@ -35,21 +35,21 @@ quiet_cmd_rustdoc = RUSTDOC $<
--output $(objtree)/rust/doc --crate-name $(subst rustdoc-,,$@) \
-Fmissing-docs @$(objtree)/include/generated/rustc_cfg $<

rustdoc: rustdoc-module rustdoc-compiler_builtins rustdoc-kernel
rustdoc: rustdoc-macros rustdoc-compiler_builtins rustdoc-kernel

rustdoc-module: private rustdoc_target_flags = --crate-type proc-macro \
rustdoc-macros: private rustdoc_target_flags = --crate-type proc-macro \
--extern proc_macro
rustdoc-module: $(srctree)/rust/module.rs FORCE
rustdoc-macros: $(srctree)/rust/macros/lib.rs FORCE
$(call if_changed,rustdoc_host)

rustdoc-compiler_builtins: $(srctree)/rust/compiler_builtins.rs FORCE
$(call if_changed,rustdoc)

rustdoc-kernel: private rustdoc_target_flags = --extern alloc \
--extern build_error \
--extern module=$(objtree)/rust/libmodule.so
rustdoc-kernel: $(srctree)/rust/kernel/lib.rs rustdoc-module \
$(objtree)/rust/libmodule.so $(objtree)/rust/bindings_generated.rs FORCE
--extern macros=$(objtree)/rust/libmacros.so
rustdoc-kernel: $(srctree)/rust/kernel/lib.rs rustdoc-macros \
$(objtree)/rust/libmacros.so $(objtree)/rust/bindings_generated.rs FORCE
$(call if_changed,rustdoc)

ifdef CONFIG_CC_IS_CLANG
Expand Down Expand Up @@ -126,7 +126,7 @@ quiet_cmd_rustc_procmacro = $(RUSTC_OR_CLIPPY_QUIET) P $@
mv $(objtree)/rust/$(patsubst lib%.so,%,$(notdir $@)).d $(depfile); \
sed -i '/^\#/d' $(depfile)

$(objtree)/rust/libmodule.so: $(srctree)/rust/module.rs FORCE
$(objtree)/rust/libmacros.so: $(srctree)/rust/macros/lib.rs FORCE
$(call if_changed_dep,rustc_procmacro)

quiet_cmd_rustc_library = $(if $(skip_clippy),RUSTC,$(RUSTC_OR_CLIPPY_QUIET)) L $@
Expand Down Expand Up @@ -166,11 +166,11 @@ $(objtree)/rust/build_error.o: $(srctree)/rust/build_error.rs \
$(objtree)/rust/compiler_builtins.o FORCE
$(call if_changed_dep,rustc_library)

# ICE on `--extern module`: https://github.com/rust-lang/rust/issues/56935
# ICE on `--extern macros`: https://github.com/rust-lang/rust/issues/56935
$(objtree)/rust/kernel.o: private rustc_target_flags = --extern alloc \
--extern build_error \
--extern module=$(objtree)/rust/libmodule.so
--extern macros=$(objtree)/rust/libmacros.so
$(objtree)/rust/kernel.o: $(srctree)/rust/kernel/lib.rs $(objtree)/rust/alloc.o \
$(objtree)/rust/build_error.o \
$(objtree)/rust/libmodule.so $(objtree)/rust/bindings_generated.rs FORCE
$(objtree)/rust/libmacros.so $(objtree)/rust/bindings_generated.rs FORCE
$(call if_changed_dep,rustc_library)
4 changes: 2 additions & 2 deletions rust/kernel/module_param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub trait ModuleParam: core::fmt::Display + core::marker::Sized {
/// Get the current value of the parameter for use in the kernel module.
///
/// This function should not be used directly. Instead use the wrapper
/// `read` which will be generated by [`module::module`].
/// `read` which will be generated by [`macros::module`].
fn value(&self) -> &Self::Value;

/// Set the module parameter from a string.
Expand Down Expand Up @@ -428,7 +428,7 @@ impl<T: Copy + core::fmt::Display + ModuleParam, const N: usize> ModuleParam
/// A C-style string parameter.
///
/// The Rust version of the [`charp`] parameter. This type is meant to be
/// used by the [`module::module`] macro, not handled directly. Instead use the
/// used by the [`macros::module`] macro, not handled directly. Instead use the
/// `read` method generated by that macro.
///
/// [`charp`]: ../../../include/linux/moduleparam.h
Expand Down
2 changes: 1 addition & 1 deletion rust/kernel/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub use alloc::{borrow::ToOwned, string::String};

pub use super::build_assert;

pub use module::{module, module_misc_device};
pub use macros::{module, module_misc_device};

pub use super::{pr_alert, pr_cont, pr_crit, pr_emerg, pr_err, pr_info, pr_notice, pr_warn};

Expand Down
127 changes: 127 additions & 0 deletions rust/macros/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
// SPDX-License-Identifier: GPL-2.0

//! Crate for all kernel procedural macros.
mod module;
mod syn;

use proc_macro::TokenStream;

/// Declares a kernel module.
///
/// The `type` argument should be a type which implements the [`KernelModule`]
/// trait. Also accepts various forms of kernel metadata.
///
/// C header: [`include/linux/moduleparam.h`](../../../include/linux/moduleparam.h)
///
/// [`KernelModule`]: ../kernel/trait.KernelModule.html
///
/// # Examples
///
/// ```rust,no_run
/// use kernel::prelude::*;
///
/// module!{
/// type: MyKernelModule,
/// name: "my_kernel_module",
/// author: "Rust for Linux Contributors",
/// description: "My very own kernel module!",
/// license: "GPL v2",
/// params: {
/// my_i32: i32 {
/// default: 42,
/// permissions: 0o000,
/// description: "Example of i32",
/// },
/// writeable_i32: i32 {
/// default: 42,
/// permissions: 0o644,
/// description: "Example of i32",
/// },
/// },
/// }
///
/// struct MyKernelModule;
///
/// impl KernelModule for MyKernelModule {
/// fn init() -> Result<Self> {
/// // If the parameter is writeable, then the kparam lock must be
/// // taken to read the parameter:
/// {
/// let lock = THIS_MODULE.kernel_param_lock();
/// pr_info!("i32 param is: {}\n", writeable_i32.read(&lock));
/// }
/// // If the parameter is read only, it can be read without locking
/// // the kernel parameters:
/// pr_info!("i32 param is: {}\n", my_i32.read());
/// Ok(MyKernelModule)
/// }
/// }
/// ```
///
/// # Supported argument types
/// - `type`: type which implements the [`KernelModule`] trait (required).
/// - `name`: byte array of the name of the kernel module (required).
/// - `author`: byte array of the author of the kernel module.
/// - `description`: byte array of the description of the kernel module.
/// - `license`: byte array of the license of the kernel module (required).
/// - `alias`: byte array of alias name of the kernel module.
/// - `alias_rtnl_link`: byte array of the `rtnl_link_alias` of the kernel module (mutually exclusive with `alias`).
/// - `params`: parameters for the kernel module, as described below.
///
/// # Supported parameter types
///
/// - `bool`: Corresponds to C `bool` param type.
/// - `i8`: No equivalent C param type.
/// - `u8`: Corresponds to C `char` param type.
/// - `i16`: Corresponds to C `short` param type.
/// - `u16`: Corresponds to C `ushort` param type.
/// - `i32`: Corresponds to C `int` param type.
/// - `u32`: Corresponds to C `uint` param type.
/// - `i64`: No equivalent C param type.
/// - `u64`: Corresponds to C `ullong` param type.
/// - `isize`: No equivalent C param type.
/// - `usize`: No equivalent C param type.
/// - `str`: Corresponds to C `charp` param type. Reading returns a byte slice.
/// - `ArrayParam<T,N>`: Corresponds to C parameters created using `module_param_array`. An array
/// of `T`'s of length at **most** `N`.
///
/// `invbool` is unsupported: it was only ever used in a few modules.
/// Consider using a `bool` and inverting the logic instead.
#[proc_macro]
pub fn module(ts: TokenStream) -> TokenStream {
module::module(ts)
}

/// Declares a kernel module that exposes a single misc device.
///
/// The `type` argument should be a type which implements the [`FileOpener`] trait. Also accepts
/// various forms of kernel metadata.
///
/// C header: [`include/linux/moduleparam.h`](../../../include/linux/moduleparam.h)
///
/// [`FileOpener`]: ../kernel/file_operations/trait.FileOpener.html
///
/// # Examples
///
/// ```rust,no_run
/// use kernel::prelude::*;
///
/// module_misc_device! {
/// type: MyFile,
/// name: "my_miscdev_kernel_module",
/// author: "Rust for Linux Contributors",
/// description: "My very own misc device kernel module!",
/// license: "GPL v2",
/// }
///
/// #[derive(Default)]
/// struct MyFile;
///
/// impl kernel::file_operations::FileOperations for MyFile {
/// kernel::declare_file_operations!();
/// }
/// ```
#[proc_macro]
pub fn module_misc_device(ts: TokenStream) -> TokenStream {
module::module_misc_device(ts)
}
Loading