1 // SPDX-License-Identifier: GPL-2.0 2 3 //! Implementation of [`Box`]. 4 5 #[allow(unused_imports)] // Used in doc comments. 6 use super::allocator::{KVmalloc, Kmalloc, Vmalloc, VmallocPageIter}; 7 use super::{AllocError, Allocator, Flags, NumaNode}; 8 use core::alloc::Layout; 9 use core::borrow::{Borrow, BorrowMut}; 10 use core::marker::PhantomData; 11 use core::mem::ManuallyDrop; 12 use core::mem::MaybeUninit; 13 use core::ops::{Deref, DerefMut}; 14 use core::pin::Pin; 15 use core::ptr::NonNull; 16 use core::result::Result; 17 18 use crate::ffi::c_void; 19 use crate::fmt; 20 use crate::init::InPlaceInit; 21 use crate::page::AsPageIter; 22 use crate::prelude::*; 23 use crate::types::ForeignOwnable; 24 use pin_init::{InPlaceWrite, Init, PinInit, ZeroableOption}; 25 26 /// The kernel's [`Box`] type -- a heap allocation for a single value of type `T`. 27 /// 28 /// This is the kernel's version of the Rust stdlib's `Box`. There are several differences, 29 /// for example no `noalias` attribute is emitted and partially moving out of a `Box` is not 30 /// supported. There are also several API differences, e.g. `Box` always requires an [`Allocator`] 31 /// implementation to be passed as generic, page [`Flags`] when allocating memory and all functions 32 /// that may allocate memory are fallible. 33 /// 34 /// `Box` works with any of the kernel's allocators, e.g. [`Kmalloc`], [`Vmalloc`] or [`KVmalloc`]. 35 /// There are aliases for `Box` with these allocators ([`KBox`], [`VBox`], [`KVBox`]). 36 /// 37 /// When dropping a [`Box`], the value is also dropped and the heap memory is automatically freed. 38 /// 39 /// # Examples 40 /// 41 /// ``` 42 /// let b = KBox::<u64>::new(24_u64, GFP_KERNEL)?; 43 /// 44 /// assert_eq!(*b, 24_u64); 45 /// # Ok::<(), Error>(()) 46 /// ``` 47 /// 48 /// ``` 49 /// # use kernel::bindings; 50 /// const SIZE: usize = bindings::KMALLOC_MAX_SIZE as usize + 1; 51 /// struct Huge([u8; SIZE]); 52 /// 53 /// assert!(KBox::<Huge>::new_uninit(GFP_KERNEL | __GFP_NOWARN).is_err()); 54 /// ``` 55 /// 56 /// ``` 57 /// # use kernel::bindings; 58 /// const SIZE: usize = bindings::KMALLOC_MAX_SIZE as usize + 1; 59 /// struct Huge([u8; SIZE]); 60 /// 61 /// assert!(KVBox::<Huge>::new_uninit(GFP_KERNEL).is_ok()); 62 /// ``` 63 /// 64 /// [`Box`]es can also be used to store trait objects by coercing their type: 65 /// 66 /// ``` 67 /// trait FooTrait {} 68 /// 69 /// struct FooStruct; 70 /// impl FooTrait for FooStruct {} 71 /// 72 /// let _ = KBox::new(FooStruct, GFP_KERNEL)? as KBox<dyn FooTrait>; 73 /// # Ok::<(), Error>(()) 74 /// ``` 75 /// 76 /// # Invariants 77 /// 78 /// `self.0` is always properly aligned and either points to memory allocated with `A` or, for 79 /// zero-sized types, is a dangling, well aligned pointer. 80 #[repr(transparent)] 81 #[derive(core::marker::CoercePointee)] 82 pub struct Box<#[pointee] T: ?Sized, A: Allocator>(NonNull<T>, PhantomData<A>); 83 84 /// Type alias for [`Box`] with a [`Kmalloc`] allocator. 85 /// 86 /// # Examples 87 /// 88 /// ``` 89 /// let b = KBox::new(24_u64, GFP_KERNEL)?; 90 /// 91 /// assert_eq!(*b, 24_u64); 92 /// # Ok::<(), Error>(()) 93 /// ``` 94 pub type KBox<T> = Box<T, super::allocator::Kmalloc>; 95 96 /// Type alias for [`Box`] with a [`Vmalloc`] allocator. 97 /// 98 /// # Examples 99 /// 100 /// ``` 101 /// let b = VBox::new(24_u64, GFP_KERNEL)?; 102 /// 103 /// assert_eq!(*b, 24_u64); 104 /// # Ok::<(), Error>(()) 105 /// ``` 106 pub type VBox<T> = Box<T, super::allocator::Vmalloc>; 107 108 /// Type alias for [`Box`] with a [`KVmalloc`] allocator. 109 /// 110 /// # Examples 111 /// 112 /// ``` 113 /// let b = KVBox::new(24_u64, GFP_KERNEL)?; 114 /// 115 /// assert_eq!(*b, 24_u64); 116 /// # Ok::<(), Error>(()) 117 /// ``` 118 pub type KVBox<T> = Box<T, super::allocator::KVmalloc>; 119 120 // SAFETY: All zeros is equivalent to `None` (option layout optimization guarantee: 121 // <https://doc.rust-lang.org/stable/std/option/index.html#representation>). 122 unsafe impl<T, A: Allocator> ZeroableOption for Box<T, A> {} 123 124 // SAFETY: `Box` is `Send` if `T` is `Send` because the `Box` owns a `T`. 125 unsafe impl<T, A> Send for Box<T, A> 126 where 127 T: Send + ?Sized, 128 A: Allocator, 129 { 130 } 131 132 // SAFETY: `Box` is `Sync` if `T` is `Sync` because the `Box` owns a `T`. 133 unsafe impl<T, A> Sync for Box<T, A> 134 where 135 T: Sync + ?Sized, 136 A: Allocator, 137 { 138 } 139 140 impl<T, A> Box<T, A> 141 where 142 T: ?Sized, 143 A: Allocator, 144 { 145 /// Creates a new `Box<T, A>` from a raw pointer. 146 /// 147 /// # Safety 148 /// 149 /// For non-ZSTs, `raw` must point at an allocation allocated with `A` that is sufficiently 150 /// aligned for and holds a valid `T`. The caller passes ownership of the allocation to the 151 /// `Box`. 152 /// 153 /// For ZSTs, `raw` must be a dangling, well aligned pointer. 154 #[inline] 155 pub const unsafe fn from_raw(raw: *mut T) -> Self { 156 // INVARIANT: Validity of `raw` is guaranteed by the safety preconditions of this function. 157 // SAFETY: By the safety preconditions of this function, `raw` is not a NULL pointer. 158 Self(unsafe { NonNull::new_unchecked(raw) }, PhantomData) 159 } 160 161 /// Consumes the `Box<T, A>` and returns a raw pointer. 162 /// 163 /// This will not run the destructor of `T` and for non-ZSTs the allocation will stay alive 164 /// indefinitely. Use [`Box::from_raw`] to recover the [`Box`], drop the value and free the 165 /// allocation, if any. 166 /// 167 /// # Examples 168 /// 169 /// ``` 170 /// let x = KBox::new(24, GFP_KERNEL)?; 171 /// let ptr = KBox::into_raw(x); 172 /// // SAFETY: `ptr` comes from a previous call to `KBox::into_raw`. 173 /// let x = unsafe { KBox::from_raw(ptr) }; 174 /// 175 /// assert_eq!(*x, 24); 176 /// # Ok::<(), Error>(()) 177 /// ``` 178 #[inline] 179 pub fn into_raw(b: Self) -> *mut T { 180 ManuallyDrop::new(b).0.as_ptr() 181 } 182 183 /// Consumes and leaks the `Box<T, A>` and returns a mutable reference. 184 /// 185 /// See [`Box::into_raw`] for more details. 186 #[inline] 187 pub fn leak<'a>(b: Self) -> &'a mut T { 188 // SAFETY: `Box::into_raw` always returns a properly aligned and dereferenceable pointer 189 // which points to an initialized instance of `T`. 190 unsafe { &mut *Box::into_raw(b) } 191 } 192 } 193 194 impl<T, A> Box<MaybeUninit<T>, A> 195 where 196 A: Allocator, 197 { 198 /// Converts a `Box<MaybeUninit<T>, A>` to a `Box<T, A>`. 199 /// 200 /// It is undefined behavior to call this function while the value inside of `b` is not yet 201 /// fully initialized. 202 /// 203 /// # Safety 204 /// 205 /// Callers must ensure that the value inside of `b` is in an initialized state. 206 pub unsafe fn assume_init(self) -> Box<T, A> { 207 let raw = Self::into_raw(self); 208 209 // SAFETY: `raw` comes from a previous call to `Box::into_raw`. By the safety requirements 210 // of this function, the value inside the `Box` is in an initialized state. Hence, it is 211 // safe to reconstruct the `Box` as `Box<T, A>`. 212 unsafe { Box::from_raw(raw.cast()) } 213 } 214 215 /// Writes the value and converts to `Box<T, A>`. 216 pub fn write(mut self, value: T) -> Box<T, A> { 217 (*self).write(value); 218 219 // SAFETY: We've just initialized `b`'s value. 220 unsafe { self.assume_init() } 221 } 222 } 223 224 impl<T, A> Box<T, A> 225 where 226 A: Allocator, 227 { 228 /// Creates a new `Box<T, A>` and initializes its contents with `x`. 229 /// 230 /// New memory is allocated with `A`. The allocation may fail, in which case an error is 231 /// returned. For ZSTs no memory is allocated. 232 pub fn new(x: T, flags: Flags) -> Result<Self, AllocError> { 233 let b = Self::new_uninit(flags)?; 234 Ok(Box::write(b, x)) 235 } 236 237 /// Creates a new `Box<T, A>` with uninitialized contents. 238 /// 239 /// New memory is allocated with `A`. The allocation may fail, in which case an error is 240 /// returned. For ZSTs no memory is allocated. 241 /// 242 /// # Examples 243 /// 244 /// ``` 245 /// let b = KBox::<u64>::new_uninit(GFP_KERNEL)?; 246 /// let b = KBox::write(b, 24); 247 /// 248 /// assert_eq!(*b, 24_u64); 249 /// # Ok::<(), Error>(()) 250 /// ``` 251 pub fn new_uninit(flags: Flags) -> Result<Box<MaybeUninit<T>, A>, AllocError> { 252 let layout = Layout::new::<MaybeUninit<T>>(); 253 let ptr = A::alloc(layout, flags, NumaNode::NO_NODE)?; 254 255 // INVARIANT: `ptr` is either a dangling pointer or points to memory allocated with `A`, 256 // which is sufficient in size and alignment for storing a `T`. 257 Ok(Box(ptr.cast(), PhantomData)) 258 } 259 260 /// Creates a new zero-initialized `Box<T, A>`. 261 /// 262 /// New memory is allocated with `A` and the [`__GFP_ZERO`] flag. The allocation may fail, in 263 /// which case an error is returned. For ZSTs no memory is allocated. 264 /// 265 /// # Examples 266 /// 267 /// ``` 268 /// let b = KBox::<[u8; 128]>::zeroed(GFP_KERNEL)?; 269 /// assert_eq!(*b, [0; 128]); 270 /// # Ok::<(), Error>(()) 271 /// ``` 272 pub fn zeroed(flags: Flags) -> Result<Self, AllocError> 273 where 274 T: Zeroable, 275 { 276 // SAFETY: `__GFP_ZERO` guarantees the memory is zeroed; `T: Zeroable` guarantees that 277 // all-zeroes is a valid bit pattern for `T`. 278 Ok(unsafe { Self::new_uninit(flags | __GFP_ZERO)?.assume_init() }) 279 } 280 281 /// Constructs a new `Pin<Box<T, A>>`. If `T` does not implement [`Unpin`], then `x` will be 282 /// pinned in memory and can't be moved. 283 #[inline] 284 pub fn pin(x: T, flags: Flags) -> Result<Pin<Box<T, A>>, AllocError> 285 where 286 A: 'static, 287 { 288 Ok(Self::new(x, flags)?.into()) 289 } 290 291 /// Construct a pinned slice of elements `Pin<Box<[T], A>>`. 292 /// 293 /// This is a convenient means for creation of e.g. slices of structrures containing spinlocks 294 /// or mutexes. 295 /// 296 /// # Examples 297 /// 298 /// ``` 299 /// use kernel::sync::{new_spinlock, SpinLock}; 300 /// 301 /// struct Inner { 302 /// a: u32, 303 /// b: u32, 304 /// } 305 /// 306 /// #[pin_data] 307 /// struct Example { 308 /// c: u32, 309 /// #[pin] 310 /// d: SpinLock<Inner>, 311 /// } 312 /// 313 /// impl Example { 314 /// fn new() -> impl PinInit<Self, Error> { 315 /// try_pin_init!(Self { 316 /// c: 10, 317 /// d <- new_spinlock!(Inner { a: 20, b: 30 }), 318 /// }) 319 /// } 320 /// } 321 /// 322 /// // Allocate a boxed slice of 10 `Example`s. 323 /// let s = KBox::pin_slice( 324 /// | _i | Example::new(), 325 /// 10, 326 /// GFP_KERNEL 327 /// )?; 328 /// 329 /// assert_eq!(s[5].c, 10); 330 /// assert_eq!(s[3].d.lock().a, 20); 331 /// # Ok::<(), Error>(()) 332 /// ``` 333 pub fn pin_slice<Func, Item, E>( 334 mut init: Func, 335 len: usize, 336 flags: Flags, 337 ) -> Result<Pin<Box<[T], A>>, E> 338 where 339 Func: FnMut(usize) -> Item, 340 Item: PinInit<T, E>, 341 E: From<AllocError>, 342 { 343 let mut buffer = super::Vec::<T, A>::with_capacity(len, flags)?; 344 for i in 0..len { 345 let ptr = buffer.spare_capacity_mut().as_mut_ptr().cast(); 346 // SAFETY: 347 // - `ptr` is a valid pointer to uninitialized memory. 348 // - `ptr` is not used if an error is returned. 349 // - `ptr` won't be moved until it is dropped, i.e. it is pinned. 350 unsafe { init(i).__pinned_init(ptr)? }; 351 352 // SAFETY: 353 // - `i + 1 <= len`, hence we don't exceed the capacity, due to the call to 354 // `with_capacity()` above. 355 // - The new value at index buffer.len() + 1 is the only element being added here, and 356 // it has been initialized above by `init(i).__pinned_init(ptr)`. 357 unsafe { buffer.inc_len(1) }; 358 } 359 360 let (ptr, _, _) = buffer.into_raw_parts(); 361 let slice = core::ptr::slice_from_raw_parts_mut(ptr, len); 362 363 // SAFETY: `slice` points to an allocation allocated with `A` (`buffer`) and holds a valid 364 // `[T]`. 365 Ok(Pin::from(unsafe { Box::from_raw(slice) })) 366 } 367 368 /// Convert a [`Box<T,A>`] to a [`Pin<Box<T,A>>`]. If `T` does not implement 369 /// [`Unpin`], then `x` will be pinned in memory and can't be moved. 370 pub fn into_pin(this: Self) -> Pin<Self> { 371 this.into() 372 } 373 374 /// Forgets the contents (does not run the destructor), but keeps the allocation. 375 fn forget_contents(this: Self) -> Box<MaybeUninit<T>, A> { 376 let ptr = Self::into_raw(this); 377 378 // SAFETY: `ptr` is valid, because it came from `Box::into_raw`. 379 unsafe { Box::from_raw(ptr.cast()) } 380 } 381 382 /// Drops the contents, but keeps the allocation. 383 /// 384 /// # Examples 385 /// 386 /// ``` 387 /// let value = KBox::new([0; 32], GFP_KERNEL)?; 388 /// assert_eq!(*value, [0; 32]); 389 /// let value = KBox::drop_contents(value); 390 /// // Now we can re-use `value`: 391 /// let value = KBox::write(value, [1; 32]); 392 /// assert_eq!(*value, [1; 32]); 393 /// # Ok::<(), Error>(()) 394 /// ``` 395 pub fn drop_contents(this: Self) -> Box<MaybeUninit<T>, A> { 396 let ptr = this.0.as_ptr(); 397 398 // SAFETY: `ptr` is valid, because it came from `this`. After this call we never access the 399 // value stored in `this` again. 400 unsafe { core::ptr::drop_in_place(ptr) }; 401 402 Self::forget_contents(this) 403 } 404 405 /// Moves the `Box`'s value out of the `Box` and consumes the `Box`. 406 pub fn into_inner(b: Self) -> T { 407 // SAFETY: By the type invariant `&*b` is valid for `read`. 408 let value = unsafe { core::ptr::read(&*b) }; 409 let _ = Self::forget_contents(b); 410 value 411 } 412 } 413 414 impl<T, A> From<Box<T, A>> for Pin<Box<T, A>> 415 where 416 T: ?Sized, 417 A: Allocator, 418 { 419 /// Converts a `Box<T, A>` into a `Pin<Box<T, A>>`. If `T` does not implement [`Unpin`], then 420 /// `*b` will be pinned in memory and can't be moved. 421 /// 422 /// This moves `b` into `Pin` without moving `*b` or allocating and copying any memory. 423 fn from(b: Box<T, A>) -> Self { 424 // SAFETY: The value wrapped inside a `Pin<Box<T, A>>` cannot be moved or replaced as long 425 // as `T` does not implement `Unpin`. 426 unsafe { Pin::new_unchecked(b) } 427 } 428 } 429 430 impl<T, A> InPlaceWrite<T> for Box<MaybeUninit<T>, A> 431 where 432 A: Allocator + 'static, 433 { 434 type Initialized = Box<T, A>; 435 436 fn write_init<E>(mut self, init: impl Init<T, E>) -> Result<Self::Initialized, E> { 437 let slot = self.as_mut_ptr(); 438 // SAFETY: When init errors/panics, slot will get deallocated but not dropped, 439 // slot is valid. 440 unsafe { init.__init(slot)? }; 441 // SAFETY: All fields have been initialized. 442 Ok(unsafe { Box::assume_init(self) }) 443 } 444 445 fn write_pin_init<E>(mut self, init: impl PinInit<T, E>) -> Result<Pin<Self::Initialized>, E> { 446 let slot = self.as_mut_ptr(); 447 // SAFETY: When init errors/panics, slot will get deallocated but not dropped, 448 // slot is valid and will not be moved, because we pin it later. 449 unsafe { init.__pinned_init(slot)? }; 450 // SAFETY: All fields have been initialized. 451 Ok(unsafe { Box::assume_init(self) }.into()) 452 } 453 } 454 455 impl<T, A> InPlaceInit<T> for Box<T, A> 456 where 457 A: Allocator + 'static, 458 { 459 type PinnedSelf = Pin<Self>; 460 461 #[inline] 462 fn try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Pin<Self>, E> 463 where 464 E: From<AllocError>, 465 { 466 Box::<_, A>::new_uninit(flags)?.write_pin_init(init) 467 } 468 469 #[inline] 470 fn try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E> 471 where 472 E: From<AllocError>, 473 { 474 Box::<_, A>::new_uninit(flags)?.write_init(init) 475 } 476 } 477 478 // SAFETY: The pointer returned by `into_foreign` comes from a well aligned 479 // pointer to `T` allocated by `A`. 480 unsafe impl<T, A> ForeignOwnable for Box<T, A> 481 where 482 A: Allocator, 483 { 484 const FOREIGN_ALIGN: usize = if core::mem::align_of::<T>() < A::MIN_ALIGN { 485 A::MIN_ALIGN 486 } else { 487 core::mem::align_of::<T>() 488 }; 489 490 type Borrowed<'a> 491 = &'a T 492 where 493 Self: 'a; 494 type BorrowedMut<'a> 495 = &'a mut T 496 where 497 Self: 'a; 498 499 fn into_foreign(self) -> *mut c_void { 500 Box::into_raw(self).cast() 501 } 502 503 unsafe fn from_foreign(ptr: *mut c_void) -> Self { 504 // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous 505 // call to `Self::into_foreign`. 506 unsafe { Box::from_raw(ptr.cast()) } 507 } 508 509 unsafe fn borrow<'a>(ptr: *mut c_void) -> &'a T { 510 // SAFETY: The safety requirements of this method ensure that the object remains alive and 511 // immutable for the duration of 'a. 512 unsafe { &*ptr.cast() } 513 } 514 515 unsafe fn borrow_mut<'a>(ptr: *mut c_void) -> &'a mut T { 516 let ptr = ptr.cast(); 517 // SAFETY: The safety requirements of this method ensure that the pointer is valid and that 518 // nothing else will access the value for the duration of 'a. 519 unsafe { &mut *ptr } 520 } 521 } 522 523 // SAFETY: The pointer returned by `into_foreign` comes from a well aligned 524 // pointer to `T` allocated by `A`. 525 unsafe impl<T, A> ForeignOwnable for Pin<Box<T, A>> 526 where 527 A: Allocator, 528 { 529 const FOREIGN_ALIGN: usize = <Box<T, A> as ForeignOwnable>::FOREIGN_ALIGN; 530 type Borrowed<'a> 531 = Pin<&'a T> 532 where 533 Self: 'a; 534 type BorrowedMut<'a> 535 = Pin<&'a mut T> 536 where 537 Self: 'a; 538 539 fn into_foreign(self) -> *mut c_void { 540 // SAFETY: We are still treating the box as pinned. 541 Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }).cast() 542 } 543 544 unsafe fn from_foreign(ptr: *mut c_void) -> Self { 545 // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous 546 // call to `Self::into_foreign`. 547 unsafe { Pin::new_unchecked(Box::from_raw(ptr.cast())) } 548 } 549 550 unsafe fn borrow<'a>(ptr: *mut c_void) -> Pin<&'a T> { 551 // SAFETY: The safety requirements for this function ensure that the object is still alive, 552 // so it is safe to dereference the raw pointer. 553 // The safety requirements of `from_foreign` also ensure that the object remains alive for 554 // the lifetime of the returned value. 555 let r = unsafe { &*ptr.cast() }; 556 557 // SAFETY: This pointer originates from a `Pin<Box<T>>`. 558 unsafe { Pin::new_unchecked(r) } 559 } 560 561 unsafe fn borrow_mut<'a>(ptr: *mut c_void) -> Pin<&'a mut T> { 562 let ptr = ptr.cast(); 563 // SAFETY: The safety requirements for this function ensure that the object is still alive, 564 // so it is safe to dereference the raw pointer. 565 // The safety requirements of `from_foreign` also ensure that the object remains alive for 566 // the lifetime of the returned value. 567 let r = unsafe { &mut *ptr }; 568 569 // SAFETY: This pointer originates from a `Pin<Box<T>>`. 570 unsafe { Pin::new_unchecked(r) } 571 } 572 } 573 574 impl<T, A> Deref for Box<T, A> 575 where 576 T: ?Sized, 577 A: Allocator, 578 { 579 type Target = T; 580 581 fn deref(&self) -> &T { 582 // SAFETY: `self.0` is always properly aligned, dereferenceable and points to an initialized 583 // instance of `T`. 584 unsafe { self.0.as_ref() } 585 } 586 } 587 588 impl<T, A> DerefMut for Box<T, A> 589 where 590 T: ?Sized, 591 A: Allocator, 592 { 593 fn deref_mut(&mut self) -> &mut T { 594 // SAFETY: `self.0` is always properly aligned, dereferenceable and points to an initialized 595 // instance of `T`. 596 unsafe { self.0.as_mut() } 597 } 598 } 599 600 /// # Examples 601 /// 602 /// ``` 603 /// # use core::borrow::Borrow; 604 /// # use kernel::alloc::KBox; 605 /// struct Foo<B: Borrow<u32>>(B); 606 /// 607 /// // Owned instance. 608 /// let owned = Foo(1); 609 /// 610 /// // Owned instance using `KBox`. 611 /// let owned_kbox = Foo(KBox::new(1, GFP_KERNEL)?); 612 /// 613 /// let i = 1; 614 /// // Borrowed from `i`. 615 /// let borrowed = Foo(&i); 616 /// # Ok::<(), Error>(()) 617 /// ``` 618 impl<T, A> Borrow<T> for Box<T, A> 619 where 620 T: ?Sized, 621 A: Allocator, 622 { 623 fn borrow(&self) -> &T { 624 self.deref() 625 } 626 } 627 628 /// # Examples 629 /// 630 /// ``` 631 /// # use core::borrow::BorrowMut; 632 /// # use kernel::alloc::KBox; 633 /// struct Foo<B: BorrowMut<u32>>(B); 634 /// 635 /// // Owned instance. 636 /// let owned = Foo(1); 637 /// 638 /// // Owned instance using `KBox`. 639 /// let owned_kbox = Foo(KBox::new(1, GFP_KERNEL)?); 640 /// 641 /// let mut i = 1; 642 /// // Borrowed from `i`. 643 /// let borrowed = Foo(&mut i); 644 /// # Ok::<(), Error>(()) 645 /// ``` 646 impl<T, A> BorrowMut<T> for Box<T, A> 647 where 648 T: ?Sized, 649 A: Allocator, 650 { 651 fn borrow_mut(&mut self) -> &mut T { 652 self.deref_mut() 653 } 654 } 655 656 impl<T, A> fmt::Display for Box<T, A> 657 where 658 T: ?Sized + fmt::Display, 659 A: Allocator, 660 { 661 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 662 <T as fmt::Display>::fmt(&**self, f) 663 } 664 } 665 666 impl<T, A> fmt::Debug for Box<T, A> 667 where 668 T: ?Sized + fmt::Debug, 669 A: Allocator, 670 { 671 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 672 <T as fmt::Debug>::fmt(&**self, f) 673 } 674 } 675 676 impl<T, A> Drop for Box<T, A> 677 where 678 T: ?Sized, 679 A: Allocator, 680 { 681 fn drop(&mut self) { 682 let layout = Layout::for_value::<T>(self); 683 684 // SAFETY: The pointer in `self.0` is guaranteed to be valid by the type invariant. 685 unsafe { core::ptr::drop_in_place::<T>(self.deref_mut()) }; 686 687 // SAFETY: 688 // - `self.0` was previously allocated with `A`. 689 // - `layout` is equal to the `Layout´ `self.0` was allocated with. 690 unsafe { A::free(self.0.cast(), layout) }; 691 } 692 } 693 694 /// # Examples 695 /// 696 /// ``` 697 /// # use kernel::prelude::*; 698 /// use kernel::alloc::allocator::VmallocPageIter; 699 /// use kernel::page::{AsPageIter, PAGE_SIZE}; 700 /// 701 /// let mut vbox = VBox::new((), GFP_KERNEL)?; 702 /// 703 /// assert!(vbox.page_iter().next().is_none()); 704 /// 705 /// let mut vbox = VBox::<[u8; PAGE_SIZE]>::new_uninit(GFP_KERNEL)?; 706 /// 707 /// let page = vbox.page_iter().next().expect("At least one page should be available.\n"); 708 /// 709 /// // SAFETY: There is no concurrent read or write to the same page. 710 /// unsafe { page.fill_zero_raw(0, PAGE_SIZE)? }; 711 /// # Ok::<(), Error>(()) 712 /// ``` 713 impl<T> AsPageIter for VBox<T> { 714 type Iter<'a> 715 = VmallocPageIter<'a> 716 where 717 T: 'a; 718 719 fn page_iter(&mut self) -> Self::Iter<'_> { 720 let ptr = self.0.cast(); 721 let size = core::mem::size_of::<T>(); 722 723 // SAFETY: 724 // - `ptr` is a valid pointer to the beginning of a `Vmalloc` allocation. 725 // - `ptr` is guaranteed to be valid for the lifetime of `'a`. 726 // - `size` is the size of the `Vmalloc` allocation `ptr` points to. 727 unsafe { VmallocPageIter::new(ptr, size) } 728 } 729 } 730