[PATCH RFC 1/4] rust: transmute: add `impl_transmute_via_zerocopy!` macro
From: SeungJong Ha via B4 Relay
Date: Sun Jun 28 2026 - 13:11:30 EST
From: SeungJong Ha <engineer.jjhama@xxxxxxxxx>
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 <engineer.jjhama@xxxxxxxxx>
---
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