Re: [PATCH 09/22] rust: pin-init: move impl `Zeroable` for `Opaque` and `Option<KBox<T>>` into the kernel crate
From: Alice Ryhl
Date: Wed Mar 05 2025 - 07:11:34 EST
On Wed, Mar 5, 2025 at 1:05 PM Benno Lossin <benno.lossin@xxxxxxxxx> wrote:
>
> On Wed Mar 5, 2025 at 12:26 PM CET, Andreas Hindborg wrote:
> > "Benno Lossin" <benno.lossin@xxxxxxxxx> writes:
> >
> >> In order to make pin-init a standalone crate, move kernel-specific code
> >> directly into the kernel crate. Since `Opaque<T>` and `KBox<T>` are part
> >> of the kernel, move their `Zeroable` implementation into the kernel
> >> crate.
> >>
> >> Signed-off-by: Benno Lossin <benno.lossin@xxxxxxxxx>
> >> ---
> >> rust/kernel/alloc/kbox.rs | 8 +++++++-
> >> rust/kernel/types.rs | 5 ++++-
> >> rust/pin-init/src/lib.rs | 8 +-------
> >> 3 files changed, 12 insertions(+), 9 deletions(-)
> >>
> >> diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs
> >> index 39a3ea7542da..9861433559dc 100644
> >> --- a/rust/kernel/alloc/kbox.rs
> >> +++ b/rust/kernel/alloc/kbox.rs
> >> @@ -15,7 +15,7 @@
> >> use core::ptr::NonNull;
> >> use core::result::Result;
> >>
> >> -use crate::init::{InPlaceWrite, Init, PinInit};
> >> +use crate::init::{InPlaceWrite, Init, PinInit, Zeroable};
> >> use crate::init_ext::InPlaceInit;
> >> use crate::types::ForeignOwnable;
> >>
> >> @@ -100,6 +100,12 @@
> >> /// ```
> >> pub type KVBox<T> = Box<T, super::allocator::KVmalloc>;
> >>
> >> +// SAFETY: All zeros is equivalent to `None` (option layout optimization guarantee).
> >> +//
> >> +// In this case we are allowed to use `T: ?Sized`, since all zeros is the `None` variant and there
> >> +// is no problem with a VTABLE pointer being null.
> >> +unsafe impl<T: ?Sized, A: Allocator> Zeroable for Option<Box<T, A>> {}
> >
> > Could you elaborate the statement related to vtable pointers? How does
> > that come into play for `Option<Box<_>>`? Is it for fat pointers to
> > trait objects?
>
> Yes it is for fat pointers, if you have a `x: *mut dyn Trait`, then you
> aren't allowed to write all zeroes to `x`, because the VTABLE pointer
> (that is part of the fat pointer) is not allowed to be null.
>
> Now for `Option<Box<_>>`, this doesn't matter, as there if the normal
> pointer part of the fat pointer is all zeroes, then the VTABLE pointer
> part is considered padding bytes, as it's the `None` variant.
The standard library only guarantees that all zeros is valid for
Option<Box<T,A>> when T:Sized and A=Global.
https://doc.rust-lang.org/stable/std/option/index.html#representation
Alice