186f7dacaSBenno Lossin // SPDX-License-Identifier: GPL-2.0 286f7dacaSBenno Lossin 386f7dacaSBenno Lossin //! Extensions to the [`pin-init`] crate. 486f7dacaSBenno Lossin //! 586f7dacaSBenno Lossin //! Most `struct`s from the [`sync`] module need to be pinned, because they contain self-referential 686f7dacaSBenno Lossin //! `struct`s from C. [Pinning][pinning] is Rust's way of ensuring data does not move. 786f7dacaSBenno Lossin //! 886f7dacaSBenno Lossin //! The [`pin-init`] crate is the way such structs are initialized on the Rust side. Please refer 986f7dacaSBenno Lossin //! to its documentation to better understand how to use it. Additionally, there are many examples 1086f7dacaSBenno Lossin //! throughout the kernel, such as the types from the [`sync`] module. And the ones presented 1186f7dacaSBenno Lossin //! below. 1286f7dacaSBenno Lossin //! 1386f7dacaSBenno Lossin //! [`sync`]: crate::sync 1486f7dacaSBenno Lossin //! [pinning]: https://doc.rust-lang.org/std/pin/index.html 1586f7dacaSBenno Lossin //! [`pin-init`]: https://rust.docs.kernel.org/pin_init/ 1686f7dacaSBenno Lossin //! 1786f7dacaSBenno Lossin //! # [`Opaque<T>`] 1886f7dacaSBenno Lossin //! 1986f7dacaSBenno Lossin //! For the special case where initializing a field is a single FFI-function call that cannot fail, 2086f7dacaSBenno Lossin //! there exist the helper function [`Opaque::ffi_init`]. This function initialize a single 2186f7dacaSBenno Lossin //! [`Opaque<T>`] field by just delegating to the supplied closure. You can use these in 2286f7dacaSBenno Lossin //! combination with [`pin_init!`]. 2386f7dacaSBenno Lossin //! 2486f7dacaSBenno Lossin //! [`Opaque<T>`]: crate::types::Opaque 2586f7dacaSBenno Lossin //! [`Opaque::ffi_init`]: crate::types::Opaque::ffi_init 26*dbd5058bSBenno Lossin //! [`pin_init!`]: pin_init::pin_init 2786f7dacaSBenno Lossin //! 2886f7dacaSBenno Lossin //! # Examples 2986f7dacaSBenno Lossin //! 3086f7dacaSBenno Lossin //! ## General Examples 3186f7dacaSBenno Lossin //! 3286f7dacaSBenno Lossin //! ```rust,ignore 3386f7dacaSBenno Lossin //! # #![allow(clippy::disallowed_names)] 3486f7dacaSBenno Lossin //! use kernel::types::Opaque; 3586f7dacaSBenno Lossin //! use pin_init::pin_init_from_closure; 3686f7dacaSBenno Lossin //! 3786f7dacaSBenno Lossin //! // assume we have some `raw_foo` type in C: 3886f7dacaSBenno Lossin //! #[repr(C)] 3986f7dacaSBenno Lossin //! struct RawFoo([u8; 16]); 4086f7dacaSBenno Lossin //! extern { 4186f7dacaSBenno Lossin //! fn init_foo(_: *mut RawFoo); 4286f7dacaSBenno Lossin //! } 4386f7dacaSBenno Lossin //! 4486f7dacaSBenno Lossin //! #[pin_data] 4586f7dacaSBenno Lossin //! struct Foo { 4686f7dacaSBenno Lossin //! #[pin] 4786f7dacaSBenno Lossin //! raw: Opaque<RawFoo>, 4886f7dacaSBenno Lossin //! } 4986f7dacaSBenno Lossin //! 5086f7dacaSBenno Lossin //! impl Foo { 5186f7dacaSBenno Lossin //! fn setup(self: Pin<&mut Self>) { 5286f7dacaSBenno Lossin //! pr_info!("Setting up foo\n"); 5386f7dacaSBenno Lossin //! } 5486f7dacaSBenno Lossin //! } 5586f7dacaSBenno Lossin //! 5686f7dacaSBenno Lossin //! let foo = pin_init!(Foo { 5786f7dacaSBenno Lossin //! raw <- unsafe { 5886f7dacaSBenno Lossin //! Opaque::ffi_init(|s| { 5986f7dacaSBenno Lossin //! // note that this cannot fail. 6086f7dacaSBenno Lossin //! init_foo(s); 6186f7dacaSBenno Lossin //! }) 6286f7dacaSBenno Lossin //! }, 6386f7dacaSBenno Lossin //! }).pin_chain(|foo| { 6486f7dacaSBenno Lossin //! foo.setup(); 6586f7dacaSBenno Lossin //! Ok(()) 6686f7dacaSBenno Lossin //! }); 6786f7dacaSBenno Lossin //! ``` 6886f7dacaSBenno Lossin //! 6986f7dacaSBenno Lossin //! ```rust,ignore 7086f7dacaSBenno Lossin //! # #![allow(unreachable_pub, clippy::disallowed_names)] 7186f7dacaSBenno Lossin //! use kernel::{prelude::*, types::Opaque}; 7286f7dacaSBenno Lossin //! use core::{ptr::addr_of_mut, marker::PhantomPinned, pin::Pin}; 7386f7dacaSBenno Lossin //! # mod bindings { 7486f7dacaSBenno Lossin //! # #![allow(non_camel_case_types)] 7586f7dacaSBenno Lossin //! # pub struct foo; 7686f7dacaSBenno Lossin //! # pub unsafe fn init_foo(_ptr: *mut foo) {} 7786f7dacaSBenno Lossin //! # pub unsafe fn destroy_foo(_ptr: *mut foo) {} 7886f7dacaSBenno Lossin //! # pub unsafe fn enable_foo(_ptr: *mut foo, _flags: u32) -> i32 { 0 } 7986f7dacaSBenno Lossin //! # } 8086f7dacaSBenno Lossin //! # // `Error::from_errno` is `pub(crate)` in the `kernel` crate, thus provide a workaround. 8186f7dacaSBenno Lossin //! # trait FromErrno { 8286f7dacaSBenno Lossin //! # fn from_errno(errno: core::ffi::c_int) -> Error { 8386f7dacaSBenno Lossin //! # // Dummy error that can be constructed outside the `kernel` crate. 8486f7dacaSBenno Lossin //! # Error::from(core::fmt::Error) 8586f7dacaSBenno Lossin //! # } 8686f7dacaSBenno Lossin //! # } 8786f7dacaSBenno Lossin //! # impl FromErrno for Error {} 8886f7dacaSBenno Lossin //! /// # Invariants 8986f7dacaSBenno Lossin //! /// 9086f7dacaSBenno Lossin //! /// `foo` is always initialized 9186f7dacaSBenno Lossin //! #[pin_data(PinnedDrop)] 9286f7dacaSBenno Lossin //! pub struct RawFoo { 9386f7dacaSBenno Lossin //! #[pin] 9486f7dacaSBenno Lossin //! foo: Opaque<bindings::foo>, 9586f7dacaSBenno Lossin //! #[pin] 9686f7dacaSBenno Lossin //! _p: PhantomPinned, 9786f7dacaSBenno Lossin //! } 9886f7dacaSBenno Lossin //! 9986f7dacaSBenno Lossin //! impl RawFoo { 10086f7dacaSBenno Lossin //! pub fn new(flags: u32) -> impl PinInit<Self, Error> { 10186f7dacaSBenno Lossin //! // SAFETY: 10286f7dacaSBenno Lossin //! // - when the closure returns `Ok(())`, then it has successfully initialized and 10386f7dacaSBenno Lossin //! // enabled `foo`, 10486f7dacaSBenno Lossin //! // - when it returns `Err(e)`, then it has cleaned up before 10586f7dacaSBenno Lossin //! unsafe { 10686f7dacaSBenno Lossin //! pin_init::pin_init_from_closure(move |slot: *mut Self| { 10786f7dacaSBenno Lossin //! // `slot` contains uninit memory, avoid creating a reference. 10886f7dacaSBenno Lossin //! let foo = addr_of_mut!((*slot).foo); 10986f7dacaSBenno Lossin //! 11086f7dacaSBenno Lossin //! // Initialize the `foo` 11186f7dacaSBenno Lossin //! bindings::init_foo(Opaque::raw_get(foo)); 11286f7dacaSBenno Lossin //! 11386f7dacaSBenno Lossin //! // Try to enable it. 11486f7dacaSBenno Lossin //! let err = bindings::enable_foo(Opaque::raw_get(foo), flags); 11586f7dacaSBenno Lossin //! if err != 0 { 11686f7dacaSBenno Lossin //! // Enabling has failed, first clean up the foo and then return the error. 11786f7dacaSBenno Lossin //! bindings::destroy_foo(Opaque::raw_get(foo)); 11886f7dacaSBenno Lossin //! return Err(Error::from_errno(err)); 11986f7dacaSBenno Lossin //! } 12086f7dacaSBenno Lossin //! 12186f7dacaSBenno Lossin //! // All fields of `RawFoo` have been initialized, since `_p` is a ZST. 12286f7dacaSBenno Lossin //! Ok(()) 12386f7dacaSBenno Lossin //! }) 12486f7dacaSBenno Lossin //! } 12586f7dacaSBenno Lossin //! } 12686f7dacaSBenno Lossin //! } 12786f7dacaSBenno Lossin //! 12886f7dacaSBenno Lossin //! #[pinned_drop] 12986f7dacaSBenno Lossin //! impl PinnedDrop for RawFoo { 13086f7dacaSBenno Lossin //! fn drop(self: Pin<&mut Self>) { 13186f7dacaSBenno Lossin //! // SAFETY: Since `foo` is initialized, destroying is safe. 13286f7dacaSBenno Lossin //! unsafe { bindings::destroy_foo(self.foo.get()) }; 13386f7dacaSBenno Lossin //! } 13486f7dacaSBenno Lossin //! } 13586f7dacaSBenno Lossin //! ``` 136578eb8b6SBenno Lossin 137114ca41fSBenno Lossin use crate::{ 138114ca41fSBenno Lossin alloc::{AllocError, Flags}, 139114ca41fSBenno Lossin error::{self, Error}, 140114ca41fSBenno Lossin }; 141*dbd5058bSBenno Lossin use pin_init::{init_from_closure, pin_init_from_closure, Init, PinInit}; 142114ca41fSBenno Lossin 143114ca41fSBenno Lossin /// Smart pointer that can initialize memory in-place. 144114ca41fSBenno Lossin pub trait InPlaceInit<T>: Sized { 145114ca41fSBenno Lossin /// Pinned version of `Self`. 146114ca41fSBenno Lossin /// 147114ca41fSBenno Lossin /// If a type already implicitly pins its pointee, `Pin<Self>` is unnecessary. In this case use 148114ca41fSBenno Lossin /// `Self`, otherwise just use `Pin<Self>`. 149114ca41fSBenno Lossin type PinnedSelf; 150114ca41fSBenno Lossin 151114ca41fSBenno Lossin /// Use the given pin-initializer to pin-initialize a `T` inside of a new smart pointer of this 152114ca41fSBenno Lossin /// type. 153114ca41fSBenno Lossin /// 154114ca41fSBenno Lossin /// If `T: !Unpin` it will not be able to move afterwards. try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Self::PinnedSelf, E> where E: From<AllocError>155114ca41fSBenno Lossin fn try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Self::PinnedSelf, E> 156114ca41fSBenno Lossin where 157114ca41fSBenno Lossin E: From<AllocError>; 158114ca41fSBenno Lossin 159114ca41fSBenno Lossin /// Use the given pin-initializer to pin-initialize a `T` inside of a new smart pointer of this 160114ca41fSBenno Lossin /// type. 161114ca41fSBenno Lossin /// 162114ca41fSBenno Lossin /// If `T: !Unpin` it will not be able to move afterwards. pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> error::Result<Self::PinnedSelf> where Error: From<E>,163114ca41fSBenno Lossin fn pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> error::Result<Self::PinnedSelf> 164114ca41fSBenno Lossin where 165114ca41fSBenno Lossin Error: From<E>, 166114ca41fSBenno Lossin { 167114ca41fSBenno Lossin // SAFETY: We delegate to `init` and only change the error type. 168114ca41fSBenno Lossin let init = unsafe { 169114ca41fSBenno Lossin pin_init_from_closure(|slot| init.__pinned_init(slot).map_err(|e| Error::from(e))) 170114ca41fSBenno Lossin }; 171114ca41fSBenno Lossin Self::try_pin_init(init, flags) 172114ca41fSBenno Lossin } 173114ca41fSBenno Lossin 174114ca41fSBenno Lossin /// Use the given initializer to in-place initialize a `T`. try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E> where E: From<AllocError>175114ca41fSBenno Lossin fn try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E> 176114ca41fSBenno Lossin where 177114ca41fSBenno Lossin E: From<AllocError>; 178114ca41fSBenno Lossin 179114ca41fSBenno Lossin /// Use the given initializer to in-place initialize a `T`. init<E>(init: impl Init<T, E>, flags: Flags) -> error::Result<Self> where Error: From<E>,180114ca41fSBenno Lossin fn init<E>(init: impl Init<T, E>, flags: Flags) -> error::Result<Self> 181114ca41fSBenno Lossin where 182114ca41fSBenno Lossin Error: From<E>, 183114ca41fSBenno Lossin { 184114ca41fSBenno Lossin // SAFETY: We delegate to `init` and only change the error type. 185114ca41fSBenno Lossin let init = unsafe { 186114ca41fSBenno Lossin init_from_closure(|slot| init.__pinned_init(slot).map_err(|e| Error::from(e))) 187114ca41fSBenno Lossin }; 188114ca41fSBenno Lossin Self::try_init(init, flags) 189114ca41fSBenno Lossin } 190114ca41fSBenno Lossin } 191114ca41fSBenno Lossin 192578eb8b6SBenno Lossin /// Construct an in-place fallible initializer for `struct`s. 193578eb8b6SBenno Lossin /// 194578eb8b6SBenno Lossin /// This macro defaults the error to [`Error`]. If you need [`Infallible`], then use 195578eb8b6SBenno Lossin /// [`init!`]. 196578eb8b6SBenno Lossin /// 197578eb8b6SBenno Lossin /// The syntax is identical to [`try_pin_init!`]. If you want to specify a custom error, 198578eb8b6SBenno Lossin /// append `? $type` after the `struct` initializer. 199578eb8b6SBenno Lossin /// The safety caveats from [`try_pin_init!`] also apply: 200578eb8b6SBenno Lossin /// - `unsafe` code must guarantee either full initialization or return an error and allow 201578eb8b6SBenno Lossin /// deallocation of the memory. 202578eb8b6SBenno Lossin /// - the fields are initialized in the order given in the initializer. 203578eb8b6SBenno Lossin /// - no references to fields are allowed to be created inside of the initializer. 204578eb8b6SBenno Lossin /// 205578eb8b6SBenno Lossin /// # Examples 206578eb8b6SBenno Lossin /// 207578eb8b6SBenno Lossin /// ```rust 208*dbd5058bSBenno Lossin /// use kernel::error::Error; 209*dbd5058bSBenno Lossin /// use pin_init::zeroed; 210578eb8b6SBenno Lossin /// struct BigBuf { 211578eb8b6SBenno Lossin /// big: KBox<[u8; 1024 * 1024 * 1024]>, 212578eb8b6SBenno Lossin /// small: [u8; 1024 * 1024], 213578eb8b6SBenno Lossin /// } 214578eb8b6SBenno Lossin /// 215578eb8b6SBenno Lossin /// impl BigBuf { 216578eb8b6SBenno Lossin /// fn new() -> impl Init<Self, Error> { 217578eb8b6SBenno Lossin /// try_init!(Self { 218578eb8b6SBenno Lossin /// big: KBox::init(zeroed(), GFP_KERNEL)?, 219578eb8b6SBenno Lossin /// small: [0; 1024 * 1024], 220578eb8b6SBenno Lossin /// }? Error) 221578eb8b6SBenno Lossin /// } 222578eb8b6SBenno Lossin /// } 223578eb8b6SBenno Lossin /// ``` 224578eb8b6SBenno Lossin /// 225578eb8b6SBenno Lossin /// [`Infallible`]: core::convert::Infallible 226*dbd5058bSBenno Lossin /// [`init!`]: pin_init::init 227578eb8b6SBenno Lossin /// [`try_pin_init!`]: crate::try_pin_init! 228578eb8b6SBenno Lossin /// [`Error`]: crate::error::Error 229578eb8b6SBenno Lossin #[macro_export] 230578eb8b6SBenno Lossin macro_rules! try_init { 231578eb8b6SBenno Lossin ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { 232578eb8b6SBenno Lossin $($fields:tt)* 233578eb8b6SBenno Lossin }) => { 234*dbd5058bSBenno Lossin ::pin_init::try_init!($(&$this in)? $t $(::<$($generics),* $(,)?>)? { 235578eb8b6SBenno Lossin $($fields)* 236578eb8b6SBenno Lossin }? $crate::error::Error) 237578eb8b6SBenno Lossin }; 238578eb8b6SBenno Lossin ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { 239578eb8b6SBenno Lossin $($fields:tt)* 240578eb8b6SBenno Lossin }? $err:ty) => { 241*dbd5058bSBenno Lossin ::pin_init::try_init!($(&$this in)? $t $(::<$($generics),* $(,)?>)? { 242578eb8b6SBenno Lossin $($fields)* 243578eb8b6SBenno Lossin }? $err) 244578eb8b6SBenno Lossin }; 245578eb8b6SBenno Lossin } 246578eb8b6SBenno Lossin 247578eb8b6SBenno Lossin /// Construct an in-place, fallible pinned initializer for `struct`s. 248578eb8b6SBenno Lossin /// 249578eb8b6SBenno Lossin /// If the initialization can complete without error (or [`Infallible`]), then use [`pin_init!`]. 250578eb8b6SBenno Lossin /// 251578eb8b6SBenno Lossin /// You can use the `?` operator or use `return Err(err)` inside the initializer to stop 252578eb8b6SBenno Lossin /// initialization and return the error. 253578eb8b6SBenno Lossin /// 254578eb8b6SBenno Lossin /// IMPORTANT: if you have `unsafe` code inside of the initializer you have to ensure that when 255578eb8b6SBenno Lossin /// initialization fails, the memory can be safely deallocated without any further modifications. 256578eb8b6SBenno Lossin /// 257578eb8b6SBenno Lossin /// This macro defaults the error to [`Error`]. 258578eb8b6SBenno Lossin /// 259578eb8b6SBenno Lossin /// The syntax is identical to [`pin_init!`] with the following exception: you can append `? $type` 260578eb8b6SBenno Lossin /// after the `struct` initializer to specify the error type you want to use. 261578eb8b6SBenno Lossin /// 262578eb8b6SBenno Lossin /// # Examples 263578eb8b6SBenno Lossin /// 264578eb8b6SBenno Lossin /// ```rust 265578eb8b6SBenno Lossin /// # #![feature(new_uninit)] 266*dbd5058bSBenno Lossin /// use kernel::error::Error; 267*dbd5058bSBenno Lossin /// use pin_init::zeroed; 268578eb8b6SBenno Lossin /// #[pin_data] 269578eb8b6SBenno Lossin /// struct BigBuf { 270578eb8b6SBenno Lossin /// big: KBox<[u8; 1024 * 1024 * 1024]>, 271578eb8b6SBenno Lossin /// small: [u8; 1024 * 1024], 272578eb8b6SBenno Lossin /// ptr: *mut u8, 273578eb8b6SBenno Lossin /// } 274578eb8b6SBenno Lossin /// 275578eb8b6SBenno Lossin /// impl BigBuf { 276578eb8b6SBenno Lossin /// fn new() -> impl PinInit<Self, Error> { 277578eb8b6SBenno Lossin /// try_pin_init!(Self { 278578eb8b6SBenno Lossin /// big: KBox::init(zeroed(), GFP_KERNEL)?, 279578eb8b6SBenno Lossin /// small: [0; 1024 * 1024], 280578eb8b6SBenno Lossin /// ptr: core::ptr::null_mut(), 281578eb8b6SBenno Lossin /// }? Error) 282578eb8b6SBenno Lossin /// } 283578eb8b6SBenno Lossin /// } 284578eb8b6SBenno Lossin /// ``` 285578eb8b6SBenno Lossin /// 286578eb8b6SBenno Lossin /// [`Infallible`]: core::convert::Infallible 287*dbd5058bSBenno Lossin /// [`pin_init!`]: pin_init::pin_init 288578eb8b6SBenno Lossin /// [`Error`]: crate::error::Error 289578eb8b6SBenno Lossin #[macro_export] 290578eb8b6SBenno Lossin macro_rules! try_pin_init { 291578eb8b6SBenno Lossin ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { 292578eb8b6SBenno Lossin $($fields:tt)* 293578eb8b6SBenno Lossin }) => { 294*dbd5058bSBenno Lossin ::pin_init::try_pin_init!($(&$this in)? $t $(::<$($generics),* $(,)?>)? { 295578eb8b6SBenno Lossin $($fields)* 296578eb8b6SBenno Lossin }? $crate::error::Error) 297578eb8b6SBenno Lossin }; 298578eb8b6SBenno Lossin ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { 299578eb8b6SBenno Lossin $($fields:tt)* 300578eb8b6SBenno Lossin }? $err:ty) => { 301*dbd5058bSBenno Lossin ::pin_init::try_pin_init!($(&$this in)? $t $(::<$($generics),* $(,)?>)? { 302578eb8b6SBenno Lossin $($fields)* 303578eb8b6SBenno Lossin }? $err) 304578eb8b6SBenno Lossin }; 305578eb8b6SBenno Lossin } 306