* [PATCH v2 0/3] gpu: nova-core: falcon: use I/O projections for DMA transfers
@ 2026-08-05 5:01 Alexandre Courbot
2026-08-05 5:01 ` [PATCH v2 1/3] gpu: nova-core: falcon: remove unnecessary check Alexandre Courbot
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: Alexandre Courbot @ 2026-08-05 5:01 UTC (permalink / raw)
To: Danilo Krummrich, Alice Ryhl, David Airlie, Simona Vetter,
Abdiel Janulgue, Daniel Almeida, Robin Murphy, Andreas Hindborg,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Trevor Gross, Tamir Duberstein, Onur Özkan
Cc: John Hubbard, Alistair Popple, Timur Tabi, Eliot Courtney,
Zhi Wang, nova-gpu, dri-devel, linux-kernel, driver-core,
rust-for-linux, Alexandre Courbot
Falcon DMA transfers were using cumbersome address arithmetic and
explicit bounds checks to ensure a requested transfer is valid. This
series replaces it with an I/O projection which, if successful, carries
the same bounds guarantees and does not require performing operations on
DMA addresses.
The first patch removes a redundant check that is covered by the
register's `try_with_...` family of methods.
The second patch renames `dma_handle` to `dma_address` throughout the
tree after comments received on v1. nova-core is the only user at the
moment, so the renaming remains contained.
Patch 3 switches to I/O projections in the Falcon code, the original
motivation for this series.
This series is based on drm-rust-next.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
Changes in v2:
- Add a patch renaming `dma_handle` to `dma_address`.
- Use `dma_address` consistently within nova-core.
- Link to v1: https://patch.msgid.link/20260724-falcon-dma-projections-v1-0-957028a7c0a7@nvidia.com
---
Alexandre Courbot (3):
gpu: nova-core: falcon: remove unnecessary check
rust: dma: rename dma_handle to dma_address
gpu: nova-core: falcon: use I/O projection to check transfer bounds
drivers/gpu/nova-core/falcon.rs | 66 ++++++++------------
drivers/gpu/nova-core/fb.rs | 4 +-
drivers/gpu/nova-core/firmware/booter.rs | 8 ++-
drivers/gpu/nova-core/firmware/fwsec/bootloader.rs | 4 +-
drivers/gpu/nova-core/firmware/gsp.rs | 6 +-
drivers/gpu/nova-core/fsp.rs | 6 +-
drivers/gpu/nova-core/gsp.rs | 2 +-
drivers/gpu/nova-core/gsp/cmdq.rs | 8 +--
drivers/gpu/nova-core/gsp/fw.rs | 10 ++--
drivers/gpu/nova-core/gsp/hal/gh100.rs | 2 +-
drivers/gpu/nova-core/gsp/hal/tu102.rs | 8 ++-
drivers/gpu/nova-core/gsp/sequencer.rs | 8 +--
rust/kernel/dma.rs | 70 +++++++++++-----------
13 files changed, 95 insertions(+), 107 deletions(-)
---
base-commit: 44e7e7f7cffb10a93bb88e7cb59b7b8b3e2deb1c
change-id: 20260724-falcon-dma-projections-ea9343cfcdae
Best regards,
--
Alexandre Courbot <acourbot@nvidia.com>
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2 1/3] gpu: nova-core: falcon: remove unnecessary check
2026-08-05 5:01 [PATCH v2 0/3] gpu: nova-core: falcon: use I/O projections for DMA transfers Alexandre Courbot
@ 2026-08-05 5:01 ` Alexandre Courbot
2026-08-05 7:02 ` Ethan Plant
2026-08-05 5:01 ` [PATCH v2 2/3] rust: dma: rename dma_handle to dma_address Alexandre Courbot
` (2 subsequent siblings)
3 siblings, 1 reply; 9+ messages in thread
From: Alexandre Courbot @ 2026-08-05 5:01 UTC (permalink / raw)
To: Danilo Krummrich, Alice Ryhl, David Airlie, Simona Vetter,
Abdiel Janulgue, Daniel Almeida, Robin Murphy, Andreas Hindborg,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Trevor Gross, Tamir Duberstein, Onur Özkan
Cc: John Hubbard, Alistair Popple, Timur Tabi, Eliot Courtney,
Zhi Wang, nova-gpu, dri-devel, linux-kernel, driver-core,
rust-for-linux, Alexandre Courbot
The `try_with_base` call performed on `NV_PFALCON_FALCON_DMATRFBASE1`
already returns `EOVERFLOW` if the address is too large for the
register, making this check redundant.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
drivers/gpu/nova-core/falcon.rs | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/drivers/gpu/nova-core/falcon.rs b/drivers/gpu/nova-core/falcon.rs
index a91cbdd5d636..cd05985f5ee6 100644
--- a/drivers/gpu/nova-core/falcon.rs
+++ b/drivers/gpu/nova-core/falcon.rs
@@ -9,8 +9,7 @@
dma::{
Coherent,
CoherentBox,
- DmaAddress,
- DmaMask, //
+ DmaAddress, //
},
io::{
poll::read_poll_timeout,
@@ -534,12 +533,6 @@ fn dma_wr(
return Err(EINVAL);
}
- // The DMATRFBASE/1 register pair only supports a 49-bit address.
- if dma_start > DmaMask::new::<49>().value() {
- dev_err!(self.dev, "DMA address {:#x} exceeds 49 bits\n", dma_start);
- return Err(ERANGE);
- }
-
// DMA transfers can only be done in units of 256 bytes. Compute how many such transfers we
// need to perform.
let num_transfers = load_offsets.len.div_ceil(DMA_LEN);
--
2.55.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 2/3] rust: dma: rename dma_handle to dma_address
2026-08-05 5:01 [PATCH v2 0/3] gpu: nova-core: falcon: use I/O projections for DMA transfers Alexandre Courbot
2026-08-05 5:01 ` [PATCH v2 1/3] gpu: nova-core: falcon: remove unnecessary check Alexandre Courbot
@ 2026-08-05 5:01 ` Alexandre Courbot
2026-08-05 11:32 ` Robin Murphy
2026-08-06 21:16 ` Danilo Krummrich
2026-08-05 5:01 ` [PATCH v2 3/3] gpu: nova-core: falcon: use I/O projection to check transfer bounds Alexandre Courbot
2026-08-06 21:25 ` [PATCH v2 0/3] gpu: nova-core: falcon: use I/O projections for DMA transfers Danilo Krummrich
3 siblings, 2 replies; 9+ messages in thread
From: Alexandre Courbot @ 2026-08-05 5:01 UTC (permalink / raw)
To: Danilo Krummrich, Alice Ryhl, David Airlie, Simona Vetter,
Abdiel Janulgue, Daniel Almeida, Robin Murphy, Andreas Hindborg,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Trevor Gross, Tamir Duberstein, Onur Özkan
Cc: John Hubbard, Alistair Popple, Timur Tabi, Eliot Courtney,
Zhi Wang, nova-gpu, dri-devel, linux-kernel, driver-core,
rust-for-linux, Alexandre Courbot
The `dma_handle` naming is inherited from the C API, but what this
really describes is the device DMA address; everything named
`dma_handle` is actually a `dma_addr_t`.
This naming introduces some confusion on the Rust API side, as handles
are supposed to be opaque tokens, yet we were doing address computation
on values returned by `dma_handle`.
Rename `dma_handle` to `dma_address` while nova-core is still its only
user.
Suggested-by: John Hubbard <jhubbard@nvidia.com>
Suggested-by: Danilo Krummrich <dakr@kernel.org>
Link: https://lore.kernel.org/all/DK75LUA4NLGI.3P29AIZQE20V2@kernel.org/
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
drivers/gpu/nova-core/falcon.rs | 8 +--
drivers/gpu/nova-core/fb.rs | 4 +-
drivers/gpu/nova-core/firmware/booter.rs | 8 ++-
drivers/gpu/nova-core/firmware/fwsec/bootloader.rs | 4 +-
drivers/gpu/nova-core/firmware/gsp.rs | 6 +-
drivers/gpu/nova-core/fsp.rs | 6 +-
drivers/gpu/nova-core/gsp.rs | 2 +-
drivers/gpu/nova-core/gsp/cmdq.rs | 8 +--
drivers/gpu/nova-core/gsp/fw.rs | 10 ++--
drivers/gpu/nova-core/gsp/hal/gh100.rs | 2 +-
drivers/gpu/nova-core/gsp/hal/tu102.rs | 8 ++-
drivers/gpu/nova-core/gsp/sequencer.rs | 8 +--
rust/kernel/dma.rs | 70 +++++++++++-----------
13 files changed, 74 insertions(+), 70 deletions(-)
diff --git a/drivers/gpu/nova-core/falcon.rs b/drivers/gpu/nova-core/falcon.rs
index cd05985f5ee6..a281d316ebfd 100644
--- a/drivers/gpu/nova-core/falcon.rs
+++ b/drivers/gpu/nova-core/falcon.rs
@@ -499,7 +499,7 @@ pub(crate) fn pio_load<F: FalconFirmware<Target = E> + FalconPioLoadable>(
Ok(())
}
- /// Perform a DMA write according to `load_offsets` from `dma_handle` into the falcon's
+ /// Perform a DMA write according to `load_offsets` from `dma_obj` into the falcon's
/// `target_mem`.
///
/// `sec` is set if the loaded firmware is expected to run in secure mode.
@@ -514,14 +514,14 @@ fn dma_wr(
// For IMEM, we want to use the start offset as a virtual address tag for each page, since
// code addresses in the firmware (and the boot vector) are virtual.
//
- // For DMEM we can fold the start offset into the DMA handle.
+ // For DMEM we can fold the start offset into the DMA address.
let (src_start, dma_start) = match target_mem {
FalconMem::ImemSecure | FalconMem::ImemNonSecure => {
- (load_offsets.src_start, dma_obj.dma_handle())
+ (load_offsets.src_start, dma_obj.dma_address())
}
FalconMem::Dmem => (
0,
- dma_obj.dma_handle() + DmaAddress::from(load_offsets.src_start),
+ dma_obj.dma_address() + DmaAddress::from(load_offsets.src_start),
),
};
if dma_start % DmaAddress::from(DMA_LEN) > 0 {
diff --git a/drivers/gpu/nova-core/fb.rs b/drivers/gpu/nova-core/fb.rs
index 9e475efb1150..e7ed19a61c1a 100644
--- a/drivers/gpu/nova-core/fb.rs
+++ b/drivers/gpu/nova-core/fb.rs
@@ -61,7 +61,7 @@ pub(crate) fn register(
) -> Result<Self> {
let page = CoherentHandle::alloc(dev, kernel::page::PAGE_SIZE, GFP_KERNEL)?;
- hal::fb_hal(chipset).write_sysmem_flush_page(bar, page.dma_handle())?;
+ hal::fb_hal(chipset).write_sysmem_flush_page(bar, page.dma_address())?;
Ok(Self {
chipset,
@@ -76,7 +76,7 @@ impl Drop for SysmemFlush<'_> {
fn drop(&mut self) {
let hal = hal::fb_hal(self.chipset);
- if hal.read_sysmem_flush_page(self.bar) == self.page.dma_handle() {
+ if hal.read_sysmem_flush_page(self.bar) == self.page.dma_address() {
let _ = hal.write_sysmem_flush_page(self.bar, 0).inspect_err(|e| {
dev_warn!(
&self.device,
diff --git a/drivers/gpu/nova-core/firmware/booter.rs b/drivers/gpu/nova-core/firmware/booter.rs
index acb7f4d8a532..972618e5eafe 100644
--- a/drivers/gpu/nova-core/firmware/booter.rs
+++ b/drivers/gpu/nova-core/firmware/booter.rs
@@ -405,9 +405,11 @@ pub(crate) fn run<T>(
) -> Result {
sec2_falcon.reset()?;
sec2_falcon.load(self)?;
- let wpr_handle = wpr_meta.dma_handle();
- let (mbox0, mbox1) =
- sec2_falcon.boot(Some(wpr_handle as u32), Some((wpr_handle >> 32) as u32))?;
+ let wpr_dma_address = wpr_meta.dma_address();
+ let (mbox0, mbox1) = sec2_falcon.boot(
+ Some(wpr_dma_address as u32),
+ Some((wpr_dma_address >> 32) as u32),
+ )?;
dev_dbg!(dev, "SEC2 MBOX0: {:#x}, MBOX1: {:#x}\n", mbox0, mbox1);
if mbox0 != 0 {
diff --git a/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs b/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs
index d9fafd2eea5b..c4a327af9ac7 100644
--- a/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs
+++ b/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs
@@ -230,7 +230,7 @@ pub(crate) fn new(
reserved: [0; 4],
signature: [0; 4],
ctx_dma: FALCON_DMAIDX_PHYS_SYS_NCOH,
- code_dma_base: firmware_dma.dma_handle(),
+ code_dma_base: firmware_dma.dma_address(),
// `dst_start` is also valid as the source offset since the firmware DMA object is
// a mirror image of the target IMEM layout.
non_sec_code_off: imem_ns.dst_start,
@@ -242,7 +242,7 @@ pub(crate) fn new(
code_entry_point: 0,
// Start of data section is the added padding + the DMEM `src_start` field.
data_dma_base: firmware_dma
- .dma_handle()
+ .dma_address()
.checked_add(u64::from_safe_cast(align_padding))
.and_then(|offset| offset.checked_add(dmem.src_start.into()))
.ok_or(EOVERFLOW)?,
diff --git a/drivers/gpu/nova-core/firmware/gsp.rs b/drivers/gpu/nova-core/firmware/gsp.rs
index 99a302bae567..97977f27d74b 100644
--- a/drivers/gpu/nova-core/firmware/gsp.rs
+++ b/drivers/gpu/nova-core/firmware/gsp.rs
@@ -161,9 +161,9 @@ pub(crate) fn new<'a>(
})
}
- /// Returns the DMA handle of the radix3 level 0 page table.
- pub(crate) fn radix3_dma_handle(&self) -> DmaAddress {
- self.level0.dma_handle()
+ /// Returns the DMA address of the radix3 level 0 page table.
+ pub(crate) fn radix3_dma_address(&self) -> DmaAddress {
+ self.level0.dma_address()
}
}
diff --git a/drivers/gpu/nova-core/fsp.rs b/drivers/gpu/nova-core/fsp.rs
index ba4544210e40..1721a8387636 100644
--- a/drivers/gpu/nova-core/fsp.rs
+++ b/drivers/gpu/nova-core/fsp.rs
@@ -287,12 +287,12 @@ fn new<'a>(
.chain(move |msg| {
msg.cot.version = version;
msg.cot.size = size;
- msg.cot.gsp_fmc_sysmem_offset = fsp_fw.fmc_image.dma_handle();
+ msg.cot.gsp_fmc_sysmem_offset = fsp_fw.fmc_image.dma_address();
msg.cot.frts_vidmem_offset = frts_vidmem_offset;
msg.cot.frts_vidmem_size = frts_size;
// frts_sysmem_* are left at zero because this path places FRTS in vidmem. The sysmem
// fields point to an FRTS buffer in sysmem instead, for systems without VRAM.
- msg.cot.gsp_boot_args_sysmem_offset = args.fmc_boot_params.dma_handle();
+ msg.cot.gsp_boot_args_sysmem_offset = args.fmc_boot_params.dma_address();
msg.cot.sigs = *fsp_fw.fmc_sigs;
Ok(())
@@ -353,7 +353,7 @@ pub(crate) fn new(
libos: &'a Coherent<[LibosMemoryRegionInitArgument]>,
resume: bool,
) -> Result<Self> {
- let init = GspFmcBootParams::new(wpr_meta.dma_handle(), libos.dma_handle());
+ let init = GspFmcBootParams::new(wpr_meta.dma_address(), libos.dma_address());
Ok(Self {
chipset,
diff --git a/drivers/gpu/nova-core/gsp.rs b/drivers/gpu/nova-core/gsp.rs
index b403dc3515a5..13f361406a6c 100644
--- a/drivers/gpu/nova-core/gsp.rs
+++ b/drivers/gpu/nova-core/gsp.rs
@@ -122,7 +122,7 @@ impl LogBuffer {
fn new(dev: &device::Device<device::Bound>) -> Result<Self> {
let obj = Self(Coherent::zeroed(dev, GFP_KERNEL)?);
- let start_addr = obj.0.dma_handle();
+ let start_addr = obj.0.dma_address();
let pte_view = io_project!(
obj.0,
diff --git a/drivers/gpu/nova-core/gsp/cmdq.rs b/drivers/gpu/nova-core/gsp/cmdq.rs
index cd844fe48f05..f0f28b6ded7a 100644
--- a/drivers/gpu/nova-core/gsp/cmdq.rs
+++ b/drivers/gpu/nova-core/gsp/cmdq.rs
@@ -243,7 +243,7 @@ fn new(dev: &device::Device<device::Bound>) -> Result<Self> {
gsp_mem.cpuq.rx = MsgqRxHeader::new();
let gsp_mem: Coherent<_> = gsp_mem.into();
- PteArray::init(io_project!(gsp_mem, .ptes), gsp_mem.dma_handle())?;
+ PteArray::init(io_project!(gsp_mem, .ptes), gsp_mem.dma_address())?;
Ok(Self(gsp_mem))
}
@@ -487,8 +487,8 @@ pub(crate) struct Cmdq {
/// Inner mutex-protected state.
#[pin]
inner: Mutex<CmdqInner>,
- /// DMA handle of the command queue's shared memory region.
- pub(super) dma_handle: DmaAddress,
+ /// DMA address of the command queue's shared memory region.
+ pub(super) dma_addr: DmaAddress,
}
impl Cmdq {
@@ -517,7 +517,7 @@ pub(crate) fn new(dev: &device::Device<device::Bound>) -> impl PinInit<Self, Err
let gsp_mem = DmaGspMem::new(dev)?;
Ok(try_pin_init!(Self {
- dma_handle: gsp_mem.0.dma_handle(),
+ dma_addr: gsp_mem.0.dma_address(),
inner <- new_mutex!(CmdqInner {
dev: dev.into(),
gsp_mem,
diff --git a/drivers/gpu/nova-core/gsp/fw.rs b/drivers/gpu/nova-core/gsp/fw.rs
index 6e8e7d822ef1..a237db74cad5 100644
--- a/drivers/gpu/nova-core/gsp/fw.rs
+++ b/drivers/gpu/nova-core/gsp/fw.rs
@@ -183,16 +183,16 @@ pub(crate) fn new<'a>(
// CAST: we want to store the bits of `GSP_FW_WPR_META_MAGIC` unmodified.
magic: bindings::GSP_FW_WPR_META_MAGIC as u64,
revision: u64::from(bindings::GSP_FW_WPR_META_REVISION),
- sysmemAddrOfRadix3Elf: gsp_firmware.radix3_dma_handle(),
+ sysmemAddrOfRadix3Elf: gsp_firmware.radix3_dma_address(),
sizeOfRadix3Elf: u64::from_safe_cast(gsp_firmware.size),
- sysmemAddrOfBootloader: gsp_firmware.bootloader.ucode.dma_handle(),
+ sysmemAddrOfBootloader: gsp_firmware.bootloader.ucode.dma_address(),
sizeOfBootloader: u64::from_safe_cast(gsp_firmware.bootloader.ucode.size()),
bootloaderCodeOffset: u64::from(gsp_firmware.bootloader.code_offset),
bootloaderDataOffset: u64::from(gsp_firmware.bootloader.data_offset),
bootloaderManifestOffset: u64::from(gsp_firmware.bootloader.manifest_offset),
__bindgen_anon_1: GspFwWprMetaBootResumeInfo {
__bindgen_anon_1: GspFwWprMetaBootInfo {
- sysmemAddrOfSignature: gsp_firmware.signatures.dma_handle(),
+ sysmemAddrOfSignature: gsp_firmware.signatures.dma_address(),
sizeOfSignature: u64::from_safe_cast(gsp_firmware.signatures.size()),
},
},
@@ -635,7 +635,7 @@ fn id8(name: &str) -> u64 {
let init_inner = init!(bindings::LibosMemoryRegionInitArgument {
id8: id8(name),
- pa: obj.dma_handle(),
+ pa: obj.dma_address(),
size: num::usize_as_u64(obj.size()),
kind: num::u32_into_u8::<
{ bindings::LibosMemoryRegionKind_LIBOS_MEMORY_REGION_CONTIGUOUS },
@@ -901,7 +901,7 @@ impl MessageQueueInitArguments {
/// Creates a new init arguments structure for `cmdq`.
fn new(cmdq: &Cmdq) -> impl Init<Self> + '_ {
init!(MessageQueueInitArguments {
- sharedMemPhysAddr: cmdq.dma_handle,
+ sharedMemPhysAddr: cmdq.dma_addr,
pageTableEntryCount: num::usize_into_u32::<{ Cmdq::NUM_PTES }>(),
cmdQueueOffset: num::usize_as_u64(Cmdq::CMDQ_OFFSET),
statQueueOffset: num::usize_as_u64(Cmdq::STATQ_OFFSET),
diff --git a/drivers/gpu/nova-core/gsp/hal/gh100.rs b/drivers/gpu/nova-core/gsp/hal/gh100.rs
index 22b60f9233de..8e219a0cb164 100644
--- a/drivers/gpu/nova-core/gsp/hal/gh100.rs
+++ b/drivers/gpu/nova-core/gsp/hal/gh100.rs
@@ -63,7 +63,7 @@ fn lockdown_released_or_error(
// boot. If the address is still there, keep polling rather than treating it as an error.
// Any other non-zero mailbox0 value is a GSP-FMC error code.
if self.mbox0 != 0 {
- return self.combined_addr() != fmc_boot_params.dma_handle();
+ return self.combined_addr() != fmc_boot_params.dma_address();
}
!gsp_falcon.riscv_branch_privilege_lockdown()
diff --git a/drivers/gpu/nova-core/gsp/hal/tu102.rs b/drivers/gpu/nova-core/gsp/hal/tu102.rs
index 03133f723faf..26ac1adba1bf 100644
--- a/drivers/gpu/nova-core/gsp/hal/tu102.rs
+++ b/drivers/gpu/nova-core/gsp/hal/tu102.rs
@@ -286,9 +286,11 @@ fn boot(
}
gsp_falcon.reset()?;
- let libos_handle = gsp.libos.dma_handle();
- let (mbox0, mbox1) =
- gsp_falcon.boot(Some(libos_handle as u32), Some((libos_handle >> 32) as u32))?;
+ let libos_dma_address = gsp.libos.dma_address();
+ let (mbox0, mbox1) = gsp_falcon.boot(
+ Some(libos_dma_address as u32),
+ Some((libos_dma_address >> 32) as u32),
+ )?;
dev_dbg!(dev, "GSP MBOX0: {:#x}, MBOX1: {:#x}\n", mbox0, mbox1);
dev_dbg!(
diff --git a/drivers/gpu/nova-core/gsp/sequencer.rs b/drivers/gpu/nova-core/gsp/sequencer.rs
index 5e1ec7e59ab0..bcad1421953a 100644
--- a/drivers/gpu/nova-core/gsp/sequencer.rs
+++ b/drivers/gpu/nova-core/gsp/sequencer.rs
@@ -234,12 +234,12 @@ fn run(&self, seq: &GspSequencer<'_>) -> Result {
// Reset the GSP to prepare it for resuming.
seq.gsp_falcon.reset()?;
- let libos_dma_handle = seq.libos.dma_handle();
+ let libos_dma_address = seq.libos.dma_address();
- // Write the libOS DMA handle to GSP mailboxes.
+ // Write the libOS DMA address to GSP mailboxes.
seq.gsp_falcon.write_mailboxes(
- Some(libos_dma_handle as u32),
- Some((libos_dma_handle >> 32) as u32),
+ Some(libos_dma_address as u32),
+ Some((libos_dma_address >> 32) as u32),
);
// Start the SEC2 falcon which will trigger GSP-RM to resume on the GSP.
diff --git a/rust/kernel/dma.rs b/rust/kernel/dma.rs
index e275f2562a5b..4258ff7ff525 100644
--- a/rust/kernel/dma.rs
+++ b/rust/kernel/dma.rs
@@ -585,7 +585,7 @@ fn from(value: CoherentBox<T>) -> Self {
/// # Invariants
///
/// - For the lifetime of an instance of [`Coherent`], the `cpu_addr` is a valid pointer
-/// to an allocated region of coherent memory and `dma_handle` is the DMA address base of the
+/// to an allocated region of coherent memory and `dma_addr` is the DMA address base of the
/// region.
/// - The size in bytes of the allocation is equal to size information via pointer.
// TODO
@@ -602,7 +602,7 @@ fn from(value: CoherentBox<T>) -> Self {
// entire `Coherent` including the allocated memory itself.
pub struct Coherent<T: KnownSize + ?Sized> {
dev: ARef<device::Device>,
- dma_handle: DmaAddress,
+ dma_addr: DmaAddress,
cpu_addr: NonNull<T>,
dma_attrs: Attrs,
}
@@ -627,11 +627,10 @@ pub fn as_mut_ptr(&self) -> *mut T {
self.cpu_addr.as_ptr()
}
- /// Returns a DMA handle which may be given to the device as the DMA address base of
- /// the region.
+ /// Returns a DMA address which may be given to the device as the base of the region.
#[inline]
- pub fn dma_handle(&self) -> DmaAddress {
- self.dma_handle
+ pub fn dma_address(&self) -> DmaAddress {
+ self.dma_addr
}
/// Returns a reference to the data in the region.
@@ -678,13 +677,13 @@ fn alloc_with_attrs(
);
}
- let mut dma_handle = 0;
+ let mut dma_addr = 0;
// SAFETY: Device pointer is guaranteed as valid by the type invariant on `Device`.
let addr = unsafe {
bindings::dma_alloc_attrs(
dev.as_raw(),
core::mem::size_of::<T>(),
- &mut dma_handle,
+ &mut dma_addr,
gfp_flags.as_raw(),
dma_attrs.as_raw(),
)
@@ -696,7 +695,7 @@ fn alloc_with_attrs(
// - We also hold a refcounted reference to the device.
Ok(Self {
dev: dev.into(),
- dma_handle,
+ dma_addr,
cpu_addr,
dma_attrs,
})
@@ -795,13 +794,13 @@ fn alloc_slice_with_attrs(
}
let size = core::mem::size_of::<T>().checked_mul(len).ok_or(ENOMEM)?;
- let mut dma_handle = 0;
+ let mut dma_addr = 0;
// SAFETY: Device pointer is guaranteed as valid by the type invariant on `Device`.
let addr = unsafe {
bindings::dma_alloc_attrs(
dev.as_raw(),
size,
- &mut dma_handle,
+ &mut dma_addr,
gfp_flags.as_raw(),
dma_attrs.as_raw(),
)
@@ -813,7 +812,7 @@ fn alloc_slice_with_attrs(
// - We also hold a refcounted reference to the device.
Ok(Coherent {
dev: dev.into(),
- dma_handle,
+ dma_addr,
cpu_addr,
dma_attrs,
})
@@ -927,14 +926,14 @@ impl<T: KnownSize + ?Sized> Drop for Coherent<T> {
fn drop(&mut self) {
let size = T::size(self.cpu_addr.as_ptr());
// SAFETY: Device pointer is guaranteed as valid by the type invariant on `Device`.
- // The cpu address, and the dma handle are valid due to the type invariants on
+ // The cpu address, and the dma address are valid due to the type invariants on
// `Coherent`.
unsafe {
bindings::dma_free_attrs(
self.dev.as_raw(),
size,
self.cpu_addr.as_ptr().cast(),
- self.dma_handle,
+ self.dma_addr,
self.dma_attrs.as_raw(),
)
}
@@ -989,13 +988,13 @@ fn write_to_slice(
///
/// - `cpu_handle` holds the opaque handle returned by `dma_alloc_attrs` with
/// `DMA_ATTR_NO_KERNEL_MAPPING` set, and is only valid for passing back to `dma_free_attrs`.
-/// - `dma_handle` is the corresponding bus address for device DMA.
+/// - `dma_addr` is the corresponding bus address for device DMA.
/// - `size` is the allocation size in bytes as passed to `dma_alloc_attrs`.
/// - `dma_attrs` contains the attributes used for the allocation, always including
/// `DMA_ATTR_NO_KERNEL_MAPPING`.
pub struct CoherentHandle {
dev: ARef<device::Device>,
- dma_handle: DmaAddress,
+ dma_addr: DmaAddress,
cpu_handle: NonNull<c_void>,
size: usize,
dma_attrs: Attrs,
@@ -1019,13 +1018,13 @@ pub fn alloc_with_attrs(
}
let dma_attrs = dma_attrs | Attrs(bindings::DMA_ATTR_NO_KERNEL_MAPPING);
- let mut dma_handle = 0;
+ let mut dma_addr = 0;
// SAFETY: `dev.as_raw()` is valid by the type invariant on `device::Device`.
let cpu_handle = unsafe {
bindings::dma_alloc_attrs(
dev.as_raw(),
size,
- &mut dma_handle,
+ &mut dma_addr,
gfp_flags.as_raw(),
dma_attrs.as_raw(),
)
@@ -1034,11 +1033,11 @@ pub fn alloc_with_attrs(
let cpu_handle = NonNull::new(cpu_handle).ok_or(ENOMEM)?;
// INVARIANT: `cpu_handle` is the opaque handle from a successful `dma_alloc_attrs` call
- // with `DMA_ATTR_NO_KERNEL_MAPPING`, `dma_handle` is the corresponding DMA address,
+ // with `DMA_ATTR_NO_KERNEL_MAPPING`, `dma_addr` is the corresponding DMA address,
// and we hold a refcounted reference to the device.
Ok(Self {
dev: dev.into(),
- dma_handle,
+ dma_addr,
cpu_handle,
size,
dma_attrs,
@@ -1055,12 +1054,12 @@ pub fn alloc(
Self::alloc_with_attrs(dev, size, gfp_flags, Attrs(0))
}
- /// Returns the DMA handle for this allocation.
+ /// Returns the DMA address for this allocation.
///
/// This address can be programmed into device hardware for DMA access.
#[inline]
- pub fn dma_handle(&self) -> DmaAddress {
- self.dma_handle
+ pub fn dma_address(&self) -> DmaAddress {
+ self.dma_addr
}
/// Returns the size in bytes of this allocation.
@@ -1079,28 +1078,29 @@ fn drop(&mut self) {
self.dev.as_raw(),
self.size,
self.cpu_handle.as_ptr(),
- self.dma_handle,
+ self.dma_addr,
self.dma_attrs.as_raw(),
)
}
}
}
-// SAFETY: `CoherentHandle` only holds a device reference, a DMA handle, an opaque CPU handle,
+// SAFETY: `CoherentHandle` only holds a device reference, a DMA address, an opaque CPU handle,
// and a size. None of these are tied to a specific thread.
unsafe impl Send for CoherentHandle {}
// SAFETY: `CoherentHandle` provides no CPU access to the underlying allocation. The only
-// operations on `&CoherentHandle` are reading the DMA handle and size, both of which are
+// operations on `&CoherentHandle` are reading the DMA address and size, both of which are
// plain `Copy` values.
unsafe impl Sync for CoherentHandle {}
/// View type for `Coherent`.
///
-/// This is same as [`SysMem`] but with additional information that allows handing out a DMA handle.
+/// This is same as [`SysMem`] but with additional information that allows handing out a DMA
+/// address.
pub struct CoherentView<'a, T: ?Sized> {
cpu_addr: SysMem<'a, T>,
- dma_handle: DmaAddress,
+ dma_addr: DmaAddress,
}
impl<T: ?Sized> Copy for CoherentView<'_, T> {}
@@ -1112,16 +1112,16 @@ fn clone(&self) -> Self {
}
impl<'a, T: ?Sized> CoherentView<'a, T> {
- /// Erase the DMA handle information and obtain a [`SysMem`] view of the same memory region.
+ /// Erase the DMA address information and obtain a [`SysMem`] view of the same memory region.
#[inline]
pub fn as_sys_mem(self) -> SysMem<'a, T> {
self.cpu_addr
}
- /// Returns a DMA handle which may be given to the device as the DMA address base of the region.
+ /// Returns the DMA address which may be given to the device as base of the region.
#[inline]
- pub fn dma_handle(self) -> DmaAddress {
- self.dma_handle
+ pub fn dma_address(self) -> DmaAddress {
+ self.dma_addr
}
/// Returns a reference to the data in the region.
@@ -1174,9 +1174,9 @@ unsafe fn project_view<'a, T: ?Sized + KnownSize, U: ?Sized + KnownSize>(
) -> Self::View<'a, U> {
let offset = ptr.addr() - view.cpu_addr.as_ptr().addr();
// CAST: The offset DMA address can never overflow.
- let dma_handle = view.dma_handle + offset as DmaAddress;
+ let dma_addr = view.dma_addr + offset as DmaAddress;
CoherentView {
- dma_handle,
+ dma_addr,
// SAFETY: Per safety requirement.
cpu_addr: unsafe { SysMemBackend::project_view(view.cpu_addr, ptr) },
}
@@ -1241,7 +1241,7 @@ fn as_view(self) -> CoherentView<'a, Self::Target> {
CoherentView {
// SAFETY: `cpu_addr` is valid and aligned kernel accessible memory.
cpu_addr: unsafe { SysMem::new(self.cpu_addr.as_ptr()) },
- dma_handle: self.dma_handle,
+ dma_addr: self.dma_addr,
}
}
}
--
2.55.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 3/3] gpu: nova-core: falcon: use I/O projection to check transfer bounds
2026-08-05 5:01 [PATCH v2 0/3] gpu: nova-core: falcon: use I/O projections for DMA transfers Alexandre Courbot
2026-08-05 5:01 ` [PATCH v2 1/3] gpu: nova-core: falcon: remove unnecessary check Alexandre Courbot
2026-08-05 5:01 ` [PATCH v2 2/3] rust: dma: rename dma_handle to dma_address Alexandre Courbot
@ 2026-08-05 5:01 ` Alexandre Courbot
2026-08-06 21:25 ` [PATCH v2 0/3] gpu: nova-core: falcon: use I/O projections for DMA transfers Danilo Krummrich
3 siblings, 0 replies; 9+ messages in thread
From: Alexandre Courbot @ 2026-08-05 5:01 UTC (permalink / raw)
To: Danilo Krummrich, Alice Ryhl, David Airlie, Simona Vetter,
Abdiel Janulgue, Daniel Almeida, Robin Murphy, Andreas Hindborg,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Trevor Gross, Tamir Duberstein, Onur Özkan
Cc: John Hubbard, Alistair Popple, Timur Tabi, Eliot Courtney,
Zhi Wang, nova-gpu, dri-devel, linux-kernel, driver-core,
rust-for-linux, Alexandre Courbot
The DMA transfer routine was computing the start of the DMA area by
taking the address of the coherent allocation, and then adding the
transfer's start offset. It then checked manually that the upper bound
was valid.
Convert this to an I/O projection of the same region, which returns
`ERANGE` if the passed range does not fit within the coherent
allocation. This removes the need to perform arithmetic on DMA addresses
and to explicitly check for the bounds' validity.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
drivers/gpu/nova-core/falcon.rs | 55 +++++++++++++++++------------------------
1 file changed, 23 insertions(+), 32 deletions(-)
diff --git a/drivers/gpu/nova-core/falcon.rs b/drivers/gpu/nova-core/falcon.rs
index a281d316ebfd..65cb12d26e2b 100644
--- a/drivers/gpu/nova-core/falcon.rs
+++ b/drivers/gpu/nova-core/falcon.rs
@@ -12,6 +12,7 @@
DmaAddress, //
},
io::{
+ io_project,
poll::read_poll_timeout,
register::{
RegisterBase,
@@ -511,20 +512,31 @@ fn dma_wr(
) -> Result {
const DMA_LEN: u32 = num::usize_into_u32::<{ MEM_BLOCK_ALIGNMENT }>();
+ // DMA transfers can only be done in units of 256 bytes. Compute how many such transfers we
+ // need to perform.
+ let num_transfers = load_offsets.len.div_ceil(DMA_LEN);
+
// For IMEM, we want to use the start offset as a virtual address tag for each page, since
// code addresses in the firmware (and the boot vector) are virtual.
//
- // For DMEM we can fold the start offset into the DMA address.
+ // For DMEM, the start offset is folded into the DMA address.
let (src_start, dma_start) = match target_mem {
- FalconMem::ImemSecure | FalconMem::ImemNonSecure => {
- (load_offsets.src_start, dma_obj.dma_address())
- }
- FalconMem::Dmem => (
- 0,
- dma_obj.dma_address() + DmaAddress::from(load_offsets.src_start),
- ),
+ FalconMem::ImemSecure | FalconMem::ImemNonSecure => (load_offsets.src_start, 0),
+ FalconMem::Dmem => (0, usize::from_safe_cast(load_offsets.src_start)),
};
- if dma_start % DmaAddress::from(DMA_LEN) > 0 {
+
+ let dma_address = {
+ // Upper limit of transfer is `(num_transfers * DMA_LEN) + load_offsets.src_start`.
+ let dma_end = num_transfers
+ .checked_mul(DMA_LEN)
+ .and_then(|size| size.checked_add(load_offsets.src_start))
+ .map(usize::from_safe_cast)
+ .ok_or(EOVERFLOW)?;
+
+ io_project!(dma_obj, [try: dma_start..dma_end]).dma_address()
+ };
+
+ if dma_address % DmaAddress::from(DMA_LEN) > 0 {
dev_err!(
self.dev,
"DMA transfer start addresses must be a multiple of {}\n",
@@ -533,27 +545,6 @@ fn dma_wr(
return Err(EINVAL);
}
- // DMA transfers can only be done in units of 256 bytes. Compute how many such transfers we
- // need to perform.
- let num_transfers = load_offsets.len.div_ceil(DMA_LEN);
-
- // Check that the area we are about to transfer is within the bounds of the DMA object.
- // Upper limit of transfer is `(num_transfers * DMA_LEN) + load_offsets.src_start`.
- match num_transfers
- .checked_mul(DMA_LEN)
- .and_then(|size| size.checked_add(load_offsets.src_start))
- {
- None => {
- dev_err!(self.dev, "DMA transfer length overflow\n");
- return Err(EOVERFLOW);
- }
- Some(upper_bound) if usize::from_safe_cast(upper_bound) > dma_obj.size() => {
- dev_err!(self.dev, "DMA transfer goes beyond range of DMA object\n");
- return Err(EINVAL);
- }
- Some(_) => (),
- };
-
// Set up the base source DMA address.
self.bar.write(
@@ -561,12 +552,12 @@ fn dma_wr(
regs::NV_PFALCON_FALCON_DMATRFBASE::zeroed().with_base(
// CAST: `as u32` is used on purpose since we do want to strip the upper bits,
// which will be written to `NV_PFALCON_FALCON_DMATRFBASE1`.
- (dma_start >> 8) as u32,
+ (dma_address >> 8) as u32,
),
);
self.bar.write(
WithBase::of::<E>(),
- regs::NV_PFALCON_FALCON_DMATRFBASE1::zeroed().try_with_base(dma_start >> 40)?,
+ regs::NV_PFALCON_FALCON_DMATRFBASE1::zeroed().try_with_base(dma_address >> 40)?,
);
let cmd = regs::NV_PFALCON_FALCON_DMATRFCMD::zeroed()
--
2.55.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v2 1/3] gpu: nova-core: falcon: remove unnecessary check
2026-08-05 5:01 ` [PATCH v2 1/3] gpu: nova-core: falcon: remove unnecessary check Alexandre Courbot
@ 2026-08-05 7:02 ` Ethan Plant
0 siblings, 0 replies; 9+ messages in thread
From: Ethan Plant @ 2026-08-05 7:02 UTC (permalink / raw)
To: Alexandre Courbot
Cc: Danilo Krummrich, Alice Ryhl, David Airlie, Simona Vetter,
Abdiel Janulgue, Daniel Almeida, Robin Murphy, Andreas Hindborg,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Trevor Gross, Tamir Duberstein, Onur Özkan,
John Hubbard, Alistair Popple, Timur Tabi, Eliot Courtney,
Zhi Wang, nova-gpu, dri-devel, linux-kernel, driver-core,
rust-for-linux
On Tue, Aug 4, 2026 at 10:03 PM Alexandre Courbot <acourbot@nvidia.com> wrote:
>
> The `try_with_base` call performed on `NV_PFALCON_FALCON_DMATRFBASE1`
> already returns `EOVERFLOW` if the address is too large for the
> register, making this check redundant.
>
> - // The DMATRFBASE/1 register pair only supports a 49-bit address.
> - if dma_start > DmaMask::new::<49>().value() {
> - dev_err!(self.dev, "DMA address {:#x} exceeds 49 bits\n", dma_start);
> - return Err(ERANGE);
> - }
This also changes the error returned for an address that does not fit
from `ERANGE` to `EOVERFLOW`, and drops the `dev_err!` diagnostic.
Is that change intentional? If so, would it be worth
mentioning that in the commit message?
Thanks,
Ethan
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 2/3] rust: dma: rename dma_handle to dma_address
2026-08-05 5:01 ` [PATCH v2 2/3] rust: dma: rename dma_handle to dma_address Alexandre Courbot
@ 2026-08-05 11:32 ` Robin Murphy
2026-08-05 20:39 ` Danilo Krummrich
2026-08-06 21:16 ` Danilo Krummrich
1 sibling, 1 reply; 9+ messages in thread
From: Robin Murphy @ 2026-08-05 11:32 UTC (permalink / raw)
To: Alexandre Courbot, Danilo Krummrich, Alice Ryhl, David Airlie,
Simona Vetter, Abdiel Janulgue, Daniel Almeida, Andreas Hindborg,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Trevor Gross, Tamir Duberstein, Onur Özkan
Cc: John Hubbard, Alistair Popple, Timur Tabi, Eliot Courtney,
Zhi Wang, nova-gpu, dri-devel, linux-kernel, driver-core,
rust-for-linux
On 2026-08-05 6:01 am, Alexandre Courbot wrote:
> The `dma_handle` naming is inherited from the C API, but what this
> really describes is the device DMA address; everything named
> `dma_handle` is actually a `dma_addr_t`.
>
> This naming introduces some confusion on the Rust API side, as handles
> are supposed to be opaque tokens, yet we were doing address computation
> on values returned by `dma_handle`.
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.
However at the Rust level, the abstraction itself can convey (and even
enforce!) most of that, so for the sake of clarity here, particularly if
Rust programmers are likely to have their own expectations of what
"address" and "handle" mean, then I'm inclined to agree.
> Rename `dma_handle` to `dma_address` while nova-core is still its only
> user.
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
> Suggested-by: John Hubbard <jhubbard@nvidia.com>
> Suggested-by: Danilo Krummrich <dakr@kernel.org>
> Link: https://lore.kernel.org/all/DK75LUA4NLGI.3P29AIZQE20V2@kernel.org/
> Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
> ---
> drivers/gpu/nova-core/falcon.rs | 8 +--
> drivers/gpu/nova-core/fb.rs | 4 +-
> drivers/gpu/nova-core/firmware/booter.rs | 8 ++-
> drivers/gpu/nova-core/firmware/fwsec/bootloader.rs | 4 +-
> drivers/gpu/nova-core/firmware/gsp.rs | 6 +-
> drivers/gpu/nova-core/fsp.rs | 6 +-
> drivers/gpu/nova-core/gsp.rs | 2 +-
> drivers/gpu/nova-core/gsp/cmdq.rs | 8 +--
> drivers/gpu/nova-core/gsp/fw.rs | 10 ++--
> drivers/gpu/nova-core/gsp/hal/gh100.rs | 2 +-
> drivers/gpu/nova-core/gsp/hal/tu102.rs | 8 ++-
> drivers/gpu/nova-core/gsp/sequencer.rs | 8 +--
> rust/kernel/dma.rs | 70 +++++++++++-----------
> 13 files changed, 74 insertions(+), 70 deletions(-)
>
> diff --git a/drivers/gpu/nova-core/falcon.rs b/drivers/gpu/nova-core/falcon.rs
> index cd05985f5ee6..a281d316ebfd 100644
> --- a/drivers/gpu/nova-core/falcon.rs
> +++ b/drivers/gpu/nova-core/falcon.rs
> @@ -499,7 +499,7 @@ pub(crate) fn pio_load<F: FalconFirmware<Target = E> + FalconPioLoadable>(
> Ok(())
> }
>
> - /// Perform a DMA write according to `load_offsets` from `dma_handle` into the falcon's
> + /// Perform a DMA write according to `load_offsets` from `dma_obj` into the falcon's
> /// `target_mem`.
> ///
> /// `sec` is set if the loaded firmware is expected to run in secure mode.
> @@ -514,14 +514,14 @@ fn dma_wr(
> // For IMEM, we want to use the start offset as a virtual address tag for each page, since
> // code addresses in the firmware (and the boot vector) are virtual.
> //
> - // For DMEM we can fold the start offset into the DMA handle.
> + // For DMEM we can fold the start offset into the DMA address.
> let (src_start, dma_start) = match target_mem {
> FalconMem::ImemSecure | FalconMem::ImemNonSecure => {
> - (load_offsets.src_start, dma_obj.dma_handle())
> + (load_offsets.src_start, dma_obj.dma_address())
> }
> FalconMem::Dmem => (
> 0,
> - dma_obj.dma_handle() + DmaAddress::from(load_offsets.src_start),
> + dma_obj.dma_address() + DmaAddress::from(load_offsets.src_start),
> ),
> };
> if dma_start % DmaAddress::from(DMA_LEN) > 0 {
> diff --git a/drivers/gpu/nova-core/fb.rs b/drivers/gpu/nova-core/fb.rs
> index 9e475efb1150..e7ed19a61c1a 100644
> --- a/drivers/gpu/nova-core/fb.rs
> +++ b/drivers/gpu/nova-core/fb.rs
> @@ -61,7 +61,7 @@ pub(crate) fn register(
> ) -> Result<Self> {
> let page = CoherentHandle::alloc(dev, kernel::page::PAGE_SIZE, GFP_KERNEL)?;
>
> - hal::fb_hal(chipset).write_sysmem_flush_page(bar, page.dma_handle())?;
> + hal::fb_hal(chipset).write_sysmem_flush_page(bar, page.dma_address())?;
>
> Ok(Self {
> chipset,
> @@ -76,7 +76,7 @@ impl Drop for SysmemFlush<'_> {
> fn drop(&mut self) {
> let hal = hal::fb_hal(self.chipset);
>
> - if hal.read_sysmem_flush_page(self.bar) == self.page.dma_handle() {
> + if hal.read_sysmem_flush_page(self.bar) == self.page.dma_address() {
> let _ = hal.write_sysmem_flush_page(self.bar, 0).inspect_err(|e| {
> dev_warn!(
> &self.device,
> diff --git a/drivers/gpu/nova-core/firmware/booter.rs b/drivers/gpu/nova-core/firmware/booter.rs
> index acb7f4d8a532..972618e5eafe 100644
> --- a/drivers/gpu/nova-core/firmware/booter.rs
> +++ b/drivers/gpu/nova-core/firmware/booter.rs
> @@ -405,9 +405,11 @@ pub(crate) fn run<T>(
> ) -> Result {
> sec2_falcon.reset()?;
> sec2_falcon.load(self)?;
> - let wpr_handle = wpr_meta.dma_handle();
> - let (mbox0, mbox1) =
> - sec2_falcon.boot(Some(wpr_handle as u32), Some((wpr_handle >> 32) as u32))?;
> + let wpr_dma_address = wpr_meta.dma_address();
> + let (mbox0, mbox1) = sec2_falcon.boot(
> + Some(wpr_dma_address as u32),
> + Some((wpr_dma_address >> 32) as u32),
> + )?;
> dev_dbg!(dev, "SEC2 MBOX0: {:#x}, MBOX1: {:#x}\n", mbox0, mbox1);
>
> if mbox0 != 0 {
> diff --git a/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs b/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs
> index d9fafd2eea5b..c4a327af9ac7 100644
> --- a/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs
> +++ b/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs
> @@ -230,7 +230,7 @@ pub(crate) fn new(
> reserved: [0; 4],
> signature: [0; 4],
> ctx_dma: FALCON_DMAIDX_PHYS_SYS_NCOH,
> - code_dma_base: firmware_dma.dma_handle(),
> + code_dma_base: firmware_dma.dma_address(),
> // `dst_start` is also valid as the source offset since the firmware DMA object is
> // a mirror image of the target IMEM layout.
> non_sec_code_off: imem_ns.dst_start,
> @@ -242,7 +242,7 @@ pub(crate) fn new(
> code_entry_point: 0,
> // Start of data section is the added padding + the DMEM `src_start` field.
> data_dma_base: firmware_dma
> - .dma_handle()
> + .dma_address()
> .checked_add(u64::from_safe_cast(align_padding))
> .and_then(|offset| offset.checked_add(dmem.src_start.into()))
> .ok_or(EOVERFLOW)?,
> diff --git a/drivers/gpu/nova-core/firmware/gsp.rs b/drivers/gpu/nova-core/firmware/gsp.rs
> index 99a302bae567..97977f27d74b 100644
> --- a/drivers/gpu/nova-core/firmware/gsp.rs
> +++ b/drivers/gpu/nova-core/firmware/gsp.rs
> @@ -161,9 +161,9 @@ pub(crate) fn new<'a>(
> })
> }
>
> - /// Returns the DMA handle of the radix3 level 0 page table.
> - pub(crate) fn radix3_dma_handle(&self) -> DmaAddress {
> - self.level0.dma_handle()
> + /// Returns the DMA address of the radix3 level 0 page table.
> + pub(crate) fn radix3_dma_address(&self) -> DmaAddress {
> + self.level0.dma_address()
> }
> }
>
> diff --git a/drivers/gpu/nova-core/fsp.rs b/drivers/gpu/nova-core/fsp.rs
> index ba4544210e40..1721a8387636 100644
> --- a/drivers/gpu/nova-core/fsp.rs
> +++ b/drivers/gpu/nova-core/fsp.rs
> @@ -287,12 +287,12 @@ fn new<'a>(
> .chain(move |msg| {
> msg.cot.version = version;
> msg.cot.size = size;
> - msg.cot.gsp_fmc_sysmem_offset = fsp_fw.fmc_image.dma_handle();
> + msg.cot.gsp_fmc_sysmem_offset = fsp_fw.fmc_image.dma_address();
> msg.cot.frts_vidmem_offset = frts_vidmem_offset;
> msg.cot.frts_vidmem_size = frts_size;
> // frts_sysmem_* are left at zero because this path places FRTS in vidmem. The sysmem
> // fields point to an FRTS buffer in sysmem instead, for systems without VRAM.
> - msg.cot.gsp_boot_args_sysmem_offset = args.fmc_boot_params.dma_handle();
> + msg.cot.gsp_boot_args_sysmem_offset = args.fmc_boot_params.dma_address();
> msg.cot.sigs = *fsp_fw.fmc_sigs;
>
> Ok(())
> @@ -353,7 +353,7 @@ pub(crate) fn new(
> libos: &'a Coherent<[LibosMemoryRegionInitArgument]>,
> resume: bool,
> ) -> Result<Self> {
> - let init = GspFmcBootParams::new(wpr_meta.dma_handle(), libos.dma_handle());
> + let init = GspFmcBootParams::new(wpr_meta.dma_address(), libos.dma_address());
>
> Ok(Self {
> chipset,
> diff --git a/drivers/gpu/nova-core/gsp.rs b/drivers/gpu/nova-core/gsp.rs
> index b403dc3515a5..13f361406a6c 100644
> --- a/drivers/gpu/nova-core/gsp.rs
> +++ b/drivers/gpu/nova-core/gsp.rs
> @@ -122,7 +122,7 @@ impl LogBuffer {
> fn new(dev: &device::Device<device::Bound>) -> Result<Self> {
> let obj = Self(Coherent::zeroed(dev, GFP_KERNEL)?);
>
> - let start_addr = obj.0.dma_handle();
> + let start_addr = obj.0.dma_address();
>
> let pte_view = io_project!(
> obj.0,
> diff --git a/drivers/gpu/nova-core/gsp/cmdq.rs b/drivers/gpu/nova-core/gsp/cmdq.rs
> index cd844fe48f05..f0f28b6ded7a 100644
> --- a/drivers/gpu/nova-core/gsp/cmdq.rs
> +++ b/drivers/gpu/nova-core/gsp/cmdq.rs
> @@ -243,7 +243,7 @@ fn new(dev: &device::Device<device::Bound>) -> Result<Self> {
> gsp_mem.cpuq.rx = MsgqRxHeader::new();
>
> let gsp_mem: Coherent<_> = gsp_mem.into();
> - PteArray::init(io_project!(gsp_mem, .ptes), gsp_mem.dma_handle())?;
> + PteArray::init(io_project!(gsp_mem, .ptes), gsp_mem.dma_address())?;
>
> Ok(Self(gsp_mem))
> }
> @@ -487,8 +487,8 @@ pub(crate) struct Cmdq {
> /// Inner mutex-protected state.
> #[pin]
> inner: Mutex<CmdqInner>,
> - /// DMA handle of the command queue's shared memory region.
> - pub(super) dma_handle: DmaAddress,
> + /// DMA address of the command queue's shared memory region.
> + pub(super) dma_addr: DmaAddress,
> }
>
> impl Cmdq {
> @@ -517,7 +517,7 @@ pub(crate) fn new(dev: &device::Device<device::Bound>) -> impl PinInit<Self, Err
> let gsp_mem = DmaGspMem::new(dev)?;
>
> Ok(try_pin_init!(Self {
> - dma_handle: gsp_mem.0.dma_handle(),
> + dma_addr: gsp_mem.0.dma_address(),
> inner <- new_mutex!(CmdqInner {
> dev: dev.into(),
> gsp_mem,
> diff --git a/drivers/gpu/nova-core/gsp/fw.rs b/drivers/gpu/nova-core/gsp/fw.rs
> index 6e8e7d822ef1..a237db74cad5 100644
> --- a/drivers/gpu/nova-core/gsp/fw.rs
> +++ b/drivers/gpu/nova-core/gsp/fw.rs
> @@ -183,16 +183,16 @@ pub(crate) fn new<'a>(
> // CAST: we want to store the bits of `GSP_FW_WPR_META_MAGIC` unmodified.
> magic: bindings::GSP_FW_WPR_META_MAGIC as u64,
> revision: u64::from(bindings::GSP_FW_WPR_META_REVISION),
> - sysmemAddrOfRadix3Elf: gsp_firmware.radix3_dma_handle(),
> + sysmemAddrOfRadix3Elf: gsp_firmware.radix3_dma_address(),
> sizeOfRadix3Elf: u64::from_safe_cast(gsp_firmware.size),
> - sysmemAddrOfBootloader: gsp_firmware.bootloader.ucode.dma_handle(),
> + sysmemAddrOfBootloader: gsp_firmware.bootloader.ucode.dma_address(),
> sizeOfBootloader: u64::from_safe_cast(gsp_firmware.bootloader.ucode.size()),
> bootloaderCodeOffset: u64::from(gsp_firmware.bootloader.code_offset),
> bootloaderDataOffset: u64::from(gsp_firmware.bootloader.data_offset),
> bootloaderManifestOffset: u64::from(gsp_firmware.bootloader.manifest_offset),
> __bindgen_anon_1: GspFwWprMetaBootResumeInfo {
> __bindgen_anon_1: GspFwWprMetaBootInfo {
> - sysmemAddrOfSignature: gsp_firmware.signatures.dma_handle(),
> + sysmemAddrOfSignature: gsp_firmware.signatures.dma_address(),
> sizeOfSignature: u64::from_safe_cast(gsp_firmware.signatures.size()),
> },
> },
> @@ -635,7 +635,7 @@ fn id8(name: &str) -> u64 {
>
> let init_inner = init!(bindings::LibosMemoryRegionInitArgument {
> id8: id8(name),
> - pa: obj.dma_handle(),
> + pa: obj.dma_address(),
> size: num::usize_as_u64(obj.size()),
> kind: num::u32_into_u8::<
> { bindings::LibosMemoryRegionKind_LIBOS_MEMORY_REGION_CONTIGUOUS },
> @@ -901,7 +901,7 @@ impl MessageQueueInitArguments {
> /// Creates a new init arguments structure for `cmdq`.
> fn new(cmdq: &Cmdq) -> impl Init<Self> + '_ {
> init!(MessageQueueInitArguments {
> - sharedMemPhysAddr: cmdq.dma_handle,
> + sharedMemPhysAddr: cmdq.dma_addr,
> pageTableEntryCount: num::usize_into_u32::<{ Cmdq::NUM_PTES }>(),
> cmdQueueOffset: num::usize_as_u64(Cmdq::CMDQ_OFFSET),
> statQueueOffset: num::usize_as_u64(Cmdq::STATQ_OFFSET),
> diff --git a/drivers/gpu/nova-core/gsp/hal/gh100.rs b/drivers/gpu/nova-core/gsp/hal/gh100.rs
> index 22b60f9233de..8e219a0cb164 100644
> --- a/drivers/gpu/nova-core/gsp/hal/gh100.rs
> +++ b/drivers/gpu/nova-core/gsp/hal/gh100.rs
> @@ -63,7 +63,7 @@ fn lockdown_released_or_error(
> // boot. If the address is still there, keep polling rather than treating it as an error.
> // Any other non-zero mailbox0 value is a GSP-FMC error code.
> if self.mbox0 != 0 {
> - return self.combined_addr() != fmc_boot_params.dma_handle();
> + return self.combined_addr() != fmc_boot_params.dma_address();
> }
>
> !gsp_falcon.riscv_branch_privilege_lockdown()
> diff --git a/drivers/gpu/nova-core/gsp/hal/tu102.rs b/drivers/gpu/nova-core/gsp/hal/tu102.rs
> index 03133f723faf..26ac1adba1bf 100644
> --- a/drivers/gpu/nova-core/gsp/hal/tu102.rs
> +++ b/drivers/gpu/nova-core/gsp/hal/tu102.rs
> @@ -286,9 +286,11 @@ fn boot(
> }
>
> gsp_falcon.reset()?;
> - let libos_handle = gsp.libos.dma_handle();
> - let (mbox0, mbox1) =
> - gsp_falcon.boot(Some(libos_handle as u32), Some((libos_handle >> 32) as u32))?;
> + let libos_dma_address = gsp.libos.dma_address();
> + let (mbox0, mbox1) = gsp_falcon.boot(
> + Some(libos_dma_address as u32),
> + Some((libos_dma_address >> 32) as u32),
> + )?;
> dev_dbg!(dev, "GSP MBOX0: {:#x}, MBOX1: {:#x}\n", mbox0, mbox1);
>
> dev_dbg!(
> diff --git a/drivers/gpu/nova-core/gsp/sequencer.rs b/drivers/gpu/nova-core/gsp/sequencer.rs
> index 5e1ec7e59ab0..bcad1421953a 100644
> --- a/drivers/gpu/nova-core/gsp/sequencer.rs
> +++ b/drivers/gpu/nova-core/gsp/sequencer.rs
> @@ -234,12 +234,12 @@ fn run(&self, seq: &GspSequencer<'_>) -> Result {
> // Reset the GSP to prepare it for resuming.
> seq.gsp_falcon.reset()?;
>
> - let libos_dma_handle = seq.libos.dma_handle();
> + let libos_dma_address = seq.libos.dma_address();
>
> - // Write the libOS DMA handle to GSP mailboxes.
> + // Write the libOS DMA address to GSP mailboxes.
> seq.gsp_falcon.write_mailboxes(
> - Some(libos_dma_handle as u32),
> - Some((libos_dma_handle >> 32) as u32),
> + Some(libos_dma_address as u32),
> + Some((libos_dma_address >> 32) as u32),
> );
>
> // Start the SEC2 falcon which will trigger GSP-RM to resume on the GSP.
> diff --git a/rust/kernel/dma.rs b/rust/kernel/dma.rs
> index e275f2562a5b..4258ff7ff525 100644
> --- a/rust/kernel/dma.rs
> +++ b/rust/kernel/dma.rs
> @@ -585,7 +585,7 @@ fn from(value: CoherentBox<T>) -> Self {
> /// # Invariants
> ///
> /// - For the lifetime of an instance of [`Coherent`], the `cpu_addr` is a valid pointer
> -/// to an allocated region of coherent memory and `dma_handle` is the DMA address base of the
> +/// to an allocated region of coherent memory and `dma_addr` is the DMA address base of the
> /// region.
> /// - The size in bytes of the allocation is equal to size information via pointer.
> // TODO
> @@ -602,7 +602,7 @@ fn from(value: CoherentBox<T>) -> Self {
> // entire `Coherent` including the allocated memory itself.
> pub struct Coherent<T: KnownSize + ?Sized> {
> dev: ARef<device::Device>,
> - dma_handle: DmaAddress,
> + dma_addr: DmaAddress,
> cpu_addr: NonNull<T>,
> dma_attrs: Attrs,
> }
> @@ -627,11 +627,10 @@ pub fn as_mut_ptr(&self) -> *mut T {
> self.cpu_addr.as_ptr()
> }
>
> - /// Returns a DMA handle which may be given to the device as the DMA address base of
> - /// the region.
> + /// Returns a DMA address which may be given to the device as the base of the region.
> #[inline]
> - pub fn dma_handle(&self) -> DmaAddress {
> - self.dma_handle
> + pub fn dma_address(&self) -> DmaAddress {
> + self.dma_addr
> }
>
> /// Returns a reference to the data in the region.
> @@ -678,13 +677,13 @@ fn alloc_with_attrs(
> );
> }
>
> - let mut dma_handle = 0;
> + let mut dma_addr = 0;
> // SAFETY: Device pointer is guaranteed as valid by the type invariant on `Device`.
> let addr = unsafe {
> bindings::dma_alloc_attrs(
> dev.as_raw(),
> core::mem::size_of::<T>(),
> - &mut dma_handle,
> + &mut dma_addr,
> gfp_flags.as_raw(),
> dma_attrs.as_raw(),
> )
> @@ -696,7 +695,7 @@ fn alloc_with_attrs(
> // - We also hold a refcounted reference to the device.
> Ok(Self {
> dev: dev.into(),
> - dma_handle,
> + dma_addr,
> cpu_addr,
> dma_attrs,
> })
> @@ -795,13 +794,13 @@ fn alloc_slice_with_attrs(
> }
>
> let size = core::mem::size_of::<T>().checked_mul(len).ok_or(ENOMEM)?;
> - let mut dma_handle = 0;
> + let mut dma_addr = 0;
> // SAFETY: Device pointer is guaranteed as valid by the type invariant on `Device`.
> let addr = unsafe {
> bindings::dma_alloc_attrs(
> dev.as_raw(),
> size,
> - &mut dma_handle,
> + &mut dma_addr,
> gfp_flags.as_raw(),
> dma_attrs.as_raw(),
> )
> @@ -813,7 +812,7 @@ fn alloc_slice_with_attrs(
> // - We also hold a refcounted reference to the device.
> Ok(Coherent {
> dev: dev.into(),
> - dma_handle,
> + dma_addr,
> cpu_addr,
> dma_attrs,
> })
> @@ -927,14 +926,14 @@ impl<T: KnownSize + ?Sized> Drop for Coherent<T> {
> fn drop(&mut self) {
> let size = T::size(self.cpu_addr.as_ptr());
> // SAFETY: Device pointer is guaranteed as valid by the type invariant on `Device`.
> - // The cpu address, and the dma handle are valid due to the type invariants on
> + // The cpu address, and the dma address are valid due to the type invariants on
> // `Coherent`.
> unsafe {
> bindings::dma_free_attrs(
> self.dev.as_raw(),
> size,
> self.cpu_addr.as_ptr().cast(),
> - self.dma_handle,
> + self.dma_addr,
> self.dma_attrs.as_raw(),
> )
> }
> @@ -989,13 +988,13 @@ fn write_to_slice(
> ///
> /// - `cpu_handle` holds the opaque handle returned by `dma_alloc_attrs` with
> /// `DMA_ATTR_NO_KERNEL_MAPPING` set, and is only valid for passing back to `dma_free_attrs`.
> -/// - `dma_handle` is the corresponding bus address for device DMA.
> +/// - `dma_addr` is the corresponding bus address for device DMA.
> /// - `size` is the allocation size in bytes as passed to `dma_alloc_attrs`.
> /// - `dma_attrs` contains the attributes used for the allocation, always including
> /// `DMA_ATTR_NO_KERNEL_MAPPING`.
> pub struct CoherentHandle {
> dev: ARef<device::Device>,
> - dma_handle: DmaAddress,
> + dma_addr: DmaAddress,
> cpu_handle: NonNull<c_void>,
> size: usize,
> dma_attrs: Attrs,
> @@ -1019,13 +1018,13 @@ pub fn alloc_with_attrs(
> }
>
> let dma_attrs = dma_attrs | Attrs(bindings::DMA_ATTR_NO_KERNEL_MAPPING);
> - let mut dma_handle = 0;
> + let mut dma_addr = 0;
> // SAFETY: `dev.as_raw()` is valid by the type invariant on `device::Device`.
> let cpu_handle = unsafe {
> bindings::dma_alloc_attrs(
> dev.as_raw(),
> size,
> - &mut dma_handle,
> + &mut dma_addr,
> gfp_flags.as_raw(),
> dma_attrs.as_raw(),
> )
> @@ -1034,11 +1033,11 @@ pub fn alloc_with_attrs(
> let cpu_handle = NonNull::new(cpu_handle).ok_or(ENOMEM)?;
>
> // INVARIANT: `cpu_handle` is the opaque handle from a successful `dma_alloc_attrs` call
> - // with `DMA_ATTR_NO_KERNEL_MAPPING`, `dma_handle` is the corresponding DMA address,
> + // with `DMA_ATTR_NO_KERNEL_MAPPING`, `dma_addr` is the corresponding DMA address,
> // and we hold a refcounted reference to the device.
> Ok(Self {
> dev: dev.into(),
> - dma_handle,
> + dma_addr,
> cpu_handle,
> size,
> dma_attrs,
> @@ -1055,12 +1054,12 @@ pub fn alloc(
> Self::alloc_with_attrs(dev, size, gfp_flags, Attrs(0))
> }
>
> - /// Returns the DMA handle for this allocation.
> + /// Returns the DMA address for this allocation.
> ///
> /// This address can be programmed into device hardware for DMA access.
> #[inline]
> - pub fn dma_handle(&self) -> DmaAddress {
> - self.dma_handle
> + pub fn dma_address(&self) -> DmaAddress {
> + self.dma_addr
> }
>
> /// Returns the size in bytes of this allocation.
> @@ -1079,28 +1078,29 @@ fn drop(&mut self) {
> self.dev.as_raw(),
> self.size,
> self.cpu_handle.as_ptr(),
> - self.dma_handle,
> + self.dma_addr,
> self.dma_attrs.as_raw(),
> )
> }
> }
> }
>
> -// SAFETY: `CoherentHandle` only holds a device reference, a DMA handle, an opaque CPU handle,
> +// SAFETY: `CoherentHandle` only holds a device reference, a DMA address, an opaque CPU handle,
> // and a size. None of these are tied to a specific thread.
> unsafe impl Send for CoherentHandle {}
>
> // SAFETY: `CoherentHandle` provides no CPU access to the underlying allocation. The only
> -// operations on `&CoherentHandle` are reading the DMA handle and size, both of which are
> +// operations on `&CoherentHandle` are reading the DMA address and size, both of which are
> // plain `Copy` values.
> unsafe impl Sync for CoherentHandle {}
>
> /// View type for `Coherent`.
> ///
> -/// This is same as [`SysMem`] but with additional information that allows handing out a DMA handle.
> +/// This is same as [`SysMem`] but with additional information that allows handing out a DMA
> +/// address.
> pub struct CoherentView<'a, T: ?Sized> {
> cpu_addr: SysMem<'a, T>,
> - dma_handle: DmaAddress,
> + dma_addr: DmaAddress,
> }
>
> impl<T: ?Sized> Copy for CoherentView<'_, T> {}
> @@ -1112,16 +1112,16 @@ fn clone(&self) -> Self {
> }
>
> impl<'a, T: ?Sized> CoherentView<'a, T> {
> - /// Erase the DMA handle information and obtain a [`SysMem`] view of the same memory region.
> + /// Erase the DMA address information and obtain a [`SysMem`] view of the same memory region.
> #[inline]
> pub fn as_sys_mem(self) -> SysMem<'a, T> {
> self.cpu_addr
> }
>
> - /// Returns a DMA handle which may be given to the device as the DMA address base of the region.
> + /// Returns the DMA address which may be given to the device as base of the region.
> #[inline]
> - pub fn dma_handle(self) -> DmaAddress {
> - self.dma_handle
> + pub fn dma_address(self) -> DmaAddress {
> + self.dma_addr
> }
>
> /// Returns a reference to the data in the region.
> @@ -1174,9 +1174,9 @@ unsafe fn project_view<'a, T: ?Sized + KnownSize, U: ?Sized + KnownSize>(
> ) -> Self::View<'a, U> {
> let offset = ptr.addr() - view.cpu_addr.as_ptr().addr();
> // CAST: The offset DMA address can never overflow.
> - let dma_handle = view.dma_handle + offset as DmaAddress;
> + let dma_addr = view.dma_addr + offset as DmaAddress;
> CoherentView {
> - dma_handle,
> + dma_addr,
> // SAFETY: Per safety requirement.
> cpu_addr: unsafe { SysMemBackend::project_view(view.cpu_addr, ptr) },
> }
> @@ -1241,7 +1241,7 @@ fn as_view(self) -> CoherentView<'a, Self::Target> {
> CoherentView {
> // SAFETY: `cpu_addr` is valid and aligned kernel accessible memory.
> cpu_addr: unsafe { SysMem::new(self.cpu_addr.as_ptr()) },
> - dma_handle: self.dma_handle,
> + dma_addr: self.dma_addr,
> }
> }
> }
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 2/3] rust: dma: rename dma_handle to dma_address
2026-08-05 11:32 ` Robin Murphy
@ 2026-08-05 20:39 ` Danilo Krummrich
0 siblings, 0 replies; 9+ messages in thread
From: Danilo Krummrich @ 2026-08-05 20:39 UTC (permalink / raw)
To: Robin Murphy
Cc: Alexandre Courbot, Alice Ryhl, David Airlie, Simona Vetter,
Abdiel Janulgue, Daniel Almeida, Andreas Hindborg, Miguel Ojeda,
Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
Trevor Gross, Tamir Duberstein, Onur Özkan, John Hubbard,
Alistair Popple, Timur Tabi, Eliot Courtney, Zhi Wang, nova-gpu,
dri-devel, linux-kernel, driver-core, rust-for-linux
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.
[1] https://github.com/Rust-for-Linux/linux/issues/1248
> However at the Rust level, the abstraction itself can convey (and even
> enforce!) most of that, so for the sake of clarity here, particularly if
> Rust programmers are likely to have their own expectations of what
> "address" and "handle" mean, then I'm inclined to agree.
Yeah, as mentioned in the link below, the handle that represents the allocation
are the DMA container types (such as dma::Coherent) themselves.
>> Link: https://lore.kernel.org/all/DK75LUA4NLGI.3P29AIZQE20V2@kernel.org/
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 2/3] rust: dma: rename dma_handle to dma_address
2026-08-05 5:01 ` [PATCH v2 2/3] rust: dma: rename dma_handle to dma_address Alexandre Courbot
2026-08-05 11:32 ` Robin Murphy
@ 2026-08-06 21:16 ` Danilo Krummrich
1 sibling, 0 replies; 9+ messages in thread
From: Danilo Krummrich @ 2026-08-06 21:16 UTC (permalink / raw)
To: Alexandre Courbot
Cc: Alice Ryhl, David Airlie, Simona Vetter, Abdiel Janulgue,
Daniel Almeida, Robin Murphy, Andreas Hindborg, Miguel Ojeda,
Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
Trevor Gross, Tamir Duberstein, Onur Özkan, John Hubbard,
Alistair Popple, Timur Tabi, Eliot Courtney, Zhi Wang, nova-gpu,
dri-devel, linux-kernel, driver-core, rust-for-linux
On Wed Aug 5, 2026 at 7:01 AM CEST, Alexandre Courbot wrote:
> pub struct Coherent<T: KnownSize + ?Sized> {
> dev: ARef<device::Device>,
> - dma_handle: DmaAddress,
> + dma_addr: DmaAddress,
> cpu_addr: NonNull<T>,
> dma_attrs: Attrs,
> }
From the perspective of the DMA API the value actually serves as a handle for
the C API, so we could have also renamed the accessor only. But I think it is
fine either way.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 0/3] gpu: nova-core: falcon: use I/O projections for DMA transfers
2026-08-05 5:01 [PATCH v2 0/3] gpu: nova-core: falcon: use I/O projections for DMA transfers Alexandre Courbot
` (2 preceding siblings ...)
2026-08-05 5:01 ` [PATCH v2 3/3] gpu: nova-core: falcon: use I/O projection to check transfer bounds Alexandre Courbot
@ 2026-08-06 21:25 ` Danilo Krummrich
3 siblings, 0 replies; 9+ messages in thread
From: Danilo Krummrich @ 2026-08-06 21:25 UTC (permalink / raw)
To: Alexandre Courbot
Cc: Danilo Krummrich, Alice Ryhl, David Airlie, Simona Vetter,
Abdiel Janulgue, Daniel Almeida, Robin Murphy, Andreas Hindborg,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Trevor Gross, Tamir Duberstein, Onur Özkan,
John Hubbard, Alistair Popple, Timur Tabi, Eliot Courtney,
Zhi Wang, nova-gpu, dri-devel, linux-kernel, driver-core,
rust-for-linux
On Wed, 05 Aug 2026 14:01:44 +0900, Alexandre Courbot wrote:
> [PATCH v2 0/3] gpu: nova-core: falcon: use I/O projections for DMA transfers
Applied, thanks!
Branch: drm-rust-next
Tree: https://gitlab.freedesktop.org/drm/rust/kernel.git
[1/3] gpu: nova-core: falcon: remove unnecessary check
commit: d1dc8faf1152
[2/3] rust: dma: rename dma_handle to dma_address
commit: 91645a52ebf2
[ Rebase and fix up build failures due to newly introduced dma_handle()
calls. - Danilo ]
[3/3] gpu: nova-core: falcon: use I/O projection to check transfer bounds
commit: 4c9ba407018e
The patches will appear in the next linux-next integration (typically within 24
hours on weekdays).
The patches are queued up for the upcoming merge window for the next major
kernel release.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-08-06 21:25 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-05 5:01 [PATCH v2 0/3] gpu: nova-core: falcon: use I/O projections for DMA transfers Alexandre Courbot
2026-08-05 5:01 ` [PATCH v2 1/3] gpu: nova-core: falcon: remove unnecessary check Alexandre Courbot
2026-08-05 7:02 ` Ethan Plant
2026-08-05 5:01 ` [PATCH v2 2/3] rust: dma: rename dma_handle to dma_address Alexandre Courbot
2026-08-05 11:32 ` Robin Murphy
2026-08-05 20:39 ` Danilo Krummrich
2026-08-06 21:16 ` Danilo Krummrich
2026-08-05 5:01 ` [PATCH v2 3/3] gpu: nova-core: falcon: use I/O projection to check transfer bounds Alexandre Courbot
2026-08-06 21:25 ` [PATCH v2 0/3] gpu: nova-core: falcon: use I/O projections for DMA transfers Danilo Krummrich
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox