Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Timur Tabi and committed by
Danilo Krummrich
01681851 69bfce0f

+34
+34
rust/kernel/dma.rs
··· 6 6 7 7 use crate::{ 8 8 bindings, 9 + debugfs, 9 10 device::{ 10 11 self, 11 12 Bound, 12 13 Core, // 13 14 }, 14 15 error::to_result, 16 + fs::file, 15 17 prelude::*, 16 18 ptr::KnownSize, 17 19 sync::aref::ARef, ··· 21 19 AsBytes, 22 20 FromBytes, // 23 21 }, // 22 + uaccess::UserSliceWriter, 24 23 }; 25 24 use core::{ 26 25 ops::{ ··· 878 875 // SAFETY: It is safe to send a `Coherent` to another thread if `T` 879 876 // can be sent to another thread. 880 877 unsafe impl<T: KnownSize + Send + ?Sized> Send for Coherent<T> {} 878 + 879 + // SAFETY: Sharing `&Coherent` across threads is safe if `T` is `Sync`, because all 880 + // methods that access the buffer contents (`field_read`, `field_write`, `as_slice`, 881 + // `as_slice_mut`) are `unsafe`, and callers are responsible for ensuring no data races occur. 882 + // The safe methods only return metadata or raw pointers whose use requires `unsafe`. 883 + unsafe impl<T: KnownSize + ?Sized + AsBytes + FromBytes + Sync> Sync for Coherent<T> {} 884 + 885 + impl debugfs::BinaryWriter for Coherent<[u8]> { 886 + fn write_to_slice( 887 + &self, 888 + writer: &mut UserSliceWriter, 889 + offset: &mut file::Offset, 890 + ) -> Result<usize> { 891 + if offset.is_negative() { 892 + return Err(EINVAL); 893 + } 894 + 895 + // If the offset is too large for a usize (e.g. on 32-bit platforms), 896 + // then consider that as past EOF and just return 0 bytes. 897 + let Ok(offset_val) = usize::try_from(*offset) else { 898 + return Ok(0); 899 + }; 900 + 901 + let count = self.size().saturating_sub(offset_val).min(writer.len()); 902 + 903 + writer.write_dma(self, offset_val, count)?; 904 + 905 + *offset += count as i64; 906 + Ok(count) 907 + } 908 + } 881 909 882 910 /// Reads a field of an item from an allocated region of structs. 883 911 ///