Re: [PATCH v2 2/3] rust: dma: rename dma_handle to dma_address
From: Gary Guo
Date: Wed Aug 12 2026 - 19:54:34 EST
On Wed Aug 12, 2026 at 11:32 PM BST, Danilo Krummrich wrote:
> On Fri Aug 7, 2026 at 3:04 PM CEST, Gary Guo wrote:
>> On Wed Aug 5, 2026 at 9:39 PM BST, Danilo Krummrich wrote:
>>> On Wed Aug 5, 2026 at 1:32 PM CEST, Robin Murphy wrote:
>>>> To be fair, that is sort of the intent in the C API as well, to be clear
>>>> that DMA addresses must not simply be treated as physical addresses, and
>>>> aren't necessarily address-like in general e.g. comparing two
>>>> dma_handles is pretty meaningless, since they could have different
>>>> values but still refer to the same underlying memory, or vice-versa.
>>>> Adding or subtracting offsets within the bounds of the original
>>>> allocation/mapping size is pretty much the only arithmetic that _is_ valid.
>>>
>>> Yes, I did suggest a dma::Range type [1] for this purpose, such that only this
>>> kind arithmetic is possible to do.
>>>
>>> The dma::Range type should have a method returning its embedded raw value which
>>> then can be used to program registers etc.
>>>
>>> This patch is only an intermediate step, that clarifies that intent of the
>>> current usage of dma_handle() (or now dma_address()), which is not to serve as a
>>> handle.
>>
>> I suppose with I/O projections now it's rarer that people need to operate on dma
>> address directly? What do you envison as the use case for `dma::Range`?
>>
>> Also, I suppose we can also represent dma address ranges as `Io` views that does
>> not implement any accessor methods, so projection still works on them.
>
> Yes, that covers most cases. What about SGEntry cases and CoherentHandle?
>
> For instance, in nova-core we currently have
>
> for sg_entry in sg_table.iter() {
> let num_pages = usize::from_safe_cast(sg_entry.dma_len()).div_ceil(GSP_PAGE_SIZE);
> for i in 0..num_pages {
> let entry = sg_entry.dma_address()
> + (u64::from_safe_cast(i) * u64::from_safe_cast(GSP_PAGE_SIZE));
> dst.extend_from_slice(&entry.to_le_bytes(), GFP_KERNEL)?;
> }
> }
>
> which could become
>
> for sg_entry in sg_table.iter() {
> sg_entry.dma_range().for_each_block(GSP_PAGE_SIZE, |addr| {
> dst.extend_from_slice(&addr.to_le_bytes(), GFP_KERNEL)
> })?;
> }
If we have `DmaRange<T>: IoBase` and `fn dma_address() -> DmaRange<[u8]>`
then you could imagine doing
io_project!(sg_entry.dma_range(), [panic: i * GSP_PAGE_SIZE..]).address()
A caveat is that it's slightly tricky to implement `IoBase` for `DmaRange` due
to the ptr_metadata feature being unstable... That said, this could be worked
around.
Best,
Gary