mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
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>
This commit is contained in:
parent
69bfce0f25
commit
0168185139
|
|
@ -6,12 +6,14 @@
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
bindings,
|
bindings,
|
||||||
|
debugfs,
|
||||||
device::{
|
device::{
|
||||||
self,
|
self,
|
||||||
Bound,
|
Bound,
|
||||||
Core, //
|
Core, //
|
||||||
},
|
},
|
||||||
error::to_result,
|
error::to_result,
|
||||||
|
fs::file,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
ptr::KnownSize,
|
ptr::KnownSize,
|
||||||
sync::aref::ARef,
|
sync::aref::ARef,
|
||||||
|
|
@ -19,6 +21,7 @@
|
||||||
AsBytes,
|
AsBytes,
|
||||||
FromBytes, //
|
FromBytes, //
|
||||||
}, //
|
}, //
|
||||||
|
uaccess::UserSliceWriter,
|
||||||
};
|
};
|
||||||
use core::{
|
use core::{
|
||||||
ops::{
|
ops::{
|
||||||
|
|
@ -876,6 +879,37 @@ fn drop(&mut self) {
|
||||||
// can be sent to another thread.
|
// can be sent to another thread.
|
||||||
unsafe impl<T: KnownSize + Send + ?Sized> Send for Coherent<T> {}
|
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.
|
/// 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
|
/// The syntax is of the form `kernel::dma_read!(dma, proj)` where `dma` is an expression evaluating
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user