summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimur Tabi <ttabi@nvidia.com>2026-03-20 00:26:55 +0300
committerDanilo Krummrich <dakr@kernel.org>2026-03-25 03:24:11 +0300
commit01681851393642e10b5cc3f35eb6a1916ee4aff1 (patch)
treead72d3d87c2a9972ca19c8ce4e48e0f4d5d31094
parent69bfce0f25c8f949f7a02c3ed93e36aadad3fa57 (diff)
downloadlinux-01681851393642e10b5cc3f35eb6a1916ee4aff1.tar.xz
rust: dma: implement BinaryWriter for Coherent<[u8]>
Implement the BinaryWriter trait for Coherent<[u8]>, enabling DMA coherent allocations to be exposed as readable binary files. The implementation handles offset tracking and bounds checking, copying data from the coherent allocation to userspace via write_dma(). Signed-off-by: Timur Tabi <ttabi@nvidia.com> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Tested-by: John Hubbard <jhubbard@nvidia.com> Tested-by: Eliot Courtney <ecourtney@nvidia.com> Link: https://patch.msgid.link/20260319212658.2541610-4-ttabi@nvidia.com [ Rebase onto Coherent<T> changes. - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
-rw-r--r--rust/kernel/dma.rs34
1 files changed, 34 insertions, 0 deletions
diff --git a/rust/kernel/dma.rs b/rust/kernel/dma.rs
index bf823818a67d..3eef7c2396bb 100644
--- a/rust/kernel/dma.rs
+++ b/rust/kernel/dma.rs
@@ -6,12 +6,14 @@
use crate::{
bindings,
+ debugfs,
device::{
self,
Bound,
Core, //
},
error::to_result,
+ fs::file,
prelude::*,
ptr::KnownSize,
sync::aref::ARef,
@@ -19,6 +21,7 @@ use crate::{
AsBytes,
FromBytes, //
}, //
+ uaccess::UserSliceWriter,
};
use core::{
ops::{
@@ -876,6 +879,37 @@ impl<T: KnownSize + ?Sized> Drop for Coherent<T> {
// can be sent to another thread.
unsafe impl<T: KnownSize + Send + ?Sized> Send for Coherent<T> {}
+// SAFETY: Sharing `&Coherent` across threads is safe if `T` is `Sync`, because all
+// methods that access the buffer contents (`field_read`, `field_write`, `as_slice`,
+// `as_slice_mut`) are `unsafe`, and callers are responsible for ensuring no data races occur.
+// The safe methods only return metadata or raw pointers whose use requires `unsafe`.
+unsafe impl<T: KnownSize + ?Sized + AsBytes + FromBytes + Sync> Sync for Coherent<T> {}
+
+impl debugfs::BinaryWriter for Coherent<[u8]> {
+ fn write_to_slice(
+ &self,
+ writer: &mut UserSliceWriter,
+ offset: &mut file::Offset,
+ ) -> Result<usize> {
+ if offset.is_negative() {
+ return Err(EINVAL);
+ }
+
+ // If the offset is too large for a usize (e.g. on 32-bit platforms),
+ // then consider that as past EOF and just return 0 bytes.
+ let Ok(offset_val) = usize::try_from(*offset) else {
+ return Ok(0);
+ };
+
+ let count = self.size().saturating_sub(offset_val).min(writer.len());
+
+ writer.write_dma(self, offset_val, count)?;
+
+ *offset += count as i64;
+ Ok(count)
+ }
+}
+
/// Reads a field of an item from an allocated region of structs.
///
/// The syntax is of the form `kernel::dma_read!(dma, proj)` where `dma` is an expression evaluating