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