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