lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <f421387a-6797-487f-843d-2c67811d8f68@nvidia.com>
Date: Fri, 5 Sep 2025 14:45:43 -0400
From: Joel Fernandes <joelagnelf@...dia.com>
To: Yury Norov <yury.norov@...il.com>
Cc: linux-kernel@...r.kernel.org, Danilo Krummrich <dakr@...nel.org>,
 Alexandre Courbot <acourbot@...dia.com>, David Airlie <airlied@...il.com>,
 Simona Vetter <simona@...ll.ch>, Miguel Ojeda <ojeda@...nel.org>,
 Alex Gaynor <alex.gaynor@...il.com>, Boqun Feng <boqun.feng@...il.com>,
 Gary Guo <gary@...yguo.net>, Björn Roy Baron
 <bjorn3_gh@...tonmail.com>, Benno Lossin <lossin@...nel.org>,
 Andreas Hindborg <a.hindborg@...nel.org>, Alice Ryhl <aliceryhl@...gle.com>,
 Trevor Gross <tmgross@...ch.edu>, John Hubbard <jhubbard@...dia.com>,
 Alistair Popple <apopple@...dia.com>, nouveau@...ts.freedesktop.org,
 dri-devel@...ts.freedesktop.org, rust-for-linux@...r.kernel.org
Subject: Re: [PATCH 1/2] nova-core: Add a library for bitfields in Rust
 structs



On 9/4/2025 5:35 PM, Yury Norov wrote:
> Hi Joel,
> 
> (Thanks to John for referencing this.)
> 
> On Sun, Aug 24, 2025 at 09:59:52AM -0400, Joel Fernandes wrote:
>> Add a minimal bitfield library for defining in Rust structures (called
>> bitstruct), similar in concept to bit fields in C structs.
> 
> So maybe name it bitfield?

Sure, that sounds good to me. I wanted the name "struct" in it, but I guess
since a caller is expected to pass "struct" in the invocation, it should be
good, in fact better because "bitfield" adds more information, so thank you!

> 
>> This will be used
>> for defining page table entries and other structures in nova-core.
> 
> I think this is understatement, and this will find a broader use. :)

Thanks :)

> 
>> Signed-off-by: Joel Fernandes <joelagnelf@...dia.com>
> 
> I agree with the others that this bitstruct is worth to live in core
> directory. I just merged bitmap wrapper in rust/kernel/bitmap.rs, and
> I think this one should go in rust/kernel/bitstruct.rs (or bitfield.rs?).

Sure, bitfield.rs sounds good to me.

> 
> Can you please consider this change for v2, and also add the new file in
> BITOPS API record in MAINTAINERS?

Yes.

[...]>> +/// # Example (just for illustration)
>> +/// ```rust
>> +/// bitstruct! {
>> +///     #[repr(u64)]
>> +///     pub struct PageTableEntry {
>> +///         0:0       present     as bool,
>> +///         1:1       writable    as bool,
>> +///         11:9      available   as u8,
>> +///         51:12     pfn         as u64,
>> +///         62:52     available2  as u16,
>> +///         63:63     nx          as bool,
>> +///     }
>> +/// }
> 
> Is it possible to create overlapping fields? Should we allow that?
> (I guess yes.) Does your machinery handle it correctly now?
> 
> If the answer is yes, can you add a test for it?

It is possible, but it is an unintended side effect. It is not the primary use
case though, but also there is no harm in doing it if the user needs it. I will
add a test case, I will include this in the K-Unit test in v3.

> 
>> +/// ```
>> +///
>> +/// This generates a struct with methods:
>> +/// - Constructor: `default()` sets all bits to zero.
>> +/// - Field accessors: `present()`, `pfn()`, etc.
>> +/// - Field setters: `set_present()`, `set_pfn()`, etc.
>> +/// - Builder methods: `with_present()`, `with_pfn()`, etc.
>> +/// - Raw conversion: `from_raw()`, `into_raw()`
>> +#[allow(unused_macros)]
>> +macro_rules! bitstruct {
>> +    (
>> +        #[repr($storage:ty)]
>> +        $vis:vis struct $name:ident {
>> +            $(
>> +                $hi:literal : $lo:literal $field:ident as $field_type:tt
>> +            ),* $(,)?
>> +        }
>> +    ) => {
>> +        #[repr(transparent)]
>> +        #[derive(Copy, Clone, Default)]
>> +        $vis struct $name($storage);
>> +
>> +        impl $name {
>> +            /// Create from raw value
>> +            #[inline(always)]
>> +            $vis const fn from_raw(val: $storage) -> Self {
>> +                Self(val)
>> +            }
>> +
>> +            /// Get raw value
>> +            #[inline(always)]
>> +            $vis const fn into_raw(self) -> $storage {
>> +                self.0
>> +            }
>> +        }
>> +
>> +        impl core::fmt::Debug for $name {
>> +            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
>> +                write!(f, "{}({:#x})", stringify!($name), self.0)
>> +            }
>> +        }
>> +
>> +        // Generate all field methods
>> +        $(
>> +            bitstruct_field_impl!($vis, $name, $storage, $hi, $lo, $field as $field_type);
>> +        )*
>> +    };
>> +}
>> +
>> +/// Helper to calculate mask for bit fields
>> +#[allow(unused_macros)]
>> +macro_rules! bitstruct_mask {
>> +    ($hi:literal, $lo:literal, $storage:ty) => {{
>> +        let width = ($hi - $lo + 1) as usize;
>> +        let storage_bits = 8 * core::mem::size_of::<$storage>();
> 
> Does this '8' mean BITS_PER_BYTE? If so, we've got BITS_PER_TYPE() macro. Can
> you use it here?
> 
>> +        if width >= storage_bits {
>> +            <$storage>::MAX
> 
> This is an attempt to make an out-of-boundary access. Maybe print a
> warning or similar? 

Only width > storage_bits is out-of-boundary. Also in v2 [1] I completely
replaced this part with genmask, so we are no longer calculating WIDTH.

+        const [<$field:upper _MASK>]: $storage = {
+            // Generate mask for shifting
+            match ::core::mem::size_of::<$storage>() {
+                1 => ::kernel::bits::genmask_u8($lo..=$hi) as $storage,
+                2 => ::kernel::bits::genmask_u16($lo..=$hi) as $storage,
+                4 => ::kernel::bits::genmask_u32($lo..=$hi) as $storage,
+                8 => ::kernel::bits::genmask_u64($lo..=$hi) as $storage,
+                _ => <$storage>::MAX
+            }
+        };

I could add a build_assert here though to make sure size_of($storage) > ($hi -
$lo), but I think genmask already has a build_assert:
                build_assert!(n < <$ty>::BITS);
so it may not be needed.

[1] https://lore.kernel.org/all/20250903215428.1296517-3-joelagnelf@nvidia.com/

thanks,

 - Joel


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ