Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
a3fe8d8
xattr: make the xattr array itself const
wedsonaf Sep 29, 2023
484ec70
rust: introduce `InPlaceModule`
wedsonaf Sep 29, 2023
da1a2b6
samples: rust: add in-place initialisation sample
wedsonaf Sep 29, 2023
883e433
rust: add the `container_of` macro
wedsonaf Sep 29, 2023
14513c0
rust: init: introduce `Opaque::try_ffi_init`
wedsonaf Sep 29, 2023
c7d0fb2
rust: time: introduce `time` module
wedsonaf Sep 29, 2023
ca4a93c
rust: types: add little-endian type
wedsonaf Sep 29, 2023
a44bdcc
rust: types: introduce `FromBytes` trait
wedsonaf Sep 29, 2023
caf9b29
rust: mem_cache: introduce `MemCache`
wedsonaf Sep 29, 2023
b0bc357
kbuild: rust: allow modules to allocate memory
wedsonaf Sep 29, 2023
528babd
rust: fs: add registration/unregistration of file systems
wedsonaf Sep 29, 2023
e909f43
rust: fs: introduce the `module_fs` macro
wedsonaf Sep 29, 2023
ad07f4b
samples: rust: add initial ro file system sample
wedsonaf Sep 29, 2023
626056a
rust: fs: introduce `FileSystem::super_params`
wedsonaf Sep 29, 2023
a448dc5
rust: fs: introduce `INode<T>`
wedsonaf Sep 29, 2023
b26f77a
rust: fs: introduce `FileSystem::init_root`
wedsonaf Sep 29, 2023
ac0f637
rust: fs: introduce `FileSystem::read_dir`
wedsonaf Sep 29, 2023
14b32d0
rust: fs: introduce `FileSystem::lookup`
wedsonaf Sep 29, 2023
5e601b9
rust: folio: introduce basic support for folios
wedsonaf Sep 29, 2023
c02d2b9
rust: fs: introduce `FileSystem::read_folio`
wedsonaf Sep 29, 2023
ce0acb6
rust: fs: introduce `FileSystem::read_xattr`
wedsonaf Sep 29, 2023
3f94966
rust: fs: introduce `FileSystem::statfs`
wedsonaf Sep 29, 2023
6032d93
rust: fs: introduce more inode types
wedsonaf Sep 29, 2023
1cf6e5e
rust: fs: add per-superblock data
wedsonaf Sep 29, 2023
516d0e4
rust: fs: add basic support for fs buffer heads
wedsonaf Sep 29, 2023
0605dba
rust: fs: allow file systems backed by a block device
wedsonaf Sep 29, 2023
b40e37b
rust: fs: allow per-inode data
wedsonaf Sep 29, 2023
80fda66
rust: fs: export file type from mode constants
wedsonaf Sep 29, 2023
7189177
tarfs: introduce tar fs
wedsonaf Sep 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
rust: introduce InPlaceModule
This allows modules to be initialised in-place in pinned memory, which
enables the usage of pinned types (e.g., mutexes, spinlocks, driver
registrations, etc.) in modules without any extra allocations.

Drivers that don't need this may continue to implement `Module` without
any changes.

Signed-off-by: Wedson Almeida Filho <walmeida@microsoft.com>
  • Loading branch information
wedsonaf committed Oct 18, 2023
commit 484ec70025ff9887d9ca228ec631264039cee355
26 changes: 25 additions & 1 deletion rust/kernel/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#![feature(dispatch_from_dyn)]
#![feature(new_uninit)]
#![feature(receiver_trait)]
#![feature(return_position_impl_trait_in_trait)]
#![feature(unsize)]

// Ensure conditional compilation based on the kernel configuration works;
Expand Down Expand Up @@ -60,7 +61,7 @@ const __LOG_PREFIX: &[u8] = b"rust_kernel\0";
/// The top level entrypoint to implementing a kernel module.
///
/// For any teardown or cleanup operations, your type may implement [`Drop`].
pub trait Module: Sized + Sync {
pub trait Module: Sized + Sync + Send {
/// Called at module initialization time.
///
/// Use this method to perform whatever setup or registration your module
Expand All @@ -70,6 +71,29 @@ pub trait Module: Sized + Sync {
fn init(module: &'static ThisModule) -> error::Result<Self>;
}

/// A module that is pinned and initialised in-place.
pub trait InPlaceModule: Sync + Send {
/// Creates an initialiser for the module.
///
/// It is called when the module is loaded.
fn init(module: &'static ThisModule) -> impl init::PinInit<Self, error::Error>;
}

impl<T: Module> InPlaceModule for T {
fn init(module: &'static ThisModule) -> impl init::PinInit<Self, error::Error> {
let initer = move |slot: *mut Self| {
let m = <Self as Module>::init(module)?;

// SAFETY: `slot` is valid for write per the contract with `pin_init_from_closure`.
unsafe { slot.write(m) };
Ok(())
};

// SAFETY: On success, `initer` always fully initialises an instance of `Self`.
unsafe { init::pin_init_from_closure(initer) }
}
}

/// Equivalent to `THIS_MODULE` in the C API.
///
/// C header: `include/linux/export.h`
Expand Down
18 changes: 6 additions & 12 deletions rust/macros/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {
#[used]
static __IS_RUST_MODULE: () = ();

static mut __MOD: Option<{type_}> = None;
static mut __MOD: core::mem::MaybeUninit<{type_}> = core::mem::MaybeUninit::uninit();

// SAFETY: `__this_module` is constructed by the kernel at load time and will not be
// freed until the module is unloaded.
Expand Down Expand Up @@ -270,23 +270,17 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {
}}

fn __init() -> core::ffi::c_int {{
match <{type_} as kernel::Module>::init(&THIS_MODULE) {{
Ok(m) => {{
unsafe {{
__MOD = Some(m);
}}
return 0;
}}
Err(e) => {{
return e.to_errno();
}}
let initer = <{type_} as kernel::InPlaceModule>::init(&THIS_MODULE);
match unsafe {{ initer.__pinned_init(__MOD.as_mut_ptr()) }} {{
Ok(m) => 0,
Err(e) => e.to_errno(),
}}
}}

fn __exit() {{
unsafe {{
// Invokes `drop()` on `__MOD`, which should be used for cleanup.
__MOD = None;
__MOD.assume_init_drop();
}}
}}

Expand Down
2 changes: 1 addition & 1 deletion scripts/Makefile.build
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ $(obj)/%.lst: $(src)/%.c FORCE
# Compile Rust sources (.rs)
# ---------------------------------------------------------------------------

rust_allowed_features := new_uninit
rust_allowed_features := new_uninit,impl_trait_in_assoc_type

# `--out-dir` is required to avoid temporaries being created by `rustc` in the
# current working directory, which may be not accessible in the out-of-tree
Expand Down