From: Alexandre Courbot Date: Thu, 19 Jun 2025 13:23:47 +0000 (+0900) Subject: rust: dma: add dma_handle_with_offset method to CoherentAllocation X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=26af856539842a4107c821e133fdda896022737f;p=thirdparty%2Fkernel%2Flinux.git rust: dma: add dma_handle_with_offset method to CoherentAllocation Sometimes one may want to obtain a DMA handle starting at a given offset. This can be done by adding said offset to the result of `dma_handle()`, but doing so on the client side carries the risk that the operation will go outside the bounds of the allocation. Thus, add a `dma_handle_with_offset` method that adds the desired offset after checking that it is still valid. Signed-off-by: Alexandre Courbot Link: https://lore.kernel.org/r/20250619-nova-frts-v6-3-ecf41ef99252@nvidia.com Signed-off-by: Danilo Krummrich --- diff --git a/rust/kernel/dma.rs b/rust/kernel/dma.rs index 34a406a0602e3..25dfa0e6cc3ce 100644 --- a/rust/kernel/dma.rs +++ b/rust/kernel/dma.rs @@ -238,6 +238,20 @@ impl CoherentAllocation { self.dma_handle } + /// Returns a DMA handle starting at `offset` (in units of `T`) which may be given to the + /// device as the DMA address base of the region. + /// + /// Returns `EINVAL` if `offset` is not within the bounds of the allocation. + pub fn dma_handle_with_offset(&self, offset: usize) -> Result { + if offset >= self.count { + Err(EINVAL) + } else { + // INVARIANT: The type invariant of `Self` guarantees that `size_of:: * count` fits + // into a `usize`, and `offset` is inferior to `count`. + Ok(self.dma_handle + (offset * core::mem::size_of::()) as bindings::dma_addr_t) + } + } + /// Common helper to validate a range applied from the allocated region in the CPU's virtual /// address space. fn validate_range(&self, offset: usize, count: usize) -> Result {