| 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::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 | //! use kernel::{prelude::*, types::Opaque}; |
| 71 | //! use core::{ptr::addr_of_mut, marker::PhantomPinned, pin::Pin}; |
| 72 | //! # mod bindings { |
| 73 | //! # #![expect(non_camel_case_types, clippy::missing_safety_doc)] |
| 74 | //! # pub struct foo; |
| 75 | //! # pub unsafe fn init_foo(_ptr: *mut foo) {} |
| 76 | //! # pub unsafe fn destroy_foo(_ptr: *mut foo) {} |
| 77 | //! # pub unsafe fn enable_foo(_ptr: *mut foo, _flags: u32) -> i32 { 0 } |
| 78 | //! # } |
| 79 | //! /// # Invariants |
| 80 | //! /// |
| 81 | //! /// `foo` is always initialized |
| 82 | //! #[pin_data(PinnedDrop)] |
| 83 | //! pub struct RawFoo { |
| 84 | //! #[pin] |
| 85 | //! foo: Opaque<bindings::foo>, |
| 86 | //! #[pin] |
| 87 | //! _p: PhantomPinned, |
| 88 | //! } |
| 89 | //! |
| 90 | //! impl RawFoo { |
| 91 | //! pub fn new(flags: u32) -> impl PinInit<Self, Error> { |
| 92 | //! // SAFETY: |
| 93 | //! // - when the closure returns `Ok(())`, then it has successfully initialized and |
| 94 | //! // enabled `foo`, |
| 95 | //! // - when it returns `Err(e)`, then it has cleaned up before |
| 96 | //! unsafe { |
| 97 | //! pin_init::pin_init_from_closure(move |slot: *mut Self| { |
| 98 | //! // `slot` contains uninit memory, avoid creating a reference. |
| 99 | //! let foo = addr_of_mut!((*slot).foo); |
| 100 | //! |
| 101 | //! // Initialize the `foo` |
| 102 | //! bindings::init_foo(Opaque::cast_into(foo)); |
| 103 | //! |
| 104 | //! // Try to enable it. |
| 105 | //! let err = bindings::enable_foo(Opaque::cast_into(foo), flags); |
| 106 | //! if err != 0 { |
| 107 | //! // Enabling has failed, first clean up the foo and then return the error. |
| 108 | //! bindings::destroy_foo(Opaque::cast_into(foo)); |
| 109 | //! return Err(Error::from_errno(err)); |
| 110 | //! } |
| 111 | //! |
| 112 | //! // All fields of `RawFoo` have been initialized, since `_p` is a ZST. |
| 113 | //! Ok(()) |
| 114 | //! }) |
| 115 | //! } |
| 116 | //! } |
| 117 | //! } |
| 118 | //! |
| 119 | //! #[pinned_drop] |
| 120 | //! impl PinnedDrop for RawFoo { |
| 121 | //! fn drop(self: Pin<&mut Self>) { |
| 122 | //! // SAFETY: Since `foo` is initialized, destroying is safe. |
| 123 | //! unsafe { bindings::destroy_foo(self.foo.get()) }; |
| 124 | //! } |
| 125 | //! } |
| 126 | //! ``` |
| 127 | |
| 128 | use crate:: |
| 129 | , |
| 130 | , |
| 131 | ; |
| 132 | use ; |
| 133 | |
| 134 | /// Smart pointer that can initialize memory in-place. |
| 135 | |
| 136 | /// Pinned version of `Self`. |
| 137 | /// |
| 138 | /// If a type already implicitly pins its pointee, `Pin<Self>` is unnecessary. In this case use |
| 139 | /// `Self`, otherwise just use `Pin<Self>`. |
| 140 | type PinnedSelf; |
| 141 | |
| 142 | /// Use the given pin-initializer to pin-initialize a `T` inside of a new smart pointer of this |
| 143 | /// type. |
| 144 | /// |
| 145 | /// If `T: !Unpin` it will not be able to move afterwards. |
| 146 | |
| 147 | |
| 148 | E: ; |
| 149 | |
| 150 | /// Use the given pin-initializer to pin-initialize a `T` inside of a new smart pointer of this |
| 151 | /// type. |
| 152 | /// |
| 153 | /// If `T: !Unpin` it will not be able to move afterwards. |
| 154 | #[inline] |
| 155 | fn (init: impl , flags: Flags) -> |
| 156 | where |
| 157 | Error: , |
| 158 | |
| 159 | // SAFETY: We delegate to `init` and only change the error type. |
| 160 | let init = unsafe |
| 161 | pin_init_from_closure |
| 162 | raw_try_init.map_err |
| 163 | |
| 164 | ; |
| 165 | Selftry_pin_init |
| 166 | |
| 167 | |
| 168 | /// Use the given initializer to in-place initialize a `T`. |
| 169 | |
| 170 | |
| 171 | E: ; |
| 172 | |
| 173 | /// Use the given initializer to in-place initialize a `T`. |
| 174 | #[inline] |
| 175 | fn (init: impl , flags: Flags) -> |
| 176 | where |
| 177 | Error: , |
| 178 | |
| 179 | // SAFETY: We delegate to `init` and only change the error type. |
| 180 | let init = unsafe |
| 181 | init_from_closure |
| 182 | ; |
| 183 | Selftry_init |
| 184 | |
| 185 | |
| 186 | |
| 187 | /// Construct an in-place fallible initializer for `struct`s. |
| 188 | /// |
| 189 | /// This macro defaults the error to [`Error`]. If you need [`Infallible`], then use |
| 190 | /// [`init!`]. |
| 191 | /// |
| 192 | /// The syntax is identical to [`try_pin_init!`]. If you want to specify a custom error, |
| 193 | /// append `? $type` after the `struct` initializer. |
| 194 | /// The safety caveats from [`try_pin_init!`] also apply: |
| 195 | /// - `unsafe` code must guarantee either full initialization or return an error and allow |
| 196 | /// deallocation of the memory. |
| 197 | /// - the fields are initialized in the order given in the initializer. |
| 198 | /// - no references to fields are allowed to be created inside of the initializer. |
| 199 | /// |
| 200 | /// # Examples |
| 201 | /// |
| 202 | /// ```rust |
| 203 | /// use kernel::error::Error; |
| 204 | /// use pin_init::init_zeroed; |
| 205 | /// struct BigBuf { |
| 206 | /// big: KBox<[u8; 1024 * 1024 * 1024]>, |
| 207 | /// small: [u8; 1024 * 1024], |
| 208 | /// } |
| 209 | /// |
| 210 | /// impl BigBuf { |
| 211 | /// fn new() -> impl Init<Self, Error> { |
| 212 | /// try_init!(Self { |
| 213 | /// big: KBox::init(init_zeroed(), GFP_KERNEL)?, |
| 214 | /// small: [0; 1024 * 1024], |
| 215 | /// }? Error) |
| 216 | /// } |
| 217 | /// } |
| 218 | /// ``` |
| 219 | /// |
| 220 | /// [`Infallible`]: core::convert::Infallible |
| 221 | /// [`init!`]: pin_init::init |
| 222 | /// [`try_pin_init!`]: crate::try_pin_init! |
| 223 | /// [`Error`]: crate::error::Error |
| 224 | |
| 225 | |
| 226 | => |
| 227 | init! |
| 228 | |
| 229 | $* |
| 230 | |
| 231 | } |
| 232 | |
| 233 | |
| 234 | /// Construct an in-place, fallible pinned initializer for `struct`s. |
| 235 | /// |
| 236 | /// If the initialization can complete without error (or [`Infallible`]), then use [`pin_init!`]. |
| 237 | /// |
| 238 | /// You can use the `?` operator or use `return Err(err)` inside the initializer to stop |
| 239 | /// initialization and return the error. |
| 240 | /// |
| 241 | /// IMPORTANT: if you have `unsafe` code inside of the initializer you have to ensure that when |
| 242 | /// initialization fails, the memory can be safely deallocated without any further modifications. |
| 243 | /// |
| 244 | /// This macro defaults the error to [`Error`]. |
| 245 | /// |
| 246 | /// The syntax is identical to [`pin_init!`] with the following exception: you can append `? $type` |
| 247 | /// after the `struct` initializer to specify the error type you want to use. |
| 248 | /// |
| 249 | /// # Examples |
| 250 | /// |
| 251 | /// ```rust |
| 252 | /// # #![feature(new_uninit)] |
| 253 | /// use kernel::error::Error; |
| 254 | /// use pin_init::init_zeroed; |
| 255 | /// #[pin_data] |
| 256 | /// struct BigBuf { |
| 257 | /// big: KBox<[u8; 1024 * 1024 * 1024]>, |
| 258 | /// small: [u8; 1024 * 1024], |
| 259 | /// ptr: *mut u8, |
| 260 | /// } |
| 261 | /// |
| 262 | /// impl BigBuf { |
| 263 | /// fn new() -> impl PinInit<Self, Error> { |
| 264 | /// try_pin_init!(Self { |
| 265 | /// big: KBox::init(init_zeroed(), GFP_KERNEL)?, |
| 266 | /// small: [0; 1024 * 1024], |
| 267 | /// ptr: core::ptr::null_mut(), |
| 268 | /// }? Error) |
| 269 | /// } |
| 270 | /// } |
| 271 | /// ``` |
| 272 | /// |
| 273 | /// [`Infallible`]: core::convert::Infallible |
| 274 | /// [`pin_init!`]: pin_init::pin_init |
| 275 | /// [`Error`]: crate::error::Error |
| 276 | |
| 277 | |
| 278 | => |
| 279 | pin_init! |
| 280 | |
| 281 | $* |
| 282 | |
| 283 | } |
| 284 |