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 /// Constructs a new `Pin<Box<T, A>>`. If `T` does not implement [`Unpin`], then `x` will be 283 /// pinned in memory and can't be moved. 284 #[inline] 285 pub fn pin(x: T, flags: Flags) -> Result<Pin<Box<T, A>>, AllocError> 286 where 287 A: 'static, 288 { 289 Ok(Self::new(x, flags)?.into()) 290 } 291 292 /// Construct a pinned slice of elements `Pin<Box<[T], A>>`. 293 /// 294 /// This is a convenient means for creation of e.g. slices of structrures containing spinlocks 295 /// or mutexes. 296 /// 297 /// # Examples 298 /// 299 /// ``` 300 /// use kernel::sync::{new_spinlock, SpinLock}; 301 /// 302 /// struct Inner { 303 /// a: u32, 304 /// b: u32, 305 /// } 306 /// 307 /// #[pin_data] 308 /// struct Example { 309 /// c: u32, 310 /// #[pin] 311 /// d: SpinLock<Inner>, 312 /// } 313 /// 314 /// impl Example { 315 /// fn new() -> impl PinInit<Self, Error> { 316 /// try_pin_init!(Self { 317 /// c: 10, 318 /// d <- new_spinlock!(Inner { a: 20, b: 30 }), 319 /// }) 320 /// } 321 /// } 322 /// 323 /// // Allocate a boxed slice of 10 `Example`s. 324 /// let s = KBox::pin_slice( 325 /// | _i | Example::new(), 326 /// 10, 327 /// GFP_KERNEL 328 /// )?; 329 /// 330 /// assert_eq!(s[5].c, 10); 331 /// assert_eq!(s[3].d.lock().a, 20); 332 /// # Ok::<(), Error>(()) 333 /// ``` 334 pub fn pin_slice<Func, Item, E>( 335 mut init: Func, 336 len: usize, 337 flags: Flags, 338 ) -> Result<Pin<Box<[T], A>>, E> 339 where 340 Func: FnMut(usize) -> Item, 341 Item: PinInit<T, E>, 342 E: From<AllocError>, 343 { 344 let mut buffer = super::Vec::<T, A>::with_capacity(len, flags)?; 345 for i in 0..len { 346 let ptr = buffer.spare_capacity_mut().as_mut_ptr().cast(); 347 // SAFETY: 348 // - `ptr` is a valid pointer to uninitialized memory. 349 // - `ptr` is not used if an error is returned. 350 // - `ptr` won't be moved until it is dropped, i.e. it is pinned. 351 unsafe { init(i).__pinned_init(ptr)? }; 352 353 // SAFETY: 354 // - `i + 1 <= len`, hence we don't exceed the capacity, due to the call to 355 // `with_capacity()` above. 356 // - The new value at index buffer.len() + 1 is the only element being added here, and 357 // it has been initialized above by `init(i).__pinned_init(ptr)`. 358 unsafe { buffer.inc_len(1) }; 359 } 360 361 let (ptr, _, _) = buffer.into_raw_parts(); 362 let slice = core::ptr::slice_from_raw_parts_mut(ptr, len); 363 364 // SAFETY: `slice` points to an allocation allocated with `A` (`buffer`) and holds a valid 365 // `[T]`. 366 Ok(Pin::from(unsafe { Box::from_raw(slice) })) 367 } 368 369 /// Convert a [`Box<T,A>`] to a [`Pin<Box<T,A>>`]. If `T` does not implement 370 /// [`Unpin`], then `x` will be pinned in memory and can't be moved. 371 pub fn into_pin(this: Self) -> Pin<Self> { 372 this.into() 373 } 374 375 /// Forgets the contents (does not run the destructor), but keeps the allocation. 376 fn forget_contents(this: Self) -> Box<MaybeUninit<T>, A> { 377 let ptr = Self::into_raw(this); 378 379 // SAFETY: `ptr` is valid, because it came from `Box::into_raw`. 380 unsafe { Box::from_raw(ptr.cast()) } 381 } 382 383 /// Drops the contents, but keeps the allocation. 384 /// 385 /// # Examples 386 /// 387 /// ``` 388 /// let value = KBox::new([0; 32], GFP_KERNEL)?; 389 /// assert_eq!(*value, [0; 32]); 390 /// let value = KBox::drop_contents(value); 391 /// // Now we can re-use `value`: 392 /// let value = KBox::write(value, [1; 32]); 393 /// assert_eq!(*value, [1; 32]); 394 /// # Ok::<(), Error>(()) 395 /// ``` 396 pub fn drop_contents(this: Self) -> Box<MaybeUninit<T>, A> { 397 let ptr = this.0.as_ptr(); 398 399 // SAFETY: `ptr` is valid, because it came from `this`. After this call we never access the 400 // value stored in `this` again. 401 unsafe { core::ptr::drop_in_place(ptr) }; 402 403 Self::forget_contents(this) 404 } 405 406 /// Moves the `Box`'s value out of the `Box` and consumes the `Box`. 407 pub fn into_inner(b: Self) -> T { 408 // SAFETY: By the type invariant `&*b` is valid for `read`. 409 let value = unsafe { core::ptr::read(&*b) }; 410 let _ = Self::forget_contents(b); 411 value 412 } 413 } 414 415 impl<T, A> From<Box<T, A>> for Pin<Box<T, A>> 416 where 417 T: ?Sized, 418 A: Allocator, 419 { 420 /// Converts a `Box<T, A>` into a `Pin<Box<T, A>>`. If `T` does not implement [`Unpin`], then 421 /// `*b` will be pinned in memory and can't be moved. 422 /// 423 /// This moves `b` into `Pin` without moving `*b` or allocating and copying any memory. 424 fn from(b: Box<T, A>) -> Self { 425 // SAFETY: The value wrapped inside a `Pin<Box<T, A>>` cannot be moved or replaced as long 426 // as `T` does not implement `Unpin`. 427 unsafe { Pin::new_unchecked(b) } 428 } 429 } 430 431 impl<T, A> InPlaceWrite<T> for Box<MaybeUninit<T>, A> 432 where 433 A: Allocator + 'static, 434 { 435 type Initialized = Box<T, A>; 436 437 fn write_init<E>(mut self, init: impl Init<T, E>) -> Result<Self::Initialized, E> { 438 let slot = self.as_mut_ptr(); 439 // SAFETY: When init errors/panics, slot will get deallocated but not dropped, 440 // slot is valid. 441 unsafe { init.__init(slot)? }; 442 // SAFETY: All fields have been initialized. 443 Ok(unsafe { Box::assume_init(self) }) 444 } 445 446 fn write_pin_init<E>(mut self, init: impl PinInit<T, E>) -> Result<Pin<Self::Initialized>, E> { 447 let slot = self.as_mut_ptr(); 448 // SAFETY: When init errors/panics, slot will get deallocated but not dropped, 449 // slot is valid and will not be moved, because we pin it later. 450 unsafe { init.__pinned_init(slot)? }; 451 // SAFETY: All fields have been initialized. 452 Ok(unsafe { Box::assume_init(self) }.into()) 453 } 454 } 455 456 impl<T, A> InPlaceInit<T> for Box<T, A> 457 where 458 A: Allocator + 'static, 459 { 460 type PinnedSelf = Pin<Self>; 461 462 #[inline] 463 fn try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Pin<Self>, E> 464 where 465 E: From<AllocError>, 466 { 467 Box::<_, A>::new_uninit(flags)?.write_pin_init(init) 468 } 469 470 #[inline] 471 fn try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E> 472 where 473 E: From<AllocError>, 474 { 475 Box::<_, A>::new_uninit(flags)?.write_init(init) 476 } 477 } 478 479 // SAFETY: The pointer returned by `into_foreign` comes from a well aligned 480 // pointer to `T` allocated by `A`. 481 unsafe impl<T: 'static, A> ForeignOwnable for Box<T, A> 482 where 483 A: Allocator, 484 { 485 const FOREIGN_ALIGN: usize = if core::mem::align_of::<T>() < A::MIN_ALIGN { 486 A::MIN_ALIGN 487 } else { 488 core::mem::align_of::<T>() 489 }; 490 491 type Borrowed<'a> = &'a T; 492 type BorrowedMut<'a> = &'a mut T; 493 494 fn into_foreign(self) -> *mut c_void { 495 Box::into_raw(self).cast() 496 } 497 498 unsafe fn from_foreign(ptr: *mut c_void) -> Self { 499 // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous 500 // call to `Self::into_foreign`. 501 unsafe { Box::from_raw(ptr.cast()) } 502 } 503 504 unsafe fn borrow<'a>(ptr: *mut c_void) -> &'a T { 505 // SAFETY: The safety requirements of this method ensure that the object remains alive and 506 // immutable for the duration of 'a. 507 unsafe { &*ptr.cast() } 508 } 509 510 unsafe fn borrow_mut<'a>(ptr: *mut c_void) -> &'a mut T { 511 let ptr = ptr.cast(); 512 // SAFETY: The safety requirements of this method ensure that the pointer is valid and that 513 // nothing else will access the value for the duration of 'a. 514 unsafe { &mut *ptr } 515 } 516 } 517 518 // SAFETY: The pointer returned by `into_foreign` comes from a well aligned 519 // pointer to `T` allocated by `A`. 520 unsafe impl<T: 'static, A> ForeignOwnable for Pin<Box<T, A>> 521 where 522 A: Allocator, 523 { 524 const FOREIGN_ALIGN: usize = <Box<T, A> as ForeignOwnable>::FOREIGN_ALIGN; 525 type Borrowed<'a> = Pin<&'a T>; 526 type BorrowedMut<'a> = Pin<&'a mut T>; 527 528 fn into_foreign(self) -> *mut c_void { 529 // SAFETY: We are still treating the box as pinned. 530 Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }).cast() 531 } 532 533 unsafe fn from_foreign(ptr: *mut c_void) -> Self { 534 // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous 535 // call to `Self::into_foreign`. 536 unsafe { Pin::new_unchecked(Box::from_raw(ptr.cast())) } 537 } 538 539 unsafe fn borrow<'a>(ptr: *mut c_void) -> Pin<&'a T> { 540 // SAFETY: The safety requirements for this function ensure that the object is still alive, 541 // so it is safe to dereference the raw pointer. 542 // The safety requirements of `from_foreign` also ensure that the object remains alive for 543 // the lifetime of the returned value. 544 let r = unsafe { &*ptr.cast() }; 545 546 // SAFETY: This pointer originates from a `Pin<Box<T>>`. 547 unsafe { Pin::new_unchecked(r) } 548 } 549 550 unsafe fn borrow_mut<'a>(ptr: *mut c_void) -> Pin<&'a mut T> { 551 let ptr = ptr.cast(); 552 // SAFETY: The safety requirements for this function ensure that the object is still alive, 553 // so it is safe to dereference the raw pointer. 554 // The safety requirements of `from_foreign` also ensure that the object remains alive for 555 // the lifetime of the returned value. 556 let r = unsafe { &mut *ptr }; 557 558 // SAFETY: This pointer originates from a `Pin<Box<T>>`. 559 unsafe { Pin::new_unchecked(r) } 560 } 561 } 562 563 impl<T, A> Deref for Box<T, A> 564 where 565 T: ?Sized, 566 A: Allocator, 567 { 568 type Target = T; 569 570 fn deref(&self) -> &T { 571 // SAFETY: `self.0` is always properly aligned, dereferenceable and points to an initialized 572 // instance of `T`. 573 unsafe { self.0.as_ref() } 574 } 575 } 576 577 impl<T, A> DerefMut for Box<T, A> 578 where 579 T: ?Sized, 580 A: Allocator, 581 { 582 fn deref_mut(&mut self) -> &mut T { 583 // SAFETY: `self.0` is always properly aligned, dereferenceable and points to an initialized 584 // instance of `T`. 585 unsafe { self.0.as_mut() } 586 } 587 } 588 589 /// # Examples 590 /// 591 /// ``` 592 /// # use core::borrow::Borrow; 593 /// # use kernel::alloc::KBox; 594 /// struct Foo<B: Borrow<u32>>(B); 595 /// 596 /// // Owned instance. 597 /// let owned = Foo(1); 598 /// 599 /// // Owned instance using `KBox`. 600 /// let owned_kbox = Foo(KBox::new(1, GFP_KERNEL)?); 601 /// 602 /// let i = 1; 603 /// // Borrowed from `i`. 604 /// let borrowed = Foo(&i); 605 /// # Ok::<(), Error>(()) 606 /// ``` 607 impl<T, A> Borrow<T> for Box<T, A> 608 where 609 T: ?Sized, 610 A: Allocator, 611 { 612 fn borrow(&self) -> &T { 613 self.deref() 614 } 615 } 616 617 /// # Examples 618 /// 619 /// ``` 620 /// # use core::borrow::BorrowMut; 621 /// # use kernel::alloc::KBox; 622 /// struct Foo<B: BorrowMut<u32>>(B); 623 /// 624 /// // Owned instance. 625 /// let owned = Foo(1); 626 /// 627 /// // Owned instance using `KBox`. 628 /// let owned_kbox = Foo(KBox::new(1, GFP_KERNEL)?); 629 /// 630 /// let mut i = 1; 631 /// // Borrowed from `i`. 632 /// let borrowed = Foo(&mut i); 633 /// # Ok::<(), Error>(()) 634 /// ``` 635 impl<T, A> BorrowMut<T> for Box<T, A> 636 where 637 T: ?Sized, 638 A: Allocator, 639 { 640 fn borrow_mut(&mut self) -> &mut T { 641 self.deref_mut() 642 } 643 } 644 645 impl<T, A> fmt::Display for Box<T, A> 646 where 647 T: ?Sized + fmt::Display, 648 A: Allocator, 649 { 650 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 651 <T as fmt::Display>::fmt(&**self, f) 652 } 653 } 654 655 impl<T, A> fmt::Debug for Box<T, A> 656 where 657 T: ?Sized + fmt::Debug, 658 A: Allocator, 659 { 660 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 661 <T as fmt::Debug>::fmt(&**self, f) 662 } 663 } 664 665 impl<T, A> Drop for Box<T, A> 666 where 667 T: ?Sized, 668 A: Allocator, 669 { 670 fn drop(&mut self) { 671 let layout = Layout::for_value::<T>(self); 672 673 // SAFETY: The pointer in `self.0` is guaranteed to be valid by the type invariant. 674 unsafe { core::ptr::drop_in_place::<T>(self.deref_mut()) }; 675 676 // SAFETY: 677 // - `self.0` was previously allocated with `A`. 678 // - `layout` is equal to the `Layout´ `self.0` was allocated with. 679 unsafe { A::free(self.0.cast(), layout) }; 680 } 681 } 682 683 /// # Examples 684 /// 685 /// ``` 686 /// # use kernel::prelude::*; 687 /// use kernel::alloc::allocator::VmallocPageIter; 688 /// use kernel::page::{AsPageIter, PAGE_SIZE}; 689 /// 690 /// let mut vbox = VBox::new((), GFP_KERNEL)?; 691 /// 692 /// assert!(vbox.page_iter().next().is_none()); 693 /// 694 /// let mut vbox = VBox::<[u8; PAGE_SIZE]>::new_uninit(GFP_KERNEL)?; 695 /// 696 /// let page = vbox.page_iter().next().expect("At least one page should be available.\n"); 697 /// 698 /// // SAFETY: There is no concurrent read or write to the same page. 699 /// unsafe { page.fill_zero_raw(0, PAGE_SIZE)? }; 700 /// # Ok::<(), Error>(()) 701 /// ``` 702 impl<T> AsPageIter for VBox<T> { 703 type Iter<'a> 704 = VmallocPageIter<'a> 705 where 706 T: 'a; 707 708 fn page_iter(&mut self) -> Self::Iter<'_> { 709 let ptr = self.0.cast(); 710 let size = core::mem::size_of::<T>(); 711 712 // SAFETY: 713 // - `ptr` is a valid pointer to the beginning of a `Vmalloc` allocation. 714 // - `ptr` is guaranteed to be valid for the lifetime of `'a`. 715 // - `size` is the size of the `Vmalloc` allocation `ptr` points to. 716 unsafe { VmallocPageIter::new(ptr, size) } 717 } 718 } 719