Skip to content

Commit

Permalink
Merge pull request torvalds#542 from wedsonaf/modules
Browse files Browse the repository at this point in the history
rust: improve `KernelModule` initialisation.
  • Loading branch information
wedsonaf authored Nov 8, 2021
2 parents 38efc40 + b5b86e4 commit 8df76b5
Show file tree
Hide file tree
Showing 15 changed files with 94 additions and 125 deletions.
6 changes: 3 additions & 3 deletions drivers/android/rust_binder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
#![feature(global_asm, try_reserve, allocator_api, concat_idents)]

use kernel::{
c_str,
io_buffer::IoBufferWriter,
linked_list::{GetLinks, GetLinksWrapped, Links},
miscdev::Registration,
prelude::*,
str::CStr,
sync::Ref,
user_ptr::UserSlicePtrWriter,
};
Expand Down Expand Up @@ -106,9 +106,9 @@ struct BinderModule {
}

impl KernelModule for BinderModule {
fn init() -> Result<Self> {
fn init(name: &'static CStr, _module: &'static kernel::ThisModule) -> Result<Self> {
let ctx = Context::new()?;
let reg = Registration::new_pinned::<process::Process>(c_str!("rust_binder"), None, ctx)?;
let reg = Registration::new_pinned::<process::Process>(name, None, ctx)?;
Ok(Self { _reg: reg })
}
}
12 changes: 5 additions & 7 deletions drivers/char/hw_random/bcm2835_rng_rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ use kernel::{
of::ConstOfMatchTable,
platdev::PlatformDriver,
prelude::*,
{c_str, platdev},
str::CStr,
ThisModule, {c_str, platdev},
};

module! {
Expand Down Expand Up @@ -69,15 +70,12 @@ struct RngModule {
}

impl KernelModule for RngModule {
fn init() -> Result<Self> {
fn init(name: &'static CStr, module: &'static ThisModule) -> Result<Self> {
const OF_MATCH_TBL: ConstOfMatchTable<1> =
ConstOfMatchTable::new_const([c_str!("brcm,bcm2835-rng")]);

let pdev = platdev::Registration::new_pinned::<RngDriver>(
c_str!("bcm2835-rng-rust"),
Some(&OF_MATCH_TBL),
&THIS_MODULE,
)?;
let pdev =
platdev::Registration::new_pinned::<RngDriver>(name, Some(&OF_MATCH_TBL), module)?;

Ok(RngModule { _pdev: pdev })
}
Expand Down
2 changes: 1 addition & 1 deletion rust/kernel/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ pub trait KernelModule: Sized + Sync {
/// should do.
///
/// Equivalent to the `module_init` macro in the C API.
fn init() -> Result<Self>;
fn init(name: &'static str::CStr, module: &'static ThisModule) -> Result<Self>;
}

/// Equivalent to `THIS_MODULE` in the C API.
Expand Down
59 changes: 57 additions & 2 deletions rust/kernel/miscdev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
use crate::bindings;
use crate::error::{Error, Result};
use crate::file_operations::{FileOpenAdapter, FileOpener, FileOperationsVtable};
use crate::str::CStr;
use crate::{str::CStr, KernelModule, ThisModule};
use alloc::boxed::Box;
use core::marker::PhantomPinned;
use core::marker::{PhantomData, PhantomPinned};
use core::pin::Pin;

/// A registration of a miscellaneous device.
Expand Down Expand Up @@ -109,3 +109,58 @@ impl<T: Sync> Drop for Registration<T> {
}
}
}

/// Kernel module that exposes a single miscdev device implemented by `F`.
pub struct Module<F: FileOpener<()>> {
_dev: Pin<Box<Registration>>,
_p: PhantomData<F>,
}

impl<F: FileOpener<()>> KernelModule for Module<F> {
fn init(name: &'static CStr, _module: &'static ThisModule) -> Result<Self> {
Ok(Self {
_p: PhantomData,
_dev: Registration::new_pinned::<F>(name, None, ())?,
})
}
}

/// 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
///
/// ```ignore
/// use kernel::prelude::*;
///
/// module_misc_device! {
/// type: MyFile,
/// name: b"my_miscdev_kernel_module",
/// author: b"Rust for Linux Contributors",
/// description: b"My very own misc device kernel module!",
/// license: b"GPL v2",
/// }
///
/// #[derive(Default)]
/// struct MyFile;
///
/// impl kernel::file_operations::FileOperations for MyFile {
/// kernel::declare_file_operations!();
/// }
/// ```
#[macro_export]
macro_rules! module_misc_device {
(type: $type:ty, $($f:tt)*) => {
type ModuleType = kernel::miscdev::Module<$type>;
module! {
type: ModuleType,
$($f)*
}
}
}
4 changes: 3 additions & 1 deletion rust/kernel/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ pub use core::pin::Pin;

pub use alloc::{boxed::Box, string::String, vec::Vec};

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

pub use super::build_assert;

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

pub use super::module_misc_device;

pub use super::static_assert;

pub use super::{Error, KernelModule, Result};
34 changes: 0 additions & 34 deletions rust/macros/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,37 +92,3 @@ use proc_macro::TokenStream;
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
///
/// ```ignore
/// use kernel::prelude::*;
///
/// module_misc_device! {
/// type: MyFile,
/// name: b"my_miscdev_kernel_module",
/// author: b"Rust for Linux Contributors",
/// description: b"My very own misc device kernel module!",
/// license: b"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)
}
58 changes: 1 addition & 57 deletions rust/macros/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ pub fn module(ts: TokenStream) -> TokenStream {
}}
fn __init() -> kernel::c_types::c_int {{
match <{type_} as kernel::KernelModule>::init() {{
match <{type_} as kernel::KernelModule>::init(kernel::c_str!(\"{name}\"), &THIS_MODULE) {{
Ok(m) => {{
unsafe {{
__MOD = Some(m);
Expand Down Expand Up @@ -592,62 +592,6 @@ pub fn module(ts: TokenStream) -> TokenStream {
).parse().expect("Error parsing formatted string into token stream.")
}

pub fn module_misc_device(ts: TokenStream) -> TokenStream {
let mut it = ts.into_iter();

let info = ModuleInfo::parse(&mut it);

let module = format!("__internal_ModuleFor{}", info.type_);

format!(
"
#[doc(hidden)]
struct {module} {{
_dev: core::pin::Pin<alloc::boxed::Box<kernel::miscdev::Registration>>,
}}
impl kernel::KernelModule for {module} {{
fn init() -> kernel::Result<Self> {{
Ok(Self {{
_dev: kernel::miscdev::Registration::new_pinned::<{type_}>(
kernel::c_str!(\"{name}\"),
None,
(),
)?,
}})
}}
}}
kernel::prelude::module! {{
type: {module},
name: b\"{name}\",
{author}
{description}
license: b\"{license}\",
{alias}
}}
",
module = module,
type_ = info.type_,
name = info.name,
author = info
.author
.map(|v| format!("author: b\"{}\",", v))
.unwrap_or_else(|| "".to_string()),
description = info
.description
.map(|v| format!("description: b\"{}\",", v))
.unwrap_or_else(|| "".to_string()),
alias = info
.alias
.map(|v| format!("alias: b\"{}\",", v))
.unwrap_or_else(|| "".to_string()),
license = info.license
)
.parse()
.expect("Error parsing formatted string into token stream.")
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
7 changes: 3 additions & 4 deletions samples/rust/rust_chrdev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#![feature(allocator_api, global_asm)]

use kernel::prelude::*;
use kernel::{c_str, chrdev, file_operations::FileOperations};
use kernel::{chrdev, file_operations::FileOperations, str::CStr, ThisModule};

module! {
type: RustChrdev,
Expand All @@ -28,11 +28,10 @@ struct RustChrdev {
}

impl KernelModule for RustChrdev {
fn init() -> Result<Self> {
fn init(name: &'static CStr, module: &'static ThisModule) -> Result<Self> {
pr_info!("Rust character device sample (init)\n");

let mut chrdev_reg =
chrdev::Registration::new_pinned(c_str!("rust_chrdev"), 0, &THIS_MODULE)?;
let mut chrdev_reg = chrdev::Registration::new_pinned(name, 0, module)?;

// Register the same kind of device twice, we're just demonstrating
// that you can use multiple minors. There are two minors in this case
Expand Down
4 changes: 2 additions & 2 deletions samples/rust/rust_minimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#![no_std]
#![feature(allocator_api, global_asm)]

use kernel::prelude::*;
use kernel::{prelude::*, str::CStr, ThisModule};

module! {
type: RustMinimal,
Expand All @@ -20,7 +20,7 @@ struct RustMinimal {
}

impl KernelModule for RustMinimal {
fn init() -> Result<Self> {
fn init(_name: &'static CStr, _module: &'static ThisModule) -> Result<Self> {
pr_info!("Rust minimal sample (init)\n");
pr_info!("Am I built-in? {}\n", !cfg!(MODULE));

Expand Down
7 changes: 4 additions & 3 deletions samples/rust/rust_miscdev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@

use kernel::prelude::*;
use kernel::{
c_str,
file::File,
file_operations::{FileOpener, FileOperations},
io_buffer::{IoBufferReader, IoBufferWriter},
miscdev,
str::CStr,
sync::{CondVar, Mutex, Ref},
ThisModule,
};

module! {
Expand Down Expand Up @@ -132,13 +133,13 @@ struct RustMiscdev {
}

impl KernelModule for RustMiscdev {
fn init() -> Result<Self> {
fn init(name: &'static CStr, _module: &'static ThisModule) -> Result<Self> {
pr_info!("Rust miscellaneous device sample (init)\n");

let state = SharedState::try_new()?;

Ok(RustMiscdev {
_dev: miscdev::Registration::new_pinned::<Token>(c_str!("rust_miscdev"), None, state)?,
_dev: miscdev::Registration::new_pinned::<Token>(name, None, state)?,
})
}
}
Expand Down
6 changes: 3 additions & 3 deletions samples/rust/rust_module_parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#![no_std]
#![feature(allocator_api, global_asm)]

use kernel::prelude::*;
use kernel::{prelude::*, str::CStr, ThisModule};

module! {
type: RustModuleParameters,
Expand Down Expand Up @@ -45,11 +45,11 @@ module! {
struct RustModuleParameters;

impl KernelModule for RustModuleParameters {
fn init() -> Result<Self> {
fn init(_name: &'static CStr, module: &'static ThisModule) -> Result<Self> {
pr_info!("Rust module parameters sample (init)\n");

{
let lock = THIS_MODULE.kernel_param_lock();
let lock = module.kernel_param_lock();
pr_info!("Parameters:\n");
pr_info!(" my_bool: {}\n", my_bool.read());
pr_info!(" my_i32: {}\n", my_i32.read(&lock));
Expand Down
4 changes: 2 additions & 2 deletions samples/rust/rust_print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
#![no_std]
#![feature(allocator_api, global_asm)]

use kernel::pr_cont;
use kernel::prelude::*;
use kernel::{pr_cont, str::CStr, ThisModule};

module! {
type: RustPrint,
Expand All @@ -19,7 +19,7 @@ module! {
struct RustPrint;

impl KernelModule for RustPrint {
fn init() -> Result<Self> {
fn init(_name: &'static CStr, _module: &'static ThisModule) -> Result<Self> {
pr_info!("Rust printing macros sample (init)\n");

pr_emerg!("Emergency message (level 0) without args\n");
Expand Down
Loading

0 comments on commit 8df76b5

Please sign in to comment.