From e7219e53c525db87b43f4a9064d0e6331d7dc710 Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Mon, 6 Jul 2026 13:44:32 +0100 Subject: rust: io: add copying methods 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 Reviewed-by: Alexandre Courbot Link: https://patch.msgid.link/20260706-io_projection-v6-19-72cd5d055d54@garyguo.net Signed-off-by: Danilo Krummrich --- samples/rust/rust_dma.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'samples') diff --git a/samples/rust/rust_dma.rs b/samples/rust/rust_dma.rs index 4af46e99d2dd..b629acc6d915 100644 --- a/samples/rust/rust_dma.rs +++ b/samples/rust/rust_dma.rs @@ -14,7 +14,8 @@ use kernel::{ }, io::{ io_project, - io_read, // + io_read, + Io, // }, page, pci, prelude::*, @@ -38,6 +39,7 @@ const TEST_VALUES: [(u32, u32); 5] = [ (0xcd, 0xef), ]; +#[derive(FromBytes, IntoBytes)] struct MyStruct { h: u32, b: u32, @@ -81,8 +83,7 @@ impl pci::Driver for DmaSampleDriver { Coherent::zeroed_slice(pdev.as_ref(), TEST_VALUES.len(), GFP_KERNEL)?; for (i, value) in TEST_VALUES.into_iter().enumerate() { - // SAFETY: `ca` is not yet shared with device or other threads. - unsafe { *io_project!(ca, [panic: i]).as_mut() = MyStruct::new(value.0, value.1) }; + io_project!(ca, [panic: i]).copy_write(MyStruct::new(value.0, value.1)); } let size = 4 * page::PAGE_SIZE; -- cgit