diff options
Diffstat (limited to 'rust/kernel/alloc')
| -rw-r--r-- | rust/kernel/alloc/kbox.rs | 53 | ||||
| -rw-r--r-- | rust/kernel/alloc/layout.rs | 19 | 
2 files changed, 61 insertions, 11 deletions
| diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs index 9ce414361c2c..cb4ebea3b074 100644 --- a/rust/kernel/alloc/kbox.rs +++ b/rust/kernel/alloc/kbox.rs @@ -354,22 +354,30 @@ where      A: Allocator,  {      type Borrowed<'a> = &'a T; +    type BorrowedMut<'a> = &'a mut T; -    fn into_foreign(self) -> *const crate::ffi::c_void { -        Box::into_raw(self) as _ +    fn into_foreign(self) -> *mut crate::ffi::c_void { +        Box::into_raw(self).cast()      } -    unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self { +    unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self {          // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous          // call to `Self::into_foreign`. -        unsafe { Box::from_raw(ptr as _) } +        unsafe { Box::from_raw(ptr.cast()) }      } -    unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> &'a T { +    unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> &'a T {          // SAFETY: The safety requirements of this method ensure that the object remains alive and          // immutable for the duration of 'a.          unsafe { &*ptr.cast() }      } + +    unsafe fn borrow_mut<'a>(ptr: *mut crate::ffi::c_void) -> &'a mut T { +        let ptr = ptr.cast(); +        // SAFETY: The safety requirements of this method ensure that the pointer is valid and that +        // nothing else will access the value for the duration of 'a. +        unsafe { &mut *ptr } +    }  }  impl<T: 'static, A> ForeignOwnable for Pin<Box<T, A>> @@ -377,19 +385,20 @@ where      A: Allocator,  {      type Borrowed<'a> = Pin<&'a T>; +    type BorrowedMut<'a> = Pin<&'a mut T>; -    fn into_foreign(self) -> *const crate::ffi::c_void { +    fn into_foreign(self) -> *mut crate::ffi::c_void {          // SAFETY: We are still treating the box as pinned. -        Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }) as _ +        Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }).cast()      } -    unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self { +    unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self {          // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous          // call to `Self::into_foreign`. -        unsafe { Pin::new_unchecked(Box::from_raw(ptr as _)) } +        unsafe { Pin::new_unchecked(Box::from_raw(ptr.cast())) }      } -    unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> Pin<&'a T> { +    unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> Pin<&'a T> {          // SAFETY: The safety requirements for this function ensure that the object is still alive,          // so it is safe to dereference the raw pointer.          // The safety requirements of `from_foreign` also ensure that the object remains alive for @@ -399,6 +408,18 @@ where          // SAFETY: This pointer originates from a `Pin<Box<T>>`.          unsafe { Pin::new_unchecked(r) }      } + +    unsafe fn borrow_mut<'a>(ptr: *mut crate::ffi::c_void) -> Pin<&'a mut T> { +        let ptr = ptr.cast(); +        // SAFETY: The safety requirements for this function ensure that the object is still alive, +        // so it is safe to dereference the raw pointer. +        // The safety requirements of `from_foreign` also ensure that the object remains alive for +        // the lifetime of the returned value. +        let r = unsafe { &mut *ptr }; + +        // SAFETY: This pointer originates from a `Pin<Box<T>>`. +        unsafe { Pin::new_unchecked(r) } +    }  }  impl<T, A> Deref for Box<T, A> @@ -427,13 +448,23 @@ where      }  } +impl<T, A> fmt::Display for Box<T, A> +where +    T: ?Sized + fmt::Display, +    A: Allocator, +{ +    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { +        <T as fmt::Display>::fmt(&**self, f) +    } +} +  impl<T, A> fmt::Debug for Box<T, A>  where      T: ?Sized + fmt::Debug,      A: Allocator,  {      fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -        fmt::Debug::fmt(&**self, f) +        <T as fmt::Debug>::fmt(&**self, f)      }  } diff --git a/rust/kernel/alloc/layout.rs b/rust/kernel/alloc/layout.rs index 4b3cd7fdc816..93ed514f7cc7 100644 --- a/rust/kernel/alloc/layout.rs +++ b/rust/kernel/alloc/layout.rs @@ -43,6 +43,25 @@ impl<T> ArrayLayout<T> {      /// # Errors      ///      /// When `len * size_of::<T>()` overflows or when `len * size_of::<T>() > isize::MAX`. +    /// +    /// # Examples +    /// +    /// ``` +    /// # use kernel::alloc::layout::{ArrayLayout, LayoutError}; +    /// let layout = ArrayLayout::<i32>::new(15)?; +    /// assert_eq!(layout.len(), 15); +    /// +    /// // Errors because `len * size_of::<T>()` overflows. +    /// let layout = ArrayLayout::<i32>::new(isize::MAX as usize); +    /// assert!(layout.is_err()); +    /// +    /// // Errors because `len * size_of::<i32>() > isize::MAX`, +    /// // even though `len < isize::MAX`. +    /// let layout = ArrayLayout::<i32>::new(isize::MAX as usize / 2); +    /// assert!(layout.is_err()); +    /// +    /// # Ok::<(), Error>(()) +    /// ```      pub const fn new(len: usize) -> Result<Self, LayoutError> {          match len.checked_mul(core::mem::size_of::<T>()) {              Some(size) if size <= ISIZE_MAX => { | 
