[PATCH RFC 1/4] rust: transmute: add `impl_transmute_via_zerocopy!` macro
SeungJong Ha via B4 Relay <[email protected]>
| Newsgroups | dev.linux.lists.nova-gpu,org.freedesktop.lists.dri-devel,org.kernel.feeds.b4-sent,org.kernel.vger.linux-kernel,org.kernel.vger.rust-for-linux |
|---|---|
| Message-ID | <[email protected]> |
From: SeungJong Ha <[email protected]> The DMA-coherent allocation APIs (`CoherentAllocation`, `Coherent`, `dma::Pool`) bound their element type on `transmute::{AsBytes, FromBytes}`, which a `zerocopy`-deriving type cannot satisfy. A blanket bridge impl is rejected by coherence, as it overlaps every existing concrete `transmute` impl. Add a per-type bridge macro that emits the `transmute` impls for a `zerocopy`-derived type. A compile-time assertion fails the build unless the type is `zerocopy::{FromBytes, IntoBytes, Immutable}`, which subsumes the `transmute::{FromBytes, AsBytes}` contracts, so the emitted unsafe impls are machine-checked. This lets DMA structures adopt `zerocopy` incrementally without flipping the DMA bound. Assisted-by: Claude-Code:claude-opus-4-8 Signed-off-by: SeungJong Ha <[email protected]> --- rust/kernel/transmute.rs | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/rust/kernel/transmute.rs b/rust/kernel/transmute.rs index 654b5ede2fe2..d9881f84dc62 100644 --- a/rust/kernel/transmute.rs +++ b/rust/kernel/transmute.rs @@ -227,3 +227,38 @@ macro_rules! impl_asbytes { {<T: AsBytes>} [T], {<T: AsBytes, const N: usize>} [T; N], } + +/// Implements the kernel's `FromBytes` and `AsBytes` byte-safety traits for a type +/// that already derives the equivalent `zerocopy` traits. +/// +/// This lets a `zerocopy`-derived type satisfy the bounds required by the +/// DMA-coherent allocation APIs (`CoherentAllocation`, `Coherent`, `dma::Pool`) +/// without a hand-audited `unsafe`: the macro fails to compile unless `$t` +/// implements `zerocopy::FromBytes`, `zerocopy::IntoBytes` and `zerocopy::Immutable`, +/// which together subsume the safety contracts of [`FromBytes`] and [`AsBytes`]. +#[macro_export] +macro_rules! impl_transmute_via_zerocopy { + ($t:ty) => { + const _: () = { + // Compile-time proof: fails to build unless `$t` carries the `zerocopy` + // byte-safety proofs. + fn assert_zerocopy< + T: ::zerocopy::FromBytes + ::zerocopy::IntoBytes + ::zerocopy::Immutable, + >() { + } + fn check() { + assert_zerocopy::<$t>(); + } + }; + + // SAFETY: `$t: zerocopy::FromBytes` guarantees that all bit patterns are valid + // and `zerocopy::Immutable` that it has no interior mutability, which is exactly + // the contract of `FromBytes`. + unsafe impl $crate::transmute::FromBytes for $t {} + + // SAFETY: `$t: zerocopy::IntoBytes` guarantees that it has no uninitialized + // (padding) bytes and `zerocopy::Immutable` that it has no interior mutability, + // which is exactly the contract of `AsBytes`. + unsafe impl $crate::transmute::AsBytes for $t {} + }; +} -- 2.54.0