rust: add pointer projection infrastructure and convert DMA
Subsystems (7)
v4 cover rust: add pointer projection infrastructure and convert DMA
From: Gary Guo <[email protected]>
This adds a general pointer projection infrastructure which is intended to serve as the basis for generic I/O projections. The idea is that we will have a unified way of reading/writing MMIO or DMA allocation, creating typed subviews into them, and able to read/write subfields safely.
This is the first step towards that direction, where an infra for projecting arbitrary pointers are added. This takes care to not assume pointers are part of a valid allocation, so it can be used to project I/O pointers, too. dma_read! and dma_write! is converted to use this infra, as they currently have soundness issues [1] and users have already encountered limitation of it [2].
---
Changes since v3:
- Add KnownSize trait for documenting safety requirement of
ProjectIndex and updated safety comments accordingly (Benno)
- Some comment rewording (Benno)
- Move code to be under ptr module.
- Link to v3: https://lore.kernel.org/rust-for-linux/[email protected]/
Changes since v2:
- Fix off-by-one issue (Aditya)
- Fix comment (Aditya)
- Link to v2: https://lore.kernel.org/rust-for-linux/[email protected]/
Changes since v1:
- Squashed patch 2,3,4 so that all users are converted in single commit
(Danilo)
- I discovered an additional soundness bug in dma_read/write macros
where it can create misaligned access. This is addressed in this new
version.
- Updated sample driver to have a function that does check instead use a budget-try block (Benno)
- Improved diagnostics when index projection is used on types that are
not slices.
- Link to v1: https://lore.kernel.org/rust-for-linux/[email protected]/
---
Gary Guo (3):
rust: ptr: add KnownSize trait to support DST size info extraction
rust: ptr: add projection infrastructure
rust: dma: use pointer projection infra for dma_{read,write} macro
drivers/gpu/nova-core/gsp.rs | 14 +- drivers/gpu/nova-core/gsp/boot.rs | 2 +- drivers/gpu/nova-core/gsp/cmdq.rs | 10 +- rust/kernel/dma.rs | 114 +++++------- rust/kernel/lib.rs | 4 + rust/kernel/ptr.rs | 30 ++- rust/kernel/ptr/projection.rs | 294 ++++++++++++++++++++++++++++++ samples/rust/rust_dma.rs | 30 +-- scripts/Makefile.build | 4 +- 9 files changed, 411 insertions(+), 91 deletions(-) create mode 100644 rust/kernel/ptr/projection.rs
base-commit: 877552aa875839314afad7154b5a561889e87ea9
Signature · 1 line
2.51.2
PATCH v4 1/3 rust: ptr: add `KnownSize` trait to support DST size info extraction
From: Gary Guo <[email protected]>
Add a KnownSize trait which is used obtain a size from a raw pointer's metadata. This makes it possible to obtain size information on a raw slice pointer. This is similar to Rust core::mem::size_of_val_raw which is not yet stable.
--- rust/kernel/lib.rs | 1 + rust/kernel/ptr.rs | 27 ++++++++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-)
rust/kernel/lib.rs +1 -0
@@ -20,6 +20,7 @@#![feature(generic_nonzero)] #![feature(inline_const)] #![feature(pointer_is_aligned)] +#![feature(slice_ptr_len)] // // Stable since Rust 1.80.0. #![feature(slice_flatten)]
rust/kernel/ptr.rs +26 -1
@@ -2,7 +2,10 @@//! Types and functions to work with pointers and addresses. -use core::mem::align_of; +use core::mem::{ + align_of, + size_of,// +};use core::num::NonZero ;/// Type representing an alignment, which is always a power of two.
@@ -225,3 +228,25 @@ fn align_up(self, alignment: Alignment) -> Option<Self> { }impl_alignable_uint! (u8 ,u16 ,u32 ,u64 ,usize ); + +/// Trait to represent compile-time known size information. +/// +/// This is a generalization of what [`size_of`] which works for dynamically sized types. +pub trait KnownSize { +/// Get the size of an object of this type in bytes, with the metadata of the given pointer. +fn size (p: *const Self ) ->usize ; +} + +impl <T >KnownSize for T { +#[inline(always)] +fn size (_: *const Self ) ->usize { +size_of ::<T >() + } +} + +impl <T >KnownSize for [T ] { +#[inline(always)] +fn size (p: *const Self ) ->usize { + p.len () *size_of ::<T >() + } +}
Signature · 1 line
2.51.2
Re: [PATCH v4 1/3] rust: ptr: add `KnownSize` trait to support DST size info extraction
Quoted 8 lines · Gary Guo
From: Gary Guo <[email protected]>
Add a
KnownSizetrait which is used obtain a size from a raw pointer's metadata. This makes it possible to obtain size information on a raw slice pointer. This is similar to Rustcore::mem::size_of_val_rawwhich is not yet stable.Signed-off-by Gary Guo <[email protected]>
Found a typo below.
Quoted 34 lines
--- rust/kernel/lib.rs | 1 + rust/kernel/ptr.rs | 27 ++++++++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-)rust/kernel/lib.rs +1
-0@@ -20,6 +20,7 @@#![feature(generic_nonzero)] #![feature(inline_const)] #![feature(pointer_is_aligned)] +#![feature(slice_ptr_len)] // // Stable since Rust 1.80.0. #![feature(slice_flatten)] rust/kernel/ptr.rs +4
-1@@ -2,7 +2,10 @@//! Types and functions to work with pointers and addresses. -use core::mem::align_of; +use core::mem::{ + align_of, + size_of,// +};use core::num::NonZero ;/// Type representing an alignment, which is always a power of two.
rust/kernel/ptr.rs fn align_up(self, alignment: Alignment) -> Option<Self> { · line 234
Quoted 7 lines
rust/kernel/ptr.rs +4
-0@@ -225,3 +228,25 @@ fn align_up(self, alignment: Alignment) -> Option<Self> { }impl_alignable_uint! (u8 ,u16 ,u32 ,u64 ,usize ); + +/// Trait to represent compile-time known size information. +/// +/// This is a generalization of what [`size_of`] which works for dynamically sized types.
s/what//
Cheers,
Benno
Quoted 18 lines
rust/kernel/ptr.rs +18
-0+pub trait KnownSize { +/// Get the size of an object of this type in bytes, with the metadata of the given pointer. +fn size (p: *const Self ) ->usize ; +} + +impl <T >KnownSize for T { +#[inline(always)] +fn size (_: *const Self ) ->usize { +size_of ::<T >() + } +} + +impl <T >KnownSize for [T ] { +#[inline(always)] +fn size (p: *const Self ) ->usize { + p.len () *size_of ::<T >() + } +}
Benno Lossin
reviewerRe: [PATCH v4 1/3] rust: ptr: add `KnownSize` trait to support DST size info extraction
In reply to Gary GuoQuoted 18 lines · Gary Guo
From: Gary Guo <[email protected]>
Add a
KnownSizetrait which is used obtain a size from a raw pointer's metadata. This makes it possible to obtain size information on a raw slice pointer. This is similar to Rustcore::mem::size_of_val_rawwhich is not yet stable.Signed-off-by Gary Guo <[email protected]>--- rust/kernel/lib.rs | 1 + rust/kernel/ptr.rs | 27 ++++++++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-)rust/kernel/lib.rs +0
-0
rust/kernel/lib.rs line 23
Quoted 4 lines
rust/kernel/lib.rs +1
-0@@ -20,6 +20,7 @@#![feature(generic_nonzero)] #![feature(inline_const)] #![feature(pointer_is_aligned)] +#![feature(slice_ptr_len)]
Oh and this is also missing a stability comment.
Cheers,
Benno
Quoted 3 lines
rust/kernel/lib.rs +0
-0// // Stable since Rust 1.80.0. #![feature(slice_flatten)]
Gary Guo
reviewerRe: [PATCH v4 1/3] rust: ptr: add `KnownSize` trait to support DST size info extraction
Quoted 14 lines · Benno Lossin
Quoted 13 lines · Gary Guo
From: Gary Guo <[email protected]>
Add a
KnownSizetrait which is used obtain a size from a raw pointer's metadata. This makes it possible to obtain size information on a raw slice pointer. This is similar to Rustcore::mem::size_of_val_rawwhich is not yet stable.Signed-off-by Gary Guo <[email protected]>--- rust/kernel/lib.rs | 1 + rust/kernel/ptr.rs | 27 ++++++++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-)
Quoted 11 lines
rust/kernel/lib.rs line 23
Quoted 9 lines
rust/kernel/lib.rs +1
-0@@ -20,6 +20,7 @@#![feature(generic_nonzero)] #![feature(inline_const)] #![feature(pointer_is_aligned)] +#![feature(slice_ptr_len)] Oh and this is also missing a stability comment.
I don't see anything missing here? This is in the same group as other features that are stable in 1.79.
Best,
Gary
Quoted 7 lines
Cheers,
BennoQuoted 3 lines
rust/kernel/lib.rs +0
-0// // Stable since Rust 1.80.0. #![feature(slice_flatten)]
Benno Lossin
reviewerRe: [PATCH v4 1/3] rust: ptr: add `KnownSize` trait to support DST size info extraction
Quoted 27 lines · Gary Guo
Quoted 14 lines · Benno Lossin
Quoted 13 lines · Gary Guo
From: Gary Guo <[email protected]>
Add a
KnownSizetrait which is used obtain a size from a raw pointer's metadata. This makes it possible to obtain size information on a raw slice pointer. This is similar to Rustcore::mem::size_of_val_rawwhich is not yet stable.Signed-off-by Gary Guo <[email protected]>--- rust/kernel/lib.rs | 1 + rust/kernel/ptr.rs | 27 ++++++++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-)Quoted 11 lines
rust/kernel/lib.rs line 23
Quoted 9 lines
rust/kernel/lib.rs +1
-0@@ -20,6 +20,7 @@#![feature(generic_nonzero)] #![feature(inline_const)] #![feature(pointer_is_aligned)] +#![feature(slice_ptr_len)] Oh and this is also missing a stability comment.
Quoted 2 lines
I don't see anything missing here? This is in the same group as other features that are stable in 1.79.
I didn't look at the file & only at the hunk.
Cheers,
Benno
PATCH v4 2/3 rust: ptr: add projection infrastructure
In reply to Gary GuoFrom: Gary Guo <[email protected]>
Add a generic infrastructure for performing field and index projections on raw pointers. This will form the basis of performing I/O projections.
Pointers manipulations are intentionally using the safe wrapping variants instead of the unsafe variants, as the latter requires pointers to be inside an allocation which is not necessarily true for I/O pointers.
This projection macro protects against rogue Deref implementation, which can causes the projected pointer to be outside the bounds of starting pointer. This is extremely unlikely and Rust has a lint to catch this, but is unsoundness regardless. The protection works by inducing type inference ambiguity when Deref is implemented.
This projection macro also stops projecting into unaligned fields (i.e. fields of #[repr(packed)] structs), as misaligned pointers require special handling. This is implemented by attempting to create reference to projected field inside a if false block. Despite being unreachable, Rust still checks that they're not unaligned fields.
The projection macro supports both fallible and infallible index projections. These are described in detail inside the documentation.
--- rust/kernel/lib.rs | 3 + rust/kernel/ptr.rs | 3 + rust/kernel/ptr/projection.rs | 294 ++++++++++++++++++++++++++++++++++ scripts/Makefile.build | 4 +- 4 files changed, 303 insertions(+), 1 deletion(-) create mode 100644 rust/kernel/ptr/projection.rs
rust/kernel/lib.rs +3 -0
@@ -38,6 +38,9 @@#![feature(const_ptr_write)] #![feature(const_refs_to_cell)] // +// Stable since Rust 1.84.0. +#![feature(strict_provenance)] +// // Expected to become stable. #![feature(arbitrary_self_types)] //
rust/kernel/ptr.rs +3 -0
@@ -2,6 +2,9 @@//! Types and functions to work with pointers and addresses. +pub mod projection; +pub use crate ::project_pointeras project; +use core::mem::{ align_of, size_of,//
rust/kernel/ptr/projection.rs new file +294 -0
294 lines not on this page · raw message
scripts/Makefile.build +3 -1
@@ -310,16 +310,18 @@ $(obj)/%.lst: $(obj)/%.c FORCE # The features in this list are the ones allowed for non-`rust/` code. # +# - Stable since Rust 1.79.0: `feature(slice_ptr_len)`. # - Stable since Rust 1.81.0: `feature(lint_reasons)`. # - Stable since Rust 1.82.0: `feature(asm_const)`, # `feature(offset_of_nested)`, `feature(raw_ref_op)`. +# - Stable since Rust 1.84.0: `feature(strict_provenance)`. # - Stable since Rust 1.87.0: `feature(asm_goto)`. # - Expected to become stable: `feature(arbitrary_self_types)`. # - To be determined: `feature(used_with_arg)`. # # Please see https://github.com/Rust-for-Linux/linux/issues/2 for details on # the unstable features in use. -rust_allowed_features := asm_const,asm_goto,arbitrary_self_types,lint_reasons,offset_of_nested,raw_ref_op,used_with_arg +rust_allowed_features := asm_const,asm_goto,arbitrary_self_types,lint_reasons,offset_of_nested,raw_ref_op,slice_ptr_len,strict_provenance,used_with_arg # `--out-dir` is required to avoid temporaries being created by `rustc` in the # current working directory, which may be not accessible in the out-of-tree
Signature · 1 line
2.51.2
Re: [PATCH v4 2/3] rust: ptr: add projection infrastructure
Quoted 21 lines · Gary Guo
From: Gary Guo <[email protected]>
Add a generic infrastructure for performing field and index projections on raw pointers. This will form the basis of performing I/O projections.
Pointers manipulations are intentionally using the safe wrapping variants instead of the unsafe variants, as the latter requires pointers to be inside an allocation which is not necessarily true for I/O pointers.
This projection macro protects against rogue
Derefimplementation, which can causes the projected pointer to be outside the bounds of starting pointer. This is extremely unlikely and Rust has a lint to catch this, but is unsoundness regardless. The protection works by inducing type inference ambiguity whenDerefis implemented.This projection macro also stops projecting into unaligned fields (i.e. fields of
#[repr(packed)]structs), as misaligned pointers require special handling. This is implemented by attempting to create reference to projected field inside aif falseblock. Despite being unreachable, Rust still checks that they're not unaligned fields.
Quoted 4 lines
The projection macro supports both fallible and infallible index projections. These are described in detail inside the documentation.
Signed-off-by Gary Guo <[email protected]>
I have a naming concern with ProjectIndex::get, but that's only used from the module & macro and unlikely to be used from the outside. So renaming later should be easy.
Great work :)
Also found a typo below.
Quoted 8 lines
--- rust/kernel/lib.rs | 3 + rust/kernel/ptr.rs | 3 + rust/kernel/ptr/projection.rs | 294 ++++++++++++++++++++++++++++++++++ scripts/Makefile.build | 4 +- 4 files changed, 303 insertions(+), 1 deletion(-) create mode 100644 rust/kernel/ptr/projection.rs
rust/kernel/ptr/projection.rs line 142
Quoted 10 lines
rust/kernel/ptr/projection.rs new file +10
-0+/// A helper trait to perform field projection. +/// +/// This trait has a `DEREF` generic parameter so it can be implemented twice for types that +/// implement `Deref`. This will cause an ambiguity error and thus block `Deref` types being used +/// as base of projection, as they can inject unsoundness. Users therefore must not specify `DEREF` +/// and should always leave it to be inferred. +/// +/// # Safety +/// +/// `proj` may only invoke `f` with a valid allocation, as documentation described.
s/described/describes/
Cheers,
Benno
Quoted 15 lines
rust/kernel/ptr/projection.rs new file +15
-0+#[doc(hidden)] +pub unsafe trait ProjectField <const DEREF :bool > { +/// Project a pointer to a type to a pointer of a field. +/// +/// `f` may only be invoked with a valid allocation so it can safely obtain raw pointers to +/// fields using `&raw mut`. +/// +/// This is needed because `base` might not point to a valid allocation, while `&raw mut` +/// requires pointers to be in bounds of a valid allocation. +/// +/// # Safety +/// +/// `f` must return a pointer in bounds of the provided pointer. +unsafe fn proj <F >(base: *mut Self , f:impl FnOnce (*mut Self ) -> *mut F ) -> *mut F ; +}
Miguel Ojeda
maintainerRe: [PATCH v4 2/3] rust: ptr: add projection infrastructure
In reply to Gary GuoQuoted 3 lines · On Mon, 02 Mar 2026 16:42:35 +0000 Gary Guo <[email protected]> wrote:
Add a generic infrastructure for performing field and index projections on raw pointers. This will form the basis of performing I/O projections.
A few nits below for patch apply time.
rust/kernel/ptr/projection.rs line 24
Quoted 3 lines
rust/kernel/ptr/projection.rs new file +3
-0+/// A helper trait to perform index projection. +/// +/// This is similar to `core::slice::SliceIndex`, but operate on raw pointers safely and fallibly.
Intra-doc link.
Quoted 1 line
+/// The implementation of
indexandget(ifSomeis returned) must ensure that, if provided
Intra-doc link.
Quoted 1 line
+// Forward array impl to slice impl.
// empty line between this and the next one.
Quoted 1 line
+// SAFETY: safety requirement guaranteed by the forwarded impl.
Capitalization (several similar ones, plus a NOTE: one, a "vacuously" one and a "the provided" one).
Quoted 1 line
+/// implement
Deref. This will cause an ambiguity error and thus blockDereftypes being used
Intra-doc links.
rust/kernel/ptr/projection.rs line 161
Quoted 2 lines
rust/kernel/ptr/projection.rs new file +2
-0+// currently support that as we need to obtain a valid allocation that `&raw const` can operate on. +// SAFETY: `proj` invokes `f` with valid allocation.
Probably // empty line between them.
Quoted 1 line
+/// It is not allowed to project into types that implement custom
DereforIndex.
Intra-doc links.
Quoted 1 line
+///
OutOfBounderror is raised via?if the index is out of bounds.
Intra-doc link.
Review
Quoted 2 lines
(quoted diff) +2
-0+/// Field projections are performed with `.field_name`: +/// ```
// emtpy line between paragraphs and examples (several more below).
Quoted 1 line
+/// // This will fail the build.
"would" may be clearer, unless we add "... if uncommented.".
Perhaps even:
// The following invocation would fail the build.
And maybe similarly in the next one.
scripts/Makefile.build $(obj)/%.lst: $(obj)/%.c FORCE · line 317
Quoted 2 lines
scripts/Makefile.build +2
-0+# - Stable since Rust 1.79.0: `feature(slice_ptr_len)`. +# - Stable since Rust 1.84.0: `feature(strict_provenance)`.
Added both (plus feature(exposed_provenance), which Andreas asked about privately in our Zulip) to our usual lists:
https://github.com/Rust-for-Linux/linux/issues/1223
linking to the PRs and to this thread etc.
I hope that helps!
Cheers,
Miguel
PATCH v4 3/3 rust: dma: use pointer projection infra for `dma_{read,write}` macro
In reply to Gary GuoFrom: Gary Guo <[email protected]>
Current dma_read!, dma_write! macros also use a custom addr_of!()-based implementation for projecting pointers, which has soundness issue as it relies on absence of Deref implementation on types. It also has a soundness issue where it does not protect against unaligned fields (when #[repr(packed)] is used) so it can generate misaligned accesses.
This commit migrates them to use the general pointer projection infrastructure, which handles these cases correctly.
As part of migration, the macro is updated to have an improved surface syntax. The current macro have
dma_read!(a.b.c[d].e.f)
to mean a.b.c is a DMA coherent allocation and it should project into it with [d].e.f and do a read, which is confusing as it makes the indexing operator integral to the macro (so it will break if you have an array of CoherentAllocation, for example).
This also is problematic as we would like to generalize CoherentAllocation from just slices to arbitrary types.
Make the macro expects dma_read!(path.to.dma, .path.inside.dma) as the canonical syntax. The index operator is no longer special and is just one type of projection (in additional to field projection). Similarly, make dma_write!(path.to.dma, .path.inside.dma, value) become the canonical syntax for writing.
Another issue of the current macro is that it is always fallible. This makes sense with existing design of CoherentAllocation, but once we support fixed size arrays with CoherentAllocation, it is desirable to have the ability to perform infallible indexing as well, e.g. doing a [0] index of [Foo; 2] is okay and can be checked at build-time, so forcing falliblity is non-ideal. To capture this, the macro is changed to use [idx] as infallible projection and [idx]? as fallible index projection (those syntax are part of the general projection infra). A benefit of this is that while individual indexing operation may fail, the overall read/write operation is not fallible.
--- drivers/gpu/nova-core/gsp.rs | 14 ++-- drivers/gpu/nova-core/gsp/boot.rs | 2 +- drivers/gpu/nova-core/gsp/cmdq.rs | 10 ++- rust/kernel/dma.rs | 114 +++++++++++++----------------- samples/rust/rust_dma.rs | 30 ++++---- 5 files changed, 81 insertions(+), 89 deletions(-)
drivers/gpu/nova-core/gsp.rs +7 -7
@@ -143,14 +143,14 @@ pub(crate) fn new(pdev: &pci::Device<device::Bound>) -> impl PinInit<Self, Error// _kgspInitLibosLoggingStructures (allocates memory for buffers) // kgspSetupLibosInitArgs_IMPL (creates pLibosInitArgs[] array) dma_write! ( - libos[0 ] =LibosMemoryRegionInitArgument ::new ("LOGINIT" , &loginit.0 ) - )?; + libos, [0 ]?,LibosMemoryRegionInitArgument ::new ("LOGINIT" , &loginit.0 ) + );dma_write! ( - libos[1 ] =LibosMemoryRegionInitArgument ::new ("LOGINTR" , &logintr.0 ) - )?; -dma_write! (libos[2 ] =LibosMemoryRegionInitArgument ::new ("LOGRM" , &logrm.0 ))?; -dma_write! (rmargs[0 ].inner = fw::GspArgumentsCached ::new (cmdq))?; -dma_write! (libos[3 ] =LibosMemoryRegionInitArgument ::new ("RMARGS" , rmargs))?; + libos, [1 ]?,LibosMemoryRegionInitArgument ::new ("LOGINTR" , &logintr.0 ) + ); +dma_write! (libos, [2 ]?,LibosMemoryRegionInitArgument ::new ("LOGRM" , &logrm.0 )); +dma_write! (rmargs, [0 ]?.inner, fw::GspArgumentsCached ::new (cmdq)); +dma_write! (libos, [3 ]?,LibosMemoryRegionInitArgument ::new ("RMARGS" , rmargs)); }, })) })
drivers/gpu/nova-core/gsp/boot.rs +1 -1
@@ -157,7 +157,7 @@ pub(crate) fn boot(let wpr_meta =CoherentAllocation ::<GspFwWprMeta >::alloc_coherent (dev,1 ,GFP_KERNEL | __GFP_ZERO)?; -dma_write! (wpr_meta[0 ] =GspFwWprMeta ::new (&gsp_fw, &fb_layout))?; +dma_write! (wpr_meta, [0 ]?,GspFwWprMeta ::new (&gsp_fw, &fb_layout)); self.cmdq .send_command (bar, commands::SetSystemInfo ::new (pdev))?;
drivers/gpu/nova-core/gsp/cmdq.rs +7 -3
@@ -202,9 +202,13 @@ fn new(dev: &device::Device<device::Bound>) -> Result<Self> {let gsp_mem =CoherentAllocation ::<GspMem >::alloc_coherent (dev,1 ,GFP_KERNEL | __GFP_ZERO)?; -dma_write! (gsp_mem[0 ].ptes =PteArray ::new (gsp_mem.dma_handle ())?)?; -dma_write! (gsp_mem[0 ].cpuq.tx =MsgqTxHeader ::new (MSGQ_SIZE ,RX_HDR_OFF ,MSGQ_NUM_PAGES ))?; -dma_write! (gsp_mem[0 ].cpuq.rx =MsgqRxHeader ::new ())?; +dma_write! (gsp_mem, [0 ]?.ptes,PteArray ::new (gsp_mem.dma_handle ())?); +dma_write! ( + gsp_mem, + [0 ]?.cpuq.tx, +MsgqTxHeader ::new (MSGQ_SIZE ,RX_HDR_OFF ,MSGQ_NUM_PAGES ) + ); +dma_write! (gsp_mem, [0 ]?.cpuq.rx,MsgqRxHeader ::new ());Ok (Self (gsp_mem)) }
rust/kernel/dma.rs +50 -64
158 lines not on this page · raw message
samples/rust/rust_dma.rs +16 -14
@@ -68,7 +68,7 @@ fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> impl PinInit<Self, ECoherentAllocation ::alloc_coherent (pdev.as_ref (),TEST_VALUES .len (),GFP_KERNEL )?;for (i, value)in TEST_VALUES .into_iter ().enumerate () { - kernel::dma_write!(ca[i] =MyStruct ::new (value.0 , value.1 ))?; + kernel::dma_write!(ca, [i]?,MyStruct ::new (value.0 , value.1 )); }let size =4 * page::PAGE_SIZE ;
@@ -85,24 +85,26 @@ fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> impl PinInit<Self, E } } +impl DmaSampleDriver { +fn check_dma (&self) ->Result { +for (i, value)in TEST_VALUES .into_iter ().enumerate () { +let val0 = kernel::dma_read!(self.ca, [i]?.h); +let val1 = kernel::dma_read!(self.ca, [i]?.b); + +assert_eq! (val0, value.0 ); +assert_eq! (val1, value.1 ); + } + +Ok (()) + } +} +#[pinned_drop] impl PinnedDrop for DmaSampleDriver {fn drop (self:Pin <&mut Self >) {dev_info! (self.pdev,"Unload DMA test driver.\n" ); -for (i, value)in TEST_VALUES .into_iter ().enumerate () { -let val0 = kernel::dma_read!(self.ca[i].h); -let val1 = kernel::dma_read!(self.ca[i].b); -assert! (val0.is_ok ()); -assert! (val1.is_ok ()); - -if let Ok (val0) = val0 { -assert_eq! (val0, value.0 ); - } -if let Ok (val1) = val1 { -assert_eq! (val1, value.1 ); - } - } +assert! (self.check_dma ().is_ok ());for (i, entry)in self.sgt.iter ().enumerate () {dev_info! (
Signature · 1 line
2.51.2
Quoted 15 lines · Gary Guo
From: Gary Guo <[email protected]>
This adds a general pointer projection infrastructure which is intended to serve as the basis for generic I/O projections. The idea is that we will have a unified way of reading/writing MMIO or DMA allocation, creating typed subviews into them, and able to read/write subfields safely.
This is the first step towards that direction, where an infra for projecting arbitrary pointers are added. This takes care to not assume pointers are part of a valid allocation, so it can be used to project I/O pointers, too.
dma_read!anddma_write!is converted to use this infra, as they currently have soundness issues [1] and users have already encountered limitation of it [2].
Quoted 2 lines
As discussed in a previous version, Danilo wants to pick this for the next -rc or so:
I am also taking a few fixes via Rust, so that is another alternative (or even as a feature, to be honest).
For some reason I didn't receive yet all the patches (and I also noticed a late email from Gary to my account in another thread), but I noticed a few nits for patch apply time -- I replied in the #2 patch.
Thanks!
Cheers,
Miguel
On Mon Mar 2, 2026 at 5:42 PM CET, Gary Guo wrote:
Applied to drm-rust-fixes, thanks!
Quoted 2 lines
Gary Guo (3):
rust: ptr: addKnownSizetrait to support DST size info extraction
[ Fix wording in doc-comment. - Danilo ]
Quoted 1 line
rust: ptr: add projection infrastructure
[ * Add intra-doc links where possible,
* Fix typos and slightly improve wording, e.g. "as documentation describes" -> "as the documentation of [Self::proj] describes",
* Add an empty line between regular and safety comments, before examples, and between logically independent comments,
* Capitalize various safety comments.
- Danilo ]
Quoted 1 line
rust: dma: use pointer projection infra for
dma_{read,write}macro
[ Capitalize safety comments; slightly improve wording in doc-comments.
- Danilo ]