1 // SPDX-License-Identifier: GPL-2.0 2 3 //! Extensions to the [`pin-init`] crate. 4 //! 5 //! Most `struct`s from the [`sync`] module need to be pinned, because they contain self-referential 6 //! `struct`s from C. [Pinning][pinning] is Rust's way of ensuring data does not move. 7 //! 8 //! The [`pin-init`] crate is the way such structs are initialized on the Rust side. Please refer 9 //! to its documentation to better understand how to use it. Additionally, there are many examples 10 //! throughout the kernel, such as the types from the [`sync`] module. And the ones presented 11 //! below. 12 //! 13 //! [`sync`]: crate::sync 14 //! [pinning]: https://doc.rust-lang.org/std/pin/index.html 15 //! [`pin-init`]: https://rust.docs.kernel.org/pin_init/ 16 //! 17 //! # [`Opaque<T>`] 18 //! 19 //! For the special case where initializing a field is a single FFI-function call that cannot fail, 20 //! there exist the helper function [`Opaque::ffi_init`]. This function initialize a single 21 //! [`Opaque<T>`] field by just delegating to the supplied closure. You can use these in 22 //! combination with [`pin_init!`]. 23 //! 24 //! [`Opaque<T>`]: crate::types::Opaque 25 //! [`Opaque::ffi_init`]: crate::types::Opaque::ffi_init 26 //! [`pin_init!`]: pin_init::pin_init 27 //! 28 //! # Examples 29 //! 30 //! ## General Examples 31 //! 32 //! ```rust 33 //! # #![expect(clippy::disallowed_names, clippy::undocumented_unsafe_blocks)] 34 //! use kernel::types::Opaque; 35 //! use pin_init::pin_init_from_closure; 36 //! 37 //! // assume we have some `raw_foo` type in C: 38 //! #[repr(C)] 39 //! struct RawFoo([u8; 16]); 40 //! extern "C" { 41 //! fn init_foo(_: *mut RawFoo); 42 //! } 43 //! 44 //! #[pin_data] 45 //! struct Foo { 46 //! #[pin] 47 //! raw: Opaque<RawFoo>, 48 //! } 49 //! 50 //! impl Foo { 51 //! fn setup(self: Pin<&mut Self>) { 52 //! pr_info!("Setting up foo\n"); 53 //! } 54 //! } 55 //! 56 //! let foo = pin_init!(Foo { 57 //! raw <- unsafe { 58 //! Opaque::ffi_init(|s| { 59 //! // note that this cannot fail. 60 //! init_foo(s); 61 //! }) 62 //! }, 63 //! }).pin_chain(|foo| { 64 //! foo.setup(); 65 //! Ok(()) 66 //! }); 67 //! ``` 68 //! 69 //! ```rust 70 //! # #![expect(unreachable_pub, clippy::disallowed_names)] 71 //! use kernel::{prelude::*, types::Opaque}; 72 //! use core::{ptr::addr_of_mut, marker::PhantomPinned, pin::Pin}; 73 //! # mod bindings { 74 //! # #![expect(non_camel_case_types, clippy::missing_safety_doc)] 75 //! # pub struct foo; 76 //! # pub unsafe fn init_foo(_ptr: *mut foo) {} 77 //! # pub unsafe fn destroy_foo(_ptr: *mut foo) {} 78 //! # pub unsafe fn enable_foo(_ptr: *mut foo, _flags: u32) -> i32 { 0 } 79 //! # } 80 //! /// # Invariants 81 //! /// 82 //! /// `foo` is always initialized 83 //! #[pin_data(PinnedDrop)] 84 //! pub struct RawFoo { 85 //! #[pin] 86 //! foo: Opaque<bindings::foo>, 87 //! #[pin] 88 //! _p: PhantomPinned, 89 //! } 90 //! 91 //! impl RawFoo { 92 //! pub fn new(flags: u32) -> impl PinInit<Self, Error> { 93 //! // SAFETY: 94 //! // - when the closure returns `Ok(())`, then it has successfully initialized and 95 //! // enabled `foo`, 96 //! // - when it returns `Err(e)`, then it has cleaned up before 97 //! unsafe { 98 //! pin_init::pin_init_from_closure(move |slot: *mut Self| { 99 //! // `slot` contains uninit memory, avoid creating a reference. 100 //! let foo = addr_of_mut!((*slot).foo); 101 //! 102 //! // Initialize the `foo` 103 //! bindings::init_foo(Opaque::cast_into(foo)); 104 //! 105 //! // Try to enable it. 106 //! let err = bindings::enable_foo(Opaque::cast_into(foo), flags); 107 //! if err != 0 { 108 //! // Enabling has failed, first clean up the foo and then return the error. 109 //! bindings::destroy_foo(Opaque::cast_into(foo)); 110 //! return Err(Error::from_errno(err)); 111 //! } 112 //! 113 //! // All fields of `RawFoo` have been initialized, since `_p` is a ZST. 114 //! Ok(()) 115 //! }) 116 //! } 117 //! } 118 //! } 119 //! 120 //! #[pinned_drop] 121 //! impl PinnedDrop for RawFoo { 122 //! fn drop(self: Pin<&mut Self>) { 123 //! // SAFETY: Since `foo` is initialized, destroying is safe. 124 //! unsafe { bindings::destroy_foo(self.foo.get()) }; 125 //! } 126 //! } 127 //! ``` 128 129 use crate::{ 130 alloc::{AllocError, Flags}, 131 error::{self, Error}, 132 }; 133 use pin_init::{init_from_closure, pin_init_from_closure, Init, PinInit}; 134 135 /// Smart pointer that can initialize memory in-place. 136 pub trait InPlaceInit<T>: Sized { 137 /// Pinned version of `Self`. 138 /// 139 /// If a type already implicitly pins its pointee, `Pin<Self>` is unnecessary. In this case use 140 /// `Self`, otherwise just use `Pin<Self>`. 141 type PinnedSelf; 142 143 /// Use the given pin-initializer to pin-initialize a `T` inside of a new smart pointer of this 144 /// type. 145 /// 146 /// 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>147 fn try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Self::PinnedSelf, E> 148 where 149 E: From<AllocError>; 150 151 /// Use the given pin-initializer to pin-initialize a `T` inside of a new smart pointer of this 152 /// type. 153 /// 154 /// 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>,155 fn pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> error::Result<Self::PinnedSelf> 156 where 157 Error: From<E>, 158 { 159 // SAFETY: We delegate to `init` and only change the error type. 160 let init = unsafe { 161 pin_init_from_closure(|slot| init.__pinned_init(slot).map_err(|e| Error::from(e))) 162 }; 163 Self::try_pin_init(init, flags) 164 } 165 166 /// 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>167 fn try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E> 168 where 169 E: From<AllocError>; 170 171 /// 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>,172 fn init<E>(init: impl Init<T, E>, flags: Flags) -> error::Result<Self> 173 where 174 Error: From<E>, 175 { 176 // SAFETY: We delegate to `init` and only change the error type. 177 let init = unsafe { 178 init_from_closure(|slot| init.__pinned_init(slot).map_err(|e| Error::from(e))) 179 }; 180 Self::try_init(init, flags) 181 } 182 } 183 184 /// Construct an in-place fallible initializer for `struct`s. 185 /// 186 /// This macro defaults the error to [`Error`]. If you need [`Infallible`], then use 187 /// [`init!`]. 188 /// 189 /// The syntax is identical to [`try_pin_init!`]. If you want to specify a custom error, 190 /// append `? $type` after the `struct` initializer. 191 /// The safety caveats from [`try_pin_init!`] also apply: 192 /// - `unsafe` code must guarantee either full initialization or return an error and allow 193 /// deallocation of the memory. 194 /// - the fields are initialized in the order given in the initializer. 195 /// - no references to fields are allowed to be created inside of the initializer. 196 /// 197 /// # Examples 198 /// 199 /// ```rust 200 /// use kernel::error::Error; 201 /// use pin_init::init_zeroed; 202 /// struct BigBuf { 203 /// big: KBox<[u8; 1024 * 1024 * 1024]>, 204 /// small: [u8; 1024 * 1024], 205 /// } 206 /// 207 /// impl BigBuf { 208 /// fn new() -> impl Init<Self, Error> { 209 /// try_init!(Self { 210 /// big: KBox::init(init_zeroed(), GFP_KERNEL)?, 211 /// small: [0; 1024 * 1024], 212 /// }? Error) 213 /// } 214 /// } 215 /// ``` 216 /// 217 /// [`Infallible`]: core::convert::Infallible 218 /// [`init!`]: pin_init::init 219 /// [`try_pin_init!`]: crate::try_pin_init! 220 /// [`Error`]: crate::error::Error 221 #[macro_export] 222 macro_rules! try_init { 223 ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { 224 $($fields:tt)* 225 }) => { 226 ::pin_init::try_init!($(&$this in)? $t $(::<$($generics),*>)? { 227 $($fields)* 228 }? $crate::error::Error) 229 }; 230 ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { 231 $($fields:tt)* 232 }? $err:ty) => { 233 ::pin_init::try_init!($(&$this in)? $t $(::<$($generics),*>)? { 234 $($fields)* 235 }? $err) 236 }; 237 } 238 239 /// Construct an in-place, fallible pinned initializer for `struct`s. 240 /// 241 /// If the initialization can complete without error (or [`Infallible`]), then use [`pin_init!`]. 242 /// 243 /// You can use the `?` operator or use `return Err(err)` inside the initializer to stop 244 /// initialization and return the error. 245 /// 246 /// IMPORTANT: if you have `unsafe` code inside of the initializer you have to ensure that when 247 /// initialization fails, the memory can be safely deallocated without any further modifications. 248 /// 249 /// This macro defaults the error to [`Error`]. 250 /// 251 /// The syntax is identical to [`pin_init!`] with the following exception: you can append `? $type` 252 /// after the `struct` initializer to specify the error type you want to use. 253 /// 254 /// # Examples 255 /// 256 /// ```rust 257 /// # #![feature(new_uninit)] 258 /// use kernel::error::Error; 259 /// use pin_init::init_zeroed; 260 /// #[pin_data] 261 /// struct BigBuf { 262 /// big: KBox<[u8; 1024 * 1024 * 1024]>, 263 /// small: [u8; 1024 * 1024], 264 /// ptr: *mut u8, 265 /// } 266 /// 267 /// impl BigBuf { 268 /// fn new() -> impl PinInit<Self, Error> { 269 /// try_pin_init!(Self { 270 /// big: KBox::init(init_zeroed(), GFP_KERNEL)?, 271 /// small: [0; 1024 * 1024], 272 /// ptr: core::ptr::null_mut(), 273 /// }? Error) 274 /// } 275 /// } 276 /// ``` 277 /// 278 /// [`Infallible`]: core::convert::Infallible 279 /// [`pin_init!`]: pin_init::pin_init 280 /// [`Error`]: crate::error::Error 281 #[macro_export] 282 macro_rules! try_pin_init { 283 ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { 284 $($fields:tt)* 285 }) => { 286 ::pin_init::try_pin_init!($(&$this in)? $t $(::<$($generics),*>)? { 287 $($fields)* 288 }? $crate::error::Error) 289 }; 290 ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { 291 $($fields:tt)* 292 }? $err:ty) => { 293 ::pin_init::try_pin_init!($(&$this in)? $t $(::<$($generics),*>)? { 294 $($fields)* 295 }? $err) 296 }; 297 } 298