* [PATCH] rust: transmute: Add implementation for FromBytes trait
@ 2024-10-09 1:47 Christian dos Santos de Lima
2024-10-09 7:37 ` Alice Ryhl
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Christian dos Santos de Lima @ 2024-10-09 1:47 UTC (permalink / raw)
To: rust-for-linux, linux-kernel, Miguel Ojeda, Alex Gaynor,
Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
Andreas Hindborg, Alice Ryhl, Trevor Gross
Add implementation and documentation for FromBytes trait.
Add new feature block in order to allow using ToBytes
and bound to from_bytes_mut function.
Link: https://github.com/Rust-for-Linux/linux/issues/1119
Signed-off-by: Christian dos Santos de Lima <christiansantoslima21@gmail.com>
---
rust/kernel/lib.rs | 2 +
rust/kernel/transmute.rs | 302 +++++++++++++++++++++++++++++++++++++--
2 files changed, 290 insertions(+), 14 deletions(-)
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index dc37aef6a008..5215f5744e12 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -18,6 +18,8 @@
#![feature(lint_reasons)]
#![feature(new_uninit)]
#![feature(unsize)]
+#![feature(portable_simd)]
+#![feature(trivial_bounds)]
// Ensure conditional compilation based on the kernel configuration works;
// otherwise we may silently break things like initcall handling.
diff --git a/rust/kernel/transmute.rs b/rust/kernel/transmute.rs
index 1c7d43771a37..f2d99c136017 100644
--- a/rust/kernel/transmute.rs
+++ b/rust/kernel/transmute.rs
@@ -12,24 +12,298 @@
/// # Safety
///
/// All bit-patterns must be valid for this type. This type must not have interior mutability.
-pub unsafe trait FromBytes {}
+pub unsafe trait FromBytes {
+ ///Converts a slice of Bytes into a Reference to Self
+ ///
+ /// # Examples
+ /// ```
+ /// pub unsafe trait FromBytes {
+ /// unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self;
+ /// unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+ /// where
+ /// Self: ToBytes;
+ /// }
+ ///
+ ///unsafe impl FromBytes for u32 {
+ /// unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+ /// let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+ /// &*slice_ptr
+ /// }
+ ///
+ /// unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+ /// where
+ /// Self: ToBytes,
+ /// {
+ /// let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+ /// &mut *slice_ptr
+ /// }
+ ///}
+ ///
+ ///let slice_of_bytes : &[u8] = &[1, 2, 3, 4];
+ ///let result = u32::from_bytes(slice_of_bytes);
+ ///assert_eq!(*result, 0x4030201);
+ ///```
+ ///# Safety
+ ///
+ ///Guarantee that all values are initiliazed
+ unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self;
+ ///Converts a mutabble slice of Bytes into a mutable Reference to Self
+ /// # Safety
+ ///
+ /// ToBytes in order to allow only types that implements ToBytes
+ unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+ where
+ Self: ToBytes;
+}
-macro_rules! impl_frombytes {
- ($($({$($generics:tt)*})? $t:ty, )*) => {
- // SAFETY: Safety comments written in the macro invocation.
- $(unsafe impl$($($generics)*)? FromBytes for $t {})*
- };
+// SAFETY: All bit patterns are acceptable values of the types below.
+unsafe impl FromBytes for u8 {
+ unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+ unsafe {
+ let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+ &*slice_ptr
+ }
+ }
+
+ unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+ where
+ Self: ToBytes,
+ {
+ unsafe {
+ let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+ &mut *slice_ptr
+ }
+ }
}
-impl_frombytes! {
- // SAFETY: All bit patterns are acceptable values of the types below.
- u8, u16, u32, u64, usize,
- i8, i16, i32, i64, isize,
+unsafe impl FromBytes for u16 {
+ unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+ unsafe {
+ let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+ &*slice_ptr
+ }
+ }
+
+ unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+ where
+ Self: ToBytes,
+ {
+ unsafe {
+ let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+ &mut *slice_ptr
+ }
+ }
+}
+
+unsafe impl FromBytes for u32 {
+ unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+ unsafe {
+ let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+ &*slice_ptr
+ }
+ }
+
+ unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+ where
+ Self: ToBytes,
+ {
+ unsafe {
+ let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+ &mut *slice_ptr
+ }
+ }
+}
+
+unsafe impl FromBytes for u64 {
+ unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+ unsafe {
+ let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+ &*slice_ptr
+ }
+ }
+
+ unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+ where
+ Self: ToBytes,
+ {
+ unsafe {
+ let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+ &mut *slice_ptr
+ }
+ }
+}
+
+unsafe impl FromBytes for usize {
+ unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+ unsafe {
+ let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+ &*slice_ptr
+ }
+ }
+
+ unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+ where
+ Self: ToBytes,
+ {
+ unsafe {
+ let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+ &mut *slice_ptr
+ }
+ }
+}
+
+unsafe impl FromBytes for i8 {
+ unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+ unsafe {
+ let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+ &*slice_ptr
+ }
+ }
+
+ unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+ where
+ Self: ToBytes,
+ {
+ unsafe {
+ let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+ &mut *slice_ptr
+ }
+ }
+}
+
+unsafe impl FromBytes for i16 {
+ unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+ unsafe {
+ let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+ &*slice_ptr
+ }
+ }
+
+ unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+ where
+ Self: ToBytes,
+ {
+ unsafe {
+ let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+ &mut *slice_ptr
+ }
+ }
+}
+
+unsafe impl FromBytes for i32 {
+ unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+ unsafe {
+ let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+ &*slice_ptr
+ }
+ }
+
+ unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+ where
+ Self: ToBytes,
+ {
+ unsafe {
+ let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+ &mut *slice_ptr
+ }
+ }
+}
+
+unsafe impl FromBytes for i64 {
+ unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+ unsafe {
+ let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+ &*slice_ptr
+ }
+ }
+
+ unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+ where
+ Self: ToBytes,
+ {
+ unsafe {
+ let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+ &mut *slice_ptr
+ }
+ }
+}
+
+unsafe impl FromBytes for isize {
+ unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+ unsafe {
+ let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+ &*slice_ptr
+ }
+ }
+
+ unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+ where
+ Self: ToBytes,
+ {
+ unsafe {
+ let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+ &mut *slice_ptr
+ }
+ }
+}
+// SAFETY: If all bit patterns are acceptable for individual values in an array, then all bit
+// patterns are also acceptable for arrays of that type.
+unsafe impl<T: FromBytes> FromBytes for [T] {
+ unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+ unsafe {
+ let slice_ptr = slice_of_bytes.as_ptr() as *const T;
+ let slice_len = slice_of_bytes.len() / core::mem::size_of::<T>();
+ core::slice::from_raw_parts(slice_ptr, slice_len)
+ }
+ }
+
+ unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+ where
+ Self: ToBytes,
+ {
+ unsafe {
+ let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut T;
+ let slice_len = slice_of_bytes.len() / core::mem::size_of::<T>();
+ core::slice::from_raw_parts_mut(slice_ptr, slice_len)
+ }
+ }
+}
+
+/// # Examples
+///```
+///let slice_of_bytes: &[u8] = &[
+/// 1, 0, 0, 0,
+/// 2, 0, 0, 0,
+/// 3, 0, 0, 0,
+/// 4, 0, 0, 0,
+/// 5, 0, 0, 0,
+/// 6, 0, 0, 0,
+/// 7, 0, 0, 0,
+/// 8, 0, 0, 0,
+///];
+///
+///let foo = <[u32; 8]>::from_bytes(slice_of_bytes);
+///let expected: [u32; 8] = [1, 2, 3, 4, 5, 6, 7, 8];
+///
+///assert_eq!(*foo, expected);
+///```
+unsafe impl<T: FromBytes, const N: usize> FromBytes for [T; N] {
+ unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+ unsafe {
+ let slice_ptr = slice_of_bytes.as_ptr() as *const T;
+ &*(slice_ptr as *const [T; N])
+ }
+ }
- // SAFETY: If all bit patterns are acceptable for individual values in an array, then all bit
- // patterns are also acceptable for arrays of that type.
- {<T: FromBytes>} [T],
- {<T: FromBytes, const N: usize>} [T; N],
+ unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+ where
+ Self: ToBytes,
+ {
+ unsafe {
+ let slice_ptr = slice_of_bytes.as_ptr() as *mut T;
+ &mut *(slice_ptr as *mut [T; N])
+ }
+ }
}
/// Types that can be viewed as an immutable slice of initialized bytes.
--
2.46.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] rust: transmute: Add implementation for FromBytes trait
2024-10-09 1:47 [PATCH] rust: transmute: Add implementation for FromBytes trait Christian dos Santos de Lima
@ 2024-10-09 7:37 ` Alice Ryhl
2024-10-09 12:32 ` Miguel Ojeda
2024-10-09 13:03 ` Dirk Behme
2 siblings, 0 replies; 5+ messages in thread
From: Alice Ryhl @ 2024-10-09 7:37 UTC (permalink / raw)
To: Christian dos Santos de Lima
Cc: rust-for-linux, linux-kernel, Miguel Ojeda, Alex Gaynor,
Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
Andreas Hindborg, Trevor Gross
On Wed, Oct 9, 2024 at 3:48 AM Christian dos Santos de Lima
<christiansantoslima21@gmail.com> wrote:
>
> Add implementation and documentation for FromBytes trait.
>
> Add new feature block in order to allow using ToBytes
> and bound to from_bytes_mut function.
>
> Link: https://github.com/Rust-for-Linux/linux/issues/1119
> Signed-off-by: Christian dos Santos de Lima <christiansantoslima21@gmail.com>
> ---
> rust/kernel/lib.rs | 2 +
> rust/kernel/transmute.rs | 302 +++++++++++++++++++++++++++++++++++++--
> 2 files changed, 290 insertions(+), 14 deletions(-)
>
> diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
> index dc37aef6a008..5215f5744e12 100644
> --- a/rust/kernel/lib.rs
> +++ b/rust/kernel/lib.rs
> @@ -18,6 +18,8 @@
> #![feature(lint_reasons)]
> #![feature(new_uninit)]
> #![feature(unsize)]
> +#![feature(portable_simd)]
> +#![feature(trivial_bounds)]
New unstable features must come with a good justification. Why are you
adding these? Why can't we avoid adding them? This information needs
to be in the commit message.
Alice
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] rust: transmute: Add implementation for FromBytes trait
2024-10-09 1:47 [PATCH] rust: transmute: Add implementation for FromBytes trait Christian dos Santos de Lima
2024-10-09 7:37 ` Alice Ryhl
@ 2024-10-09 12:32 ` Miguel Ojeda
2024-10-09 13:03 ` Dirk Behme
2 siblings, 0 replies; 5+ messages in thread
From: Miguel Ojeda @ 2024-10-09 12:32 UTC (permalink / raw)
To: Christian dos Santos de Lima
Cc: rust-for-linux, linux-kernel, Miguel Ojeda, Alex Gaynor,
Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
Andreas Hindborg, Alice Ryhl, Trevor Gross
On Wed, Oct 9, 2024 at 3:48 AM Christian dos Santos de Lima
<christiansantoslima21@gmail.com> wrote:
>
> +pub unsafe trait FromBytes {
> + ///Converts a slice of Bytes into a Reference to Self
> + ///
> + /// # Examples
> + /// ```
> + /// pub unsafe trait FromBytes {
Apart from what Alice mentions (which is critical, since we are
looking to get into stable Rust as soon as feasible -- please see
https://rust-for-linux.com/unstable-features#usage-in-the-kernel),
please also format the code, documentation and examples appropriately
(please see other files to see how it is usually done, we mostly
follow Rust's standard library conventions).
> + unsafe {
> + let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
> + &*slice_ptr
> + }
Please note that we require `// SAFETY` comments too. Missing those is
already a warning/error (depending on the kernel configuration) in
rust-next.
Thanks for the patch!
Cheers,
Miguel
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] rust: transmute: Add implementation for FromBytes trait
2024-10-09 1:47 [PATCH] rust: transmute: Add implementation for FromBytes trait Christian dos Santos de Lima
2024-10-09 7:37 ` Alice Ryhl
2024-10-09 12:32 ` Miguel Ojeda
@ 2024-10-09 13:03 ` Dirk Behme
2024-10-09 16:35 ` Benno Lossin
2 siblings, 1 reply; 5+ messages in thread
From: Dirk Behme @ 2024-10-09 13:03 UTC (permalink / raw)
To: Christian dos Santos de Lima, rust-for-linux, linux-kernel,
Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross
Am 09.10.24 um 03:47 schrieb Christian dos Santos de Lima:
> Add implementation and documentation for FromBytes trait.
>
> Add new feature block in order to allow using ToBytes
> and bound to from_bytes_mut function.
>
> Link: https://github.com/Rust-for-Linux/linux/issues/1119
> Signed-off-by: Christian dos Santos de Lima <christiansantoslima21@gmail.com>
> ---
> rust/kernel/lib.rs | 2 +
> rust/kernel/transmute.rs | 302 +++++++++++++++++++++++++++++++++++++--
> 2 files changed, 290 insertions(+), 14 deletions(-)
>
...
> --- a/rust/kernel/transmute.rs
> +++ b/rust/kernel/transmute.rs
...
> +unsafe impl FromBytes for u8 {
...
> +unsafe impl FromBytes for u16 {
...
> +unsafe impl FromBytes for u32 {
...
> +unsafe impl FromBytes for u64 {
...
> +unsafe impl FromBytes for usize {
...
> +unsafe impl FromBytes for i8 {
...
> +unsafe impl FromBytes for i16 {
...
> +unsafe impl FromBytes for i32 {
...
> +unsafe impl FromBytes for i64 {
...
> +unsafe impl FromBytes for isize {
...
Asahi Lina's device tree code which reads the device tree node's data
as a byte slice and then has to convert it
https://github.com/Fabo/linux/blob/9e496b356ee8e25f9bee9258491aa6ae3a4f1ddf/rust/kernel/of.rs#L390
uses macros to avoid code dublication:
prop_int_type!(u8);
prop_int_type!(u16);
prop_int_type!(u32);
prop_int_type!(u64);
prop_int_type!(i8);
prop_int_type!(i16);
prop_int_type!(i32);
prop_int_type!(i64);
Would anything like this be possible here, as well? To avoid code
dublication?
Best regards
Dirk
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] rust: transmute: Add implementation for FromBytes trait
2024-10-09 13:03 ` Dirk Behme
@ 2024-10-09 16:35 ` Benno Lossin
0 siblings, 0 replies; 5+ messages in thread
From: Benno Lossin @ 2024-10-09 16:35 UTC (permalink / raw)
To: Dirk Behme, Christian dos Santos de Lima, rust-for-linux,
linux-kernel, Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Andreas Hindborg, Alice Ryhl, Trevor Gross
On 09.10.24 15:03, Dirk Behme wrote:
> Am 09.10.24 um 03:47 schrieb Christian dos Santos de Lima:
>> Add implementation and documentation for FromBytes trait.
>>
>> Add new feature block in order to allow using ToBytes
>> and bound to from_bytes_mut function.
>>
>> Link: https://github.com/Rust-for-Linux/linux/issues/1119
>> Signed-off-by: Christian dos Santos de Lima <christiansantoslima21@gmail.com>
>> ---
>> rust/kernel/lib.rs | 2 +
>> rust/kernel/transmute.rs | 302 +++++++++++++++++++++++++++++++++++++--
>> 2 files changed, 290 insertions(+), 14 deletions(-)
>>
> ...
>> --- a/rust/kernel/transmute.rs
>> +++ b/rust/kernel/transmute.rs
> ...
>> +unsafe impl FromBytes for u8 {
> ...
>> +unsafe impl FromBytes for u16 {
> ...
>> +unsafe impl FromBytes for u32 {
> ...
>> +unsafe impl FromBytes for u64 {
> ...
>> +unsafe impl FromBytes for usize {
> ...
>> +unsafe impl FromBytes for i8 {
> ...
>> +unsafe impl FromBytes for i16 {
> ...
>> +unsafe impl FromBytes for i32 {
> ...
>> +unsafe impl FromBytes for i64 {
> ...
>> +unsafe impl FromBytes for isize {
> ...
>
> Asahi Lina's device tree code which reads the device tree node's data
> as a byte slice and then has to convert it
>
> https://github.com/Fabo/linux/blob/9e496b356ee8e25f9bee9258491aa6ae3a4f1ddf/rust/kernel/of.rs#L390
>
> uses macros to avoid code dublication:
>
> prop_int_type!(u8);
> prop_int_type!(u16);
> prop_int_type!(u32);
> prop_int_type!(u64);
> prop_int_type!(i8);
> prop_int_type!(i16);
> prop_int_type!(i32);
> prop_int_type!(i64);
>
> Would anything like this be possible here, as well? To avoid code
> dublication?
Yes please, create a macro.
---
Cheers,
Benno
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2024-10-09 16:36 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-09 1:47 [PATCH] rust: transmute: Add implementation for FromBytes trait Christian dos Santos de Lima
2024-10-09 7:37 ` Alice Ryhl
2024-10-09 12:32 ` Miguel Ojeda
2024-10-09 13:03 ` Dirk Behme
2024-10-09 16:35 ` Benno Lossin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).