On Thu Jun 11, 2026 at 5:28 PM BST, Gary Guo wrote:
> One feature that was lost from the old `dma_read!` and `dma_write!` when
> moving to `io_read!` and `io_write!` was the ability to read/write a large
> structs. However, the semantics was unclear to begin with, as there was no
> guarantee about their atomicity even for structs that were small enough to
> fit in u32. Re-introduce the capability in the form of copying methods.
>
>     dma_read!(foo, bar) -> io_project!(foo, bar).copy_read()
>     dma_write!(foo, bar, baz) -> io_project!(foo, bar).copy_write(baz)
>
> Model these semantics after memcpy so user has clear expectation of lack of
> atomicity. As an additional benefit of this change, this now works for MMIO
> as well by mapping them to `memcpy_{from,to}io`.
>
> For slices which is DST so the `copy_read` and `copy_write` API above can't
> work, add `copy_from_slice` and `copy_to_slice` to copy from/to normal
> memory.
>
> Signed-off-by: Gary Guo <[email protected]>
> ---
>  rust/helpers/io.c        |  13 +++
>  rust/kernel/dma.rs       |  25 +++++
>  rust/kernel/io.rs        | 238 
> ++++++++++++++++++++++++++++++++++++++++++++++-
>  samples/rust/rust_dma.rs |  15 ++-
>  4 files changed, 285 insertions(+), 6 deletions(-)
>
> [snip]
>
> +
> +    #[inline]
> +    fn copy_read<T: FromBytes>(view: Self::View<'_, T>) -> T {
> +        // SAFETY:
> +        // - Per type invariant, `ptr` is valid and aligned.
> +        // - Using read_volatile() here so that race with hardware is 
> well-defined.
> +        // - Using read_volatile() here is not sound if it races with other 
> CPU per Rust
> +        //   rules, but this is allowed per LKMM.
> +        // - The macro is only used on primitives so all bit patterns are 
> valid.

This line should read "`T: FromBytes` so all bit patterns are valid.". I copied
from `IoCapable` impl and forgot to update the comment.

Best,
Gary

> +        unsafe { view.ptr.read_volatile() }
> +    }
> +
> +    #[inline]
> +    fn copy_write<T: IntoBytes>(view: Self::View<'_, T>, value: T) {
> +        // SAFETY:
> +        // - Per type invariant, `ptr` is valid and aligned.
> +        // - Using write_volatile() here so that race with hardware is 
> well-defined.
> +        // - Using write_volatile() here is not sound if it races with other 
> CPU per Rust
> +        //   rules, but this is allowed per LKMM.
> +        unsafe { view.ptr.write_volatile(value) }
> +    }
> +}
> +
>  /// System memory region.
>  ///
>  /// Provides `Io` trait implementation for kernel virtual address ranges,

Reply via email to