rust: dma: use NonNull<T> instead of *mut T
In struct CoherentAllocation, use NonNull<T> instead of a raw *mut T for the CPU address; the CPU address of a valid CoherentAllocation won't ever be NULL. Reviewed-by: Alice Ryhl <aliceryhl@google.com> Link: https://patch.msgid.link/20251103190655.2326191-2-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
This commit is contained in:
@@ -12,6 +12,7 @@ use crate::{
|
|||||||
sync::aref::ARef,
|
sync::aref::ARef,
|
||||||
transmute::{AsBytes, FromBytes},
|
transmute::{AsBytes, FromBytes},
|
||||||
};
|
};
|
||||||
|
use core::ptr::NonNull;
|
||||||
|
|
||||||
/// DMA address type.
|
/// DMA address type.
|
||||||
///
|
///
|
||||||
@@ -358,7 +359,7 @@ pub struct CoherentAllocation<T: AsBytes + FromBytes> {
|
|||||||
dev: ARef<device::Device>,
|
dev: ARef<device::Device>,
|
||||||
dma_handle: DmaAddress,
|
dma_handle: DmaAddress,
|
||||||
count: usize,
|
count: usize,
|
||||||
cpu_addr: *mut T,
|
cpu_addr: NonNull<T>,
|
||||||
dma_attrs: Attrs,
|
dma_attrs: Attrs,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -392,7 +393,7 @@ impl<T: AsBytes + FromBytes> CoherentAllocation<T> {
|
|||||||
.ok_or(EOVERFLOW)?;
|
.ok_or(EOVERFLOW)?;
|
||||||
let mut dma_handle = 0;
|
let mut dma_handle = 0;
|
||||||
// SAFETY: Device pointer is guaranteed as valid by the type invariant on `Device`.
|
// SAFETY: Device pointer is guaranteed as valid by the type invariant on `Device`.
|
||||||
let ret = unsafe {
|
let addr = unsafe {
|
||||||
bindings::dma_alloc_attrs(
|
bindings::dma_alloc_attrs(
|
||||||
dev.as_raw(),
|
dev.as_raw(),
|
||||||
size,
|
size,
|
||||||
@@ -401,9 +402,7 @@ impl<T: AsBytes + FromBytes> CoherentAllocation<T> {
|
|||||||
dma_attrs.as_raw(),
|
dma_attrs.as_raw(),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
if ret.is_null() {
|
let addr = NonNull::new(addr).ok_or(ENOMEM)?;
|
||||||
return Err(ENOMEM);
|
|
||||||
}
|
|
||||||
// INVARIANT:
|
// INVARIANT:
|
||||||
// - We just successfully allocated a coherent region which is accessible for
|
// - We just successfully allocated a coherent region which is accessible for
|
||||||
// `count` elements, hence the cpu address is valid. We also hold a refcounted reference
|
// `count` elements, hence the cpu address is valid. We also hold a refcounted reference
|
||||||
@@ -414,7 +413,7 @@ impl<T: AsBytes + FromBytes> CoherentAllocation<T> {
|
|||||||
dev: dev.into(),
|
dev: dev.into(),
|
||||||
dma_handle,
|
dma_handle,
|
||||||
count,
|
count,
|
||||||
cpu_addr: ret.cast::<T>(),
|
cpu_addr: addr.cast(),
|
||||||
dma_attrs,
|
dma_attrs,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -446,13 +445,13 @@ impl<T: AsBytes + FromBytes> CoherentAllocation<T> {
|
|||||||
|
|
||||||
/// Returns the base address to the allocated region in the CPU's virtual address space.
|
/// Returns the base address to the allocated region in the CPU's virtual address space.
|
||||||
pub fn start_ptr(&self) -> *const T {
|
pub fn start_ptr(&self) -> *const T {
|
||||||
self.cpu_addr
|
self.cpu_addr.as_ptr()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the base address to the allocated region in the CPU's virtual address space as
|
/// Returns the base address to the allocated region in the CPU's virtual address space as
|
||||||
/// a mutable pointer.
|
/// a mutable pointer.
|
||||||
pub fn start_ptr_mut(&mut self) -> *mut T {
|
pub fn start_ptr_mut(&mut self) -> *mut T {
|
||||||
self.cpu_addr
|
self.cpu_addr.as_ptr()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a DMA handle which may be given to the device as the DMA address base of
|
/// Returns a DMA handle which may be given to the device as the DMA address base of
|
||||||
@@ -580,7 +579,7 @@ impl<T: AsBytes + FromBytes> CoherentAllocation<T> {
|
|||||||
// and we've just checked that the range and index is within bounds.
|
// and we've just checked that the range and index is within bounds.
|
||||||
// - `offset` can't overflow since it is smaller than `self.count` and we've checked
|
// - `offset` can't overflow since it is smaller than `self.count` and we've checked
|
||||||
// that `self.count` won't overflow early in the constructor.
|
// that `self.count` won't overflow early in the constructor.
|
||||||
Ok(unsafe { self.cpu_addr.add(offset) })
|
Ok(unsafe { self.cpu_addr.as_ptr().add(offset) })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reads the value of `field` and ensures that its type is [`FromBytes`].
|
/// Reads the value of `field` and ensures that its type is [`FromBytes`].
|
||||||
|
|||||||
Reference in New Issue
Block a user