From: Greg Kroah-Hartman Date: Mon, 16 Mar 2026 14:00:34 +0000 (+0100) Subject: drop rust patch X-Git-Tag: v6.18.19~86 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2bc315ef9e053fa4bfb1c3c6a3fc10b6229e0bf3;p=thirdparty%2Fkernel%2Fstable-queue.git drop rust patch --- diff --git a/queue-6.19/gpu-nova-core-align-libosmemoryregioninitargument-si.patch b/queue-6.19/gpu-nova-core-align-libosmemoryregioninitargument-si.patch deleted file mode 100644 index bc7958e524..0000000000 --- a/queue-6.19/gpu-nova-core-align-libosmemoryregioninitargument-si.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 95efa20afcc0288cad7a14ea80136a6771b3b65a Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 22 Jan 2026 16:28:46 -0600 -Subject: gpu: nova-core: align LibosMemoryRegionInitArgument size to page size - -From: Alexandre Courbot - -[ Upstream commit 58d26d42818c0f8c9b334cc7cf318b43046e675f ] - -On Turing and GA100 (i.e. the versions that use Libos v2), GSP-RM insists -that the 'size' parameter of the LibosMemoryRegionInitArgument struct be -aligned to 4KB. The logging buffers are already aligned to that size, so -only the GSP_ARGUMENTS_CACHED struct needs to be adjusted. Make that -adjustment by adding padding to the end of the struct. - -Signed-off-by: Timur Tabi -Reviewed-by: Gary Guo -Acked-by: Danilo Krummrich -Link: https://patch.msgid.link/20260122222848.2555890-12-ttabi@nvidia.com -[acourbot@nvidia.com: GspArgumentsAligned -> GspArgumentsPadded] -Signed-off-by: Alexandre Courbot -Stable-dep-of: 4da879a0d3fd ("rust: dma: use pointer projection infra for `dma_{read,write}` macro") -Signed-off-by: Sasha Levin ---- - drivers/gpu/nova-core/gsp.rs | 8 ++++---- - drivers/gpu/nova-core/gsp/fw.rs | 14 +++++++++++++- - 2 files changed, 17 insertions(+), 5 deletions(-) - -diff --git a/drivers/gpu/nova-core/gsp.rs b/drivers/gpu/nova-core/gsp.rs -index 766fd99053589..174feaca0a6b9 100644 ---- a/drivers/gpu/nova-core/gsp.rs -+++ b/drivers/gpu/nova-core/gsp.rs -@@ -27,7 +27,7 @@ pub(crate) use fw::{ - use crate::{ - gsp::cmdq::Cmdq, - gsp::fw::{ -- GspArgumentsCached, -+ GspArgumentsPadded, - LibosMemoryRegionInitArgument, // - }, - num, -@@ -114,7 +114,7 @@ pub(crate) struct Gsp { - /// Command queue. - pub(crate) cmdq: Cmdq, - /// RM arguments. -- rmargs: CoherentAllocation, -+ rmargs: CoherentAllocation, - } - - impl Gsp { -@@ -133,7 +133,7 @@ impl Gsp { - logintr: LogBuffer::new(dev)?, - logrm: LogBuffer::new(dev)?, - cmdq: Cmdq::new(dev)?, -- rmargs: CoherentAllocation::::alloc_coherent( -+ rmargs: CoherentAllocation::::alloc_coherent( - dev, - 1, - GFP_KERNEL | __GFP_ZERO, -@@ -149,7 +149,7 @@ impl Gsp { - libos[1] = LibosMemoryRegionInitArgument::new("LOGINTR", &logintr.0) - )?; - dma_write!(libos[2] = LibosMemoryRegionInitArgument::new("LOGRM", &logrm.0))?; -- dma_write!(rmargs[0] = fw::GspArgumentsCached::new(cmdq))?; -+ dma_write!(rmargs[0].inner = fw::GspArgumentsCached::new(cmdq))?; - dma_write!(libos[3] = LibosMemoryRegionInitArgument::new("RMARGS", rmargs))?; - }, - })) -diff --git a/drivers/gpu/nova-core/gsp/fw.rs b/drivers/gpu/nova-core/gsp/fw.rs -index caeb0d251fe5f..83ff91614e36d 100644 ---- a/drivers/gpu/nova-core/gsp/fw.rs -+++ b/drivers/gpu/nova-core/gsp/fw.rs -@@ -904,9 +904,21 @@ impl GspArgumentsCached { - // SAFETY: Padding is explicit and will not contain uninitialized data. - unsafe impl AsBytes for GspArgumentsCached {} - -+/// On Turing and GA100, the entries in the `LibosMemoryRegionInitArgument` -+/// must all be a multiple of GSP_PAGE_SIZE in size, so add padding to force it -+/// to that size. -+#[repr(C)] -+pub(crate) struct GspArgumentsPadded { -+ pub(crate) inner: GspArgumentsCached, -+ _padding: [u8; GSP_PAGE_SIZE - core::mem::size_of::()], -+} -+ -+// SAFETY: Padding is explicit and will not contain uninitialized data. -+unsafe impl AsBytes for GspArgumentsPadded {} -+ - // SAFETY: This struct only contains integer types for which all bit patterns - // are valid. --unsafe impl FromBytes for GspArgumentsCached {} -+unsafe impl FromBytes for GspArgumentsPadded {} - - /// Init arguments for the message queue. - #[repr(transparent)] --- -2.51.0 - diff --git a/queue-6.19/gpu-nova-core-fix-stack-overflow-in-gsp-memory-alloc.patch b/queue-6.19/gpu-nova-core-fix-stack-overflow-in-gsp-memory-alloc.patch deleted file mode 100644 index d2e1e79df2..0000000000 --- a/queue-6.19/gpu-nova-core-fix-stack-overflow-in-gsp-memory-alloc.patch +++ /dev/null @@ -1,132 +0,0 @@ -From ef4e635e9a5f24fa6432649c59af405de10b0692 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 9 Mar 2026 12:34:21 -0400 -Subject: gpu: nova-core: fix stack overflow in GSP memory allocation - -From: Tim Kovalenko - -[ Upstream commit c7940c8bf215b9dc6211781c77ce80e76982a723 ] - -The `Cmdq::new` function was allocating a `PteArray` struct on the stack -and was causing a stack overflow with 8216 bytes. - -Modify the `PteArray` to calculate and write the Page Table Entries -directly into the coherent DMA buffer one-by-one. This reduces the stack -usage quite a lot. - -Reported-by: Gary Guo -Closes: https://rust-for-linux.zulipchat.com/#narrow/channel/509436-Nova/topic/.60Cmdq.3A.3Anew.60.20uses.20excessive.20stack.20size/near/570375549 -Link: https://lore.kernel.org/rust-for-linux/CANiq72mAQxbRJZDnik3Qmd4phvFwPA01O2jwaaXRh_T+2=L-qA@mail.gmail.com/ -Fixes: f38b4f105cfc ("gpu: nova-core: Create initial Gsp") -Acked-by: Alexandre Courbot -Signed-off-by: Tim Kovalenko -Link: https://patch.msgid.link/20260309-drm-rust-next-v4-4-4ef485b19a4c@proton.me -[ * Use PteArray::entry() in LogBuffer::new(), - * Add TODO comment to use IoView projections once available, - * Add PTE_ARRAY_SIZE constant to avoid duplication. - - - Danilo ] -Signed-off-by: Danilo Krummrich -Signed-off-by: Sasha Levin ---- - drivers/gpu/nova-core/gsp.rs | 32 ++++++++++++++++--------------- - drivers/gpu/nova-core/gsp/cmdq.rs | 14 ++++++++++++-- - 2 files changed, 29 insertions(+), 17 deletions(-) - -diff --git a/drivers/gpu/nova-core/gsp.rs b/drivers/gpu/nova-core/gsp.rs -index 25cd48514c777..c69adaa92bbe7 100644 ---- a/drivers/gpu/nova-core/gsp.rs -+++ b/drivers/gpu/nova-core/gsp.rs -@@ -47,16 +47,12 @@ struct PteArray([u64; NUM_ENTRIES]); - unsafe impl AsBytes for PteArray {} - - impl PteArray { -- /// Creates a new page table array mapping `NUM_PAGES` GSP pages starting at address `start`. -- fn new(start: DmaAddress) -> Result { -- let mut ptes = [0u64; NUM_PAGES]; -- for (i, pte) in ptes.iter_mut().enumerate() { -- *pte = start -- .checked_add(num::usize_as_u64(i) << GSP_PAGE_SHIFT) -- .ok_or(EOVERFLOW)?; -- } -- -- Ok(Self(ptes)) -+ /// Returns the page table entry for `index`, for a mapping starting at `start`. -+ // TODO: Replace with `IoView` projection once available. -+ fn entry(start: DmaAddress, index: usize) -> Result { -+ start -+ .checked_add(num::usize_as_u64(index) << GSP_PAGE_SHIFT) -+ .ok_or(EOVERFLOW) - } - } - -@@ -86,16 +82,22 @@ impl LogBuffer { - NUM_PAGES * GSP_PAGE_SIZE, - GFP_KERNEL | __GFP_ZERO, - )?); -- let ptes = PteArray::::new(obj.0.dma_handle())?; -+ -+ let start_addr = obj.0.dma_handle(); - - // SAFETY: `obj` has just been created and we are its sole user. -- unsafe { -- // Copy the self-mapping PTE at the expected location. -+ let pte_region = unsafe { - obj.0 -- .as_slice_mut(size_of::(), size_of_val(&ptes))? -- .copy_from_slice(ptes.as_bytes()) -+ .as_slice_mut(size_of::(), NUM_PAGES * size_of::())? - }; - -+ // Write values one by one to avoid an on-stack instance of `PteArray`. -+ for (i, chunk) in pte_region.chunks_exact_mut(size_of::()).enumerate() { -+ let pte_value = PteArray::<0>::entry(start_addr, i)?; -+ -+ chunk.copy_from_slice(&pte_value.to_ne_bytes()); -+ } -+ - Ok(obj) - } - } -diff --git a/drivers/gpu/nova-core/gsp/cmdq.rs b/drivers/gpu/nova-core/gsp/cmdq.rs -index 1cdd1ccfe5702..e94d63f631ceb 100644 ---- a/drivers/gpu/nova-core/gsp/cmdq.rs -+++ b/drivers/gpu/nova-core/gsp/cmdq.rs -@@ -159,7 +159,7 @@ struct Msgq { - #[repr(C)] - struct GspMem { - /// Self-mapping page table entries. -- ptes: PteArray<{ GSP_PAGE_SIZE / size_of::() }>, -+ ptes: PteArray<{ Self::PTE_ARRAY_SIZE }>, - /// CPU queue: the driver writes commands here, and the GSP reads them. It also contains the - /// write and read pointers that the CPU updates. - /// -@@ -172,6 +172,10 @@ struct GspMem { - gspq: Msgq, - } - -+impl GspMem { -+ const PTE_ARRAY_SIZE: usize = GSP_PAGE_SIZE / size_of::(); -+} -+ - // SAFETY: These structs don't meet the no-padding requirements of AsBytes but - // that is not a problem because they are not used outside the kernel. - unsafe impl AsBytes for GspMem {} -@@ -201,7 +205,13 @@ impl DmaGspMem { - - let gsp_mem = - CoherentAllocation::::alloc_coherent(dev, 1, GFP_KERNEL | __GFP_ZERO)?; -- dma_write!(gsp_mem, [0]?.ptes, PteArray::new(gsp_mem.dma_handle())?); -+ -+ let start = gsp_mem.dma_handle(); -+ // Write values one by one to avoid an on-stack instance of `PteArray`. -+ for i in 0..GspMem::PTE_ARRAY_SIZE { -+ dma_write!(gsp_mem, [0]?.ptes.0[i], PteArray::<0>::entry(start, i)?); -+ } -+ - dma_write!( - gsp_mem, - [0]?.cpuq.tx, --- -2.51.0 - diff --git a/queue-6.19/gpu-nova-core-gsp-fix-ub-in-dmagspmem-pointer-access.patch b/queue-6.19/gpu-nova-core-gsp-fix-ub-in-dmagspmem-pointer-access.patch deleted file mode 100644 index 215b47e593..0000000000 --- a/queue-6.19/gpu-nova-core-gsp-fix-ub-in-dmagspmem-pointer-access.patch +++ /dev/null @@ -1,316 +0,0 @@ -From af2e195cfb4960e6070fa7f22a78be22174b6321 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 9 Mar 2026 23:53:24 +0100 -Subject: gpu: nova-core: gsp: fix UB in DmaGspMem pointer accessors - -From: Danilo Krummrich - -[ Upstream commit 0073a17b466684413ac87cf8ff6c19560db44e7a ] - -The DmaGspMem pointer accessor methods (gsp_write_ptr, gsp_read_ptr, -cpu_read_ptr, cpu_write_ptr, advance_cpu_read_ptr, -advance_cpu_write_ptr) dereference a raw pointer to DMA memory, creating -an intermediate reference before calling volatile read/write methods. - -This is undefined behavior since DMA memory can be concurrently modified -by the device. - -Fix this by moving the implementations into a gsp_mem module in fw.rs -that uses the dma_read!() / dma_write!() macros, making the original -methods on DmaGspMem thin forwarding wrappers. - -An alternative approach would have been to wrap the shared memory in -Opaque, but that would have required even more unsafe code. - -Since the gsp_mem module lives in fw.rs (to access firmware-specific -binding field names), GspMem, Msgq and their relevant fields are -temporarily widened to pub(super). This will be reverted once IoView -projections are available. - -Cc: Gary Guo -Closes: https://lore.kernel.org/nouveau/DGUT14ILG35P.1UMNRKU93JUM1@kernel.org/ -Fixes: 75f6b1de8133 ("gpu: nova-core: gsp: Add GSP command queue bindings and handling") -Reviewed-by: Alexandre Courbot -Link: https://patch.msgid.link/20260309225408.27714-1-dakr@kernel.org -[ Use pub(super) where possible; replace bitwise-and with modulo - operator analogous to [1]. - Danilo ] -Link: https://lore.kernel.org/all/20260129-nova-core-cmdq1-v3-1-2ede85493a27@nvidia.com/ [1] -Signed-off-by: Danilo Krummrich -Signed-off-by: Sasha Levin ---- - drivers/gpu/nova-core/gsp/cmdq.rs | 71 +++++---------------- - drivers/gpu/nova-core/gsp/fw.rs | 101 ++++++++++++++++++++---------- - 2 files changed, 84 insertions(+), 88 deletions(-) - -diff --git a/drivers/gpu/nova-core/gsp/cmdq.rs b/drivers/gpu/nova-core/gsp/cmdq.rs -index e94d63f631ceb..db53020a495eb 100644 ---- a/drivers/gpu/nova-core/gsp/cmdq.rs -+++ b/drivers/gpu/nova-core/gsp/cmdq.rs -@@ -2,11 +2,7 @@ - - use core::{ - cmp, -- mem, -- sync::atomic::{ -- fence, -- Ordering, // -- }, // -+ mem, // - }; - - use kernel::{ -@@ -146,30 +142,32 @@ static_assert!(align_of::() == GSP_PAGE_SIZE); - #[repr(C)] - // There is no struct defined for this in the open-gpu-kernel-source headers. - // Instead it is defined by code in `GspMsgQueuesInit()`. --struct Msgq { -+// TODO: Revert to private once `IoView` projections replace the `gsp_mem` module. -+pub(super) struct Msgq { - /// Header for sending messages, including the write pointer. -- tx: MsgqTxHeader, -+ pub(super) tx: MsgqTxHeader, - /// Header for receiving messages, including the read pointer. -- rx: MsgqRxHeader, -+ pub(super) rx: MsgqRxHeader, - /// The message queue proper. - msgq: MsgqData, - } - - /// Structure shared between the driver and the GSP and containing the command and message queues. - #[repr(C)] --struct GspMem { -+// TODO: Revert to private once `IoView` projections replace the `gsp_mem` module. -+pub(super) struct GspMem { - /// Self-mapping page table entries. - ptes: PteArray<{ Self::PTE_ARRAY_SIZE }>, - /// CPU queue: the driver writes commands here, and the GSP reads them. It also contains the - /// write and read pointers that the CPU updates. - /// - /// This member is read-only for the GSP. -- cpuq: Msgq, -+ pub(super) cpuq: Msgq, - /// GSP queue: the GSP writes messages here, and the driver reads them. It also contains the - /// write and read pointers that the GSP updates. - /// - /// This member is read-only for the driver. -- gspq: Msgq, -+ pub(super) gspq: Msgq, - } - - impl GspMem { -@@ -331,12 +329,7 @@ impl DmaGspMem { - // - // - The returned value is between `0` and `MSGQ_NUM_PAGES`. - fn gsp_write_ptr(&self) -> u32 { -- let gsp_mem = self.0.start_ptr(); -- -- // SAFETY: -- // - The 'CoherentAllocation' contains at least one object. -- // - By the invariants of `CoherentAllocation` the pointer is valid. -- (unsafe { (*gsp_mem).gspq.tx.write_ptr() } % MSGQ_NUM_PAGES) -+ super::fw::gsp_mem::gsp_write_ptr(&self.0) - } - - // Returns the index of the memory page the GSP will read the next command from. -@@ -345,12 +338,7 @@ impl DmaGspMem { - // - // - The returned value is between `0` and `MSGQ_NUM_PAGES`. - fn gsp_read_ptr(&self) -> u32 { -- let gsp_mem = self.0.start_ptr(); -- -- // SAFETY: -- // - The 'CoherentAllocation' contains at least one object. -- // - By the invariants of `CoherentAllocation` the pointer is valid. -- (unsafe { (*gsp_mem).gspq.rx.read_ptr() } % MSGQ_NUM_PAGES) -+ super::fw::gsp_mem::gsp_read_ptr(&self.0) - } - - // Returns the index of the memory page the CPU can read the next message from. -@@ -359,27 +347,12 @@ impl DmaGspMem { - // - // - The returned value is between `0` and `MSGQ_NUM_PAGES`. - fn cpu_read_ptr(&self) -> u32 { -- let gsp_mem = self.0.start_ptr(); -- -- // SAFETY: -- // - The ['CoherentAllocation'] contains at least one object. -- // - By the invariants of CoherentAllocation the pointer is valid. -- (unsafe { (*gsp_mem).cpuq.rx.read_ptr() } % MSGQ_NUM_PAGES) -+ super::fw::gsp_mem::cpu_read_ptr(&self.0) - } - - // Informs the GSP that it can send `elem_count` new pages into the message queue. - fn advance_cpu_read_ptr(&mut self, elem_count: u32) { -- let rptr = self.cpu_read_ptr().wrapping_add(elem_count) % MSGQ_NUM_PAGES; -- -- // Ensure read pointer is properly ordered. -- fence(Ordering::SeqCst); -- -- let gsp_mem = self.0.start_ptr_mut(); -- -- // SAFETY: -- // - The 'CoherentAllocation' contains at least one object. -- // - By the invariants of `CoherentAllocation` the pointer is valid. -- unsafe { (*gsp_mem).cpuq.rx.set_read_ptr(rptr) }; -+ super::fw::gsp_mem::advance_cpu_read_ptr(&self.0, elem_count) - } - - // Returns the index of the memory page the CPU can write the next command to. -@@ -388,26 +361,12 @@ impl DmaGspMem { - // - // - The returned value is between `0` and `MSGQ_NUM_PAGES`. - fn cpu_write_ptr(&self) -> u32 { -- let gsp_mem = self.0.start_ptr(); -- -- // SAFETY: -- // - The 'CoherentAllocation' contains at least one object. -- // - By the invariants of `CoherentAllocation` the pointer is valid. -- (unsafe { (*gsp_mem).cpuq.tx.write_ptr() } % MSGQ_NUM_PAGES) -+ super::fw::gsp_mem::cpu_write_ptr(&self.0) - } - - // Informs the GSP that it can process `elem_count` new pages from the command queue. - fn advance_cpu_write_ptr(&mut self, elem_count: u32) { -- let wptr = self.cpu_write_ptr().wrapping_add(elem_count) & MSGQ_NUM_PAGES; -- let gsp_mem = self.0.start_ptr_mut(); -- -- // SAFETY: -- // - The 'CoherentAllocation' contains at least one object. -- // - By the invariants of `CoherentAllocation` the pointer is valid. -- unsafe { (*gsp_mem).cpuq.tx.set_write_ptr(wptr) }; -- -- // Ensure all command data is visible before triggering the GSP read. -- fence(Ordering::SeqCst); -+ super::fw::gsp_mem::advance_cpu_write_ptr(&self.0, elem_count) - } - } - -diff --git a/drivers/gpu/nova-core/gsp/fw.rs b/drivers/gpu/nova-core/gsp/fw.rs -index 83ff91614e36d..040b30ec3089b 100644 ---- a/drivers/gpu/nova-core/gsp/fw.rs -+++ b/drivers/gpu/nova-core/gsp/fw.rs -@@ -40,6 +40,75 @@ use crate::{ - }, - }; - -+// TODO: Replace with `IoView` projections once available; the `unwrap()` calls go away once we -+// switch to the new `dma::Coherent` API. -+pub(super) mod gsp_mem { -+ use core::sync::atomic::{ -+ fence, -+ Ordering, // -+ }; -+ -+ use kernel::{ -+ dma::CoherentAllocation, -+ dma_read, -+ dma_write, -+ prelude::*, // -+ }; -+ -+ use crate::gsp::cmdq::{ -+ GspMem, -+ MSGQ_NUM_PAGES, // -+ }; -+ -+ pub(in crate::gsp) fn gsp_write_ptr(qs: &CoherentAllocation) -> u32 { -+ // PANIC: A `dma::CoherentAllocation` always contains at least one element. -+ || -> Result { Ok(dma_read!(qs, [0]?.gspq.tx.0.writePtr) % MSGQ_NUM_PAGES) }().unwrap() -+ } -+ -+ pub(in crate::gsp) fn gsp_read_ptr(qs: &CoherentAllocation) -> u32 { -+ // PANIC: A `dma::CoherentAllocation` always contains at least one element. -+ || -> Result { Ok(dma_read!(qs, [0]?.gspq.rx.0.readPtr) % MSGQ_NUM_PAGES) }().unwrap() -+ } -+ -+ pub(in crate::gsp) fn cpu_read_ptr(qs: &CoherentAllocation) -> u32 { -+ // PANIC: A `dma::CoherentAllocation` always contains at least one element. -+ || -> Result { Ok(dma_read!(qs, [0]?.cpuq.rx.0.readPtr) % MSGQ_NUM_PAGES) }().unwrap() -+ } -+ -+ pub(in crate::gsp) fn advance_cpu_read_ptr(qs: &CoherentAllocation, count: u32) { -+ let rptr = cpu_read_ptr(qs).wrapping_add(count) % MSGQ_NUM_PAGES; -+ -+ // Ensure read pointer is properly ordered. -+ fence(Ordering::SeqCst); -+ -+ // PANIC: A `dma::CoherentAllocation` always contains at least one element. -+ || -> Result { -+ dma_write!(qs, [0]?.cpuq.rx.0.readPtr, rptr); -+ Ok(()) -+ }() -+ .unwrap() -+ } -+ -+ pub(in crate::gsp) fn cpu_write_ptr(qs: &CoherentAllocation) -> u32 { -+ // PANIC: A `dma::CoherentAllocation` always contains at least one element. -+ || -> Result { Ok(dma_read!(qs, [0]?.cpuq.tx.0.writePtr) % MSGQ_NUM_PAGES) }().unwrap() -+ } -+ -+ pub(in crate::gsp) fn advance_cpu_write_ptr(qs: &CoherentAllocation, count: u32) { -+ let wptr = cpu_write_ptr(qs).wrapping_add(count) % MSGQ_NUM_PAGES; -+ -+ // PANIC: A `dma::CoherentAllocation` always contains at least one element. -+ || -> Result { -+ dma_write!(qs, [0]?.cpuq.tx.0.writePtr, wptr); -+ Ok(()) -+ }() -+ .unwrap(); -+ -+ // Ensure all command data is visible before triggering the GSP read. -+ fence(Ordering::SeqCst); -+ } -+} -+ - /// Empty type to group methods related to heap parameters for running the GSP firmware. - enum GspFwHeapParams {} - -@@ -708,22 +777,6 @@ impl MsgqTxHeader { - entryOff: num::usize_into_u32::(), - }) - } -- -- /// Returns the value of the write pointer for this queue. -- pub(crate) fn write_ptr(&self) -> u32 { -- let ptr = core::ptr::from_ref(&self.0.writePtr); -- -- // SAFETY: `ptr` is a valid pointer to a `u32`. -- unsafe { ptr.read_volatile() } -- } -- -- /// Sets the value of the write pointer for this queue. -- pub(crate) fn set_write_ptr(&mut self, val: u32) { -- let ptr = core::ptr::from_mut(&mut self.0.writePtr); -- -- // SAFETY: `ptr` is a valid pointer to a `u32`. -- unsafe { ptr.write_volatile(val) } -- } - } - - // SAFETY: Padding is explicit and does not contain uninitialized data. -@@ -739,22 +792,6 @@ impl MsgqRxHeader { - pub(crate) fn new() -> Self { - Self(Default::default()) - } -- -- /// Returns the value of the read pointer for this queue. -- pub(crate) fn read_ptr(&self) -> u32 { -- let ptr = core::ptr::from_ref(&self.0.readPtr); -- -- // SAFETY: `ptr` is a valid pointer to a `u32`. -- unsafe { ptr.read_volatile() } -- } -- -- /// Sets the value of the read pointer for this queue. -- pub(crate) fn set_read_ptr(&mut self, val: u32) { -- let ptr = core::ptr::from_mut(&mut self.0.readPtr); -- -- // SAFETY: `ptr` is a valid pointer to a `u32`. -- unsafe { ptr.write_volatile(val) } -- } - } - - // SAFETY: Padding is explicit and does not contain uninitialized data. --- -2.51.0 - diff --git a/queue-6.19/gpu-nova-core-gsp-get-rid-of-redundant-result-in-gsp.patch b/queue-6.19/gpu-nova-core-gsp-get-rid-of-redundant-result-in-gsp.patch deleted file mode 100644 index f1433c394f..0000000000 --- a/queue-6.19/gpu-nova-core-gsp-get-rid-of-redundant-result-in-gsp.patch +++ /dev/null @@ -1,130 +0,0 @@ -From 1c6058aaf9de44791f6355774b03c17778aa3b26 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 18 Dec 2025 16:50:50 +0100 -Subject: gpu: nova-core: gsp: get rid of redundant Result in Gsp::new() - -From: Danilo Krummrich - -[ Upstream commit 032a6772d663a26005f4c17be992a716457f095b ] - -In Gsp::new(), utilize pin_init_scope() to get rid of the Result in the -returned - - Result> - -which is unnecessarily redundant. - -Reviewed-by: Joel Fernandes -Link: https://patch.msgid.link/20251218155239.25243-4-dakr@kernel.org -Signed-off-by: Danilo Krummrich -Stable-dep-of: 4da879a0d3fd ("rust: dma: use pointer projection infra for `dma_{read,write}` macro") -Signed-off-by: Sasha Levin ---- - drivers/gpu/nova-core/gpu.rs | 2 +- - drivers/gpu/nova-core/gsp.rs | 78 ++++++++++++++++++------------------ - 2 files changed, 41 insertions(+), 39 deletions(-) - -diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs -index 629c9d2dc994c..50d76092fbdd7 100644 ---- a/drivers/gpu/nova-core/gpu.rs -+++ b/drivers/gpu/nova-core/gpu.rs -@@ -281,7 +281,7 @@ impl Gpu { - - sec2_falcon: Falcon::new(pdev.as_ref(), spec.chipset)?, - -- gsp <- Gsp::new(pdev)?, -+ gsp <- Gsp::new(pdev), - - _: { gsp.boot(pdev, bar, spec.chipset, gsp_falcon, sec2_falcon)? }, - -diff --git a/drivers/gpu/nova-core/gsp.rs b/drivers/gpu/nova-core/gsp.rs -index fb6f74797178e..8bc86e1bcac52 100644 ---- a/drivers/gpu/nova-core/gsp.rs -+++ b/drivers/gpu/nova-core/gsp.rs -@@ -119,43 +119,45 @@ pub(crate) struct Gsp { - - impl Gsp { - // Creates an in-place initializer for a `Gsp` manager for `pdev`. -- pub(crate) fn new(pdev: &pci::Device) -> Result> { -- let dev = pdev.as_ref(); -- let libos = CoherentAllocation::::alloc_coherent( -- dev, -- GSP_PAGE_SIZE / size_of::(), -- GFP_KERNEL | __GFP_ZERO, -- )?; -- -- // Initialise the logging structures. The OpenRM equivalents are in: -- // _kgspInitLibosLoggingStructures (allocates memory for buffers) -- // kgspSetupLibosInitArgs_IMPL (creates pLibosInitArgs[] array) -- let loginit = LogBuffer::new(dev)?; -- dma_write!(libos[0] = LibosMemoryRegionInitArgument::new("LOGINIT", &loginit.0))?; -- -- let logintr = LogBuffer::new(dev)?; -- dma_write!(libos[1] = LibosMemoryRegionInitArgument::new("LOGINTR", &logintr.0))?; -- -- let logrm = LogBuffer::new(dev)?; -- dma_write!(libos[2] = LibosMemoryRegionInitArgument::new("LOGRM", &logrm.0))?; -- -- let cmdq = Cmdq::new(dev)?; -- -- let rmargs = CoherentAllocation::::alloc_coherent( -- dev, -- 1, -- GFP_KERNEL | __GFP_ZERO, -- )?; -- dma_write!(rmargs[0] = fw::GspArgumentsCached::new(&cmdq))?; -- dma_write!(libos[3] = LibosMemoryRegionInitArgument::new("RMARGS", &rmargs))?; -- -- Ok(try_pin_init!(Self { -- libos, -- loginit, -- logintr, -- logrm, -- rmargs, -- cmdq, -- })) -+ pub(crate) fn new(pdev: &pci::Device) -> impl PinInit + '_ { -+ pin_init::pin_init_scope(move || { -+ let dev = pdev.as_ref(); -+ let libos = CoherentAllocation::::alloc_coherent( -+ dev, -+ GSP_PAGE_SIZE / size_of::(), -+ GFP_KERNEL | __GFP_ZERO, -+ )?; -+ -+ // Initialise the logging structures. The OpenRM equivalents are in: -+ // _kgspInitLibosLoggingStructures (allocates memory for buffers) -+ // kgspSetupLibosInitArgs_IMPL (creates pLibosInitArgs[] array) -+ let loginit = LogBuffer::new(dev)?; -+ dma_write!(libos[0] = LibosMemoryRegionInitArgument::new("LOGINIT", &loginit.0))?; -+ -+ let logintr = LogBuffer::new(dev)?; -+ dma_write!(libos[1] = LibosMemoryRegionInitArgument::new("LOGINTR", &logintr.0))?; -+ -+ let logrm = LogBuffer::new(dev)?; -+ dma_write!(libos[2] = LibosMemoryRegionInitArgument::new("LOGRM", &logrm.0))?; -+ -+ let cmdq = Cmdq::new(dev)?; -+ -+ let rmargs = CoherentAllocation::::alloc_coherent( -+ dev, -+ 1, -+ GFP_KERNEL | __GFP_ZERO, -+ )?; -+ dma_write!(rmargs[0] = fw::GspArgumentsCached::new(&cmdq))?; -+ dma_write!(libos[3] = LibosMemoryRegionInitArgument::new("RMARGS", &rmargs))?; -+ -+ Ok(try_pin_init!(Self { -+ libos, -+ loginit, -+ logintr, -+ logrm, -+ rmargs, -+ cmdq, -+ })) -+ }) - } - } --- -2.51.0 - diff --git a/queue-6.19/gpu-nova-core-gsp-move-appropriate-code-into-pin-ini.patch b/queue-6.19/gpu-nova-core-gsp-move-appropriate-code-into-pin-ini.patch deleted file mode 100644 index dd06323ff6..0000000000 --- a/queue-6.19/gpu-nova-core-gsp-move-appropriate-code-into-pin-ini.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 0ebe84e0db1ec49a9d195c200101de823c6c9a14 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 18 Dec 2025 16:50:51 +0100 -Subject: gpu: nova-core: gsp: move appropriate code into pin initializer - -From: Danilo Krummrich - -[ Upstream commit 7acc70476f14661149774ab88d3fe23d83ba4249 ] - -Relocate the code that technically fits in the pin initializer into the -initializer itself. - -While, thanks to pin_init_scope(), it is also possible to keep it as is, -moving appropriate code into the initializer has the advantage that it -structures the dependencies of fields naturally. - -For instance, intermediate data that is only needed for a single field -goes into the initializer block of this field, making it obvious that it -is not needed by anything else. - -On the other hand, intermediate data that is needed for multiple fields -to initialize remains above the initializer, naturally indicating that -it is needed my multiple fields. - -Reviewed-by: Joel Fernandes -Link: https://patch.msgid.link/20251218155239.25243-5-dakr@kernel.org -Signed-off-by: Danilo Krummrich -Stable-dep-of: 4da879a0d3fd ("rust: dma: use pointer projection infra for `dma_{read,write}` macro") -Signed-off-by: Sasha Levin ---- - drivers/gpu/nova-core/gsp.rs | 61 +++++++++++++++++------------------- - 1 file changed, 28 insertions(+), 33 deletions(-) - -diff --git a/drivers/gpu/nova-core/gsp.rs b/drivers/gpu/nova-core/gsp.rs -index 8bc86e1bcac52..766fd99053589 100644 ---- a/drivers/gpu/nova-core/gsp.rs -+++ b/drivers/gpu/nova-core/gsp.rs -@@ -122,41 +122,36 @@ impl Gsp { - pub(crate) fn new(pdev: &pci::Device) -> impl PinInit + '_ { - pin_init::pin_init_scope(move || { - let dev = pdev.as_ref(); -- let libos = CoherentAllocation::::alloc_coherent( -- dev, -- GSP_PAGE_SIZE / size_of::(), -- GFP_KERNEL | __GFP_ZERO, -- )?; -- -- // Initialise the logging structures. The OpenRM equivalents are in: -- // _kgspInitLibosLoggingStructures (allocates memory for buffers) -- // kgspSetupLibosInitArgs_IMPL (creates pLibosInitArgs[] array) -- let loginit = LogBuffer::new(dev)?; -- dma_write!(libos[0] = LibosMemoryRegionInitArgument::new("LOGINIT", &loginit.0))?; -- -- let logintr = LogBuffer::new(dev)?; -- dma_write!(libos[1] = LibosMemoryRegionInitArgument::new("LOGINTR", &logintr.0))?; -- -- let logrm = LogBuffer::new(dev)?; -- dma_write!(libos[2] = LibosMemoryRegionInitArgument::new("LOGRM", &logrm.0))?; -- -- let cmdq = Cmdq::new(dev)?; -- -- let rmargs = CoherentAllocation::::alloc_coherent( -- dev, -- 1, -- GFP_KERNEL | __GFP_ZERO, -- )?; -- dma_write!(rmargs[0] = fw::GspArgumentsCached::new(&cmdq))?; -- dma_write!(libos[3] = LibosMemoryRegionInitArgument::new("RMARGS", &rmargs))?; - - Ok(try_pin_init!(Self { -- libos, -- loginit, -- logintr, -- logrm, -- rmargs, -- cmdq, -+ libos: CoherentAllocation::::alloc_coherent( -+ dev, -+ GSP_PAGE_SIZE / size_of::(), -+ GFP_KERNEL | __GFP_ZERO, -+ )?, -+ loginit: LogBuffer::new(dev)?, -+ logintr: LogBuffer::new(dev)?, -+ logrm: LogBuffer::new(dev)?, -+ cmdq: Cmdq::new(dev)?, -+ rmargs: CoherentAllocation::::alloc_coherent( -+ dev, -+ 1, -+ GFP_KERNEL | __GFP_ZERO, -+ )?, -+ _: { -+ // Initialise the logging structures. The OpenRM equivalents are in: -+ // _kgspInitLibosLoggingStructures (allocates memory for buffers) -+ // kgspSetupLibosInitArgs_IMPL (creates pLibosInitArgs[] array) -+ dma_write!( -+ 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] = fw::GspArgumentsCached::new(cmdq))?; -+ dma_write!(libos[3] = LibosMemoryRegionInitArgument::new("RMARGS", rmargs))?; -+ }, - })) - }) - } --- -2.51.0 - diff --git a/queue-6.19/rust-dma-use-pointer-projection-infra-for-dma_-read-.patch b/queue-6.19/rust-dma-use-pointer-projection-infra-for-dma_-read-.patch deleted file mode 100644 index 8581422119..0000000000 --- a/queue-6.19/rust-dma-use-pointer-projection-infra-for-dma_-read-.patch +++ /dev/null @@ -1,350 +0,0 @@ -From 26dd613c37a79884da7fd824263d4c93123688c3 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 2 Mar 2026 16:42:36 +0000 -Subject: rust: dma: use pointer projection infra for `dma_{read,write}` macro - -From: Gary Guo - -[ Upstream commit 4da879a0d3fd170a70994b73baa554c6913918b5 ] - -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. - -Fixes: ad2907b4e308 ("rust: add dma coherent allocator abstraction") -Reviewed-by: Benno Lossin -Signed-off-by: Gary Guo -Link: https://patch.msgid.link/20260302164239.284084-4-gary@kernel.org -[ Capitalize safety comments; slightly improve wording in doc-comments. - - Danilo ] -Signed-off-by: Danilo Krummrich -Signed-off-by: Sasha Levin ---- - 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(-) - -diff --git a/drivers/gpu/nova-core/gsp.rs b/drivers/gpu/nova-core/gsp.rs -index 174feaca0a6b9..25cd48514c777 100644 ---- a/drivers/gpu/nova-core/gsp.rs -+++ b/drivers/gpu/nova-core/gsp.rs -@@ -143,14 +143,14 @@ impl Gsp { - // _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)); - }, - })) - }) -diff --git a/drivers/gpu/nova-core/gsp/boot.rs b/drivers/gpu/nova-core/gsp/boot.rs -index 54937606b5b0a..38b4682ff01be 100644 ---- a/drivers/gpu/nova-core/gsp/boot.rs -+++ b/drivers/gpu/nova-core/gsp/boot.rs -@@ -160,7 +160,7 @@ impl super::Gsp { - - let wpr_meta = - CoherentAllocation::::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))?; -diff --git a/drivers/gpu/nova-core/gsp/cmdq.rs b/drivers/gpu/nova-core/gsp/cmdq.rs -index 3991ccc0c10f1..1cdd1ccfe5702 100644 ---- a/drivers/gpu/nova-core/gsp/cmdq.rs -+++ b/drivers/gpu/nova-core/gsp/cmdq.rs -@@ -201,9 +201,13 @@ impl DmaGspMem { - - let gsp_mem = - CoherentAllocation::::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)) - } -diff --git a/rust/kernel/dma.rs b/rust/kernel/dma.rs -index acc65b1e0f245..37e125bb423ad 100644 ---- a/rust/kernel/dma.rs -+++ b/rust/kernel/dma.rs -@@ -444,6 +444,19 @@ impl CoherentAllocation { - self.count * core::mem::size_of::() - } - -+ /// Returns the raw pointer to the allocated region in the CPU's virtual address space. -+ #[inline] -+ pub fn as_ptr(&self) -> *const [T] { -+ core::ptr::slice_from_raw_parts(self.cpu_addr.as_ptr(), self.count) -+ } -+ -+ /// Returns the raw pointer to the allocated region in the CPU's virtual address space as -+ /// a mutable pointer. -+ #[inline] -+ pub fn as_mut_ptr(&self) -> *mut [T] { -+ core::ptr::slice_from_raw_parts_mut(self.cpu_addr.as_ptr(), self.count) -+ } -+ - /// Returns the base address to the allocated region in the CPU's virtual address space. - pub fn start_ptr(&self) -> *const T { - self.cpu_addr.as_ptr() -@@ -564,23 +577,6 @@ impl CoherentAllocation { - Ok(()) - } - -- /// Returns a pointer to an element from the region with bounds checking. `offset` is in -- /// units of `T`, not the number of bytes. -- /// -- /// Public but hidden since it should only be used from [`dma_read`] and [`dma_write`] macros. -- #[doc(hidden)] -- pub fn item_from_index(&self, offset: usize) -> Result<*mut T> { -- if offset >= self.count { -- return Err(EINVAL); -- } -- // SAFETY: -- // - The pointer is valid due to type invariant on `CoherentAllocation` -- // and we've just checked that the range and index is within bounds. -- // - `offset` can't overflow since it is smaller than `self.count` and we've checked -- // that `self.count` won't overflow early in the constructor. -- Ok(unsafe { self.cpu_addr.as_ptr().add(offset) }) -- } -- - /// Reads the value of `field` and ensures that its type is [`FromBytes`]. - /// - /// # Safety -@@ -653,6 +649,9 @@ unsafe impl Send for CoherentAllocation {} - - /// Reads a field of an item from an allocated region of structs. - /// -+/// The syntax is of the form `kernel::dma_read!(dma, proj)` where `dma` is an expression evaluating -+/// to a [`CoherentAllocation`] and `proj` is a [projection specification](kernel::ptr::project!). -+/// - /// # Examples - /// - /// ``` -@@ -667,36 +666,29 @@ unsafe impl Send for CoherentAllocation {} - /// unsafe impl kernel::transmute::AsBytes for MyStruct{}; - /// - /// # fn test(alloc: &kernel::dma::CoherentAllocation) -> Result { --/// let whole = kernel::dma_read!(alloc[2]); --/// let field = kernel::dma_read!(alloc[1].field); -+/// let whole = kernel::dma_read!(alloc, [2]?); -+/// let field = kernel::dma_read!(alloc, [1]?.field); - /// # Ok::<(), Error>(()) } - /// ``` - #[macro_export] - macro_rules! dma_read { -- ($dma:expr, $idx: expr, $($field:tt)*) => {{ -- (|| -> ::core::result::Result<_, $crate::error::Error> { -- let item = $crate::dma::CoherentAllocation::item_from_index(&$dma, $idx)?; -- // SAFETY: `item_from_index` ensures that `item` is always a valid pointer and can be -- // dereferenced. The compiler also further validates the expression on whether `field` -- // is a member of `item` when expanded by the macro. -- unsafe { -- let ptr_field = ::core::ptr::addr_of!((*item) $($field)*); -- ::core::result::Result::Ok( -- $crate::dma::CoherentAllocation::field_read(&$dma, ptr_field) -- ) -- } -- })() -+ ($dma:expr, $($proj:tt)*) => {{ -+ let dma = &$dma; -+ let ptr = $crate::ptr::project!( -+ $crate::dma::CoherentAllocation::as_ptr(dma), $($proj)* -+ ); -+ // SAFETY: The pointer created by the projection is within the DMA region. -+ unsafe { $crate::dma::CoherentAllocation::field_read(dma, ptr) } - }}; -- ($dma:ident [ $idx:expr ] $($field:tt)* ) => { -- $crate::dma_read!($dma, $idx, $($field)*) -- }; -- ($($dma:ident).* [ $idx:expr ] $($field:tt)* ) => { -- $crate::dma_read!($($dma).*, $idx, $($field)*) -- }; - } - - /// Writes to a field of an item from an allocated region of structs. - /// -+/// The syntax is of the form `kernel::dma_write!(dma, proj, val)` where `dma` is an expression -+/// evaluating to a [`CoherentAllocation`], `proj` is a -+/// [projection specification](kernel::ptr::project!), and `val` is the value to be written to the -+/// projected location. -+/// - /// # Examples - /// - /// ``` -@@ -711,37 +703,31 @@ macro_rules! dma_read { - /// unsafe impl kernel::transmute::AsBytes for MyStruct{}; - /// - /// # fn test(alloc: &kernel::dma::CoherentAllocation) -> Result { --/// kernel::dma_write!(alloc[2].member = 0xf); --/// kernel::dma_write!(alloc[1] = MyStruct { member: 0xf }); -+/// kernel::dma_write!(alloc, [2]?.member, 0xf); -+/// kernel::dma_write!(alloc, [1]?, MyStruct { member: 0xf }); - /// # Ok::<(), Error>(()) } - /// ``` - #[macro_export] - macro_rules! dma_write { -- ($dma:ident [ $idx:expr ] $($field:tt)*) => {{ -- $crate::dma_write!($dma, $idx, $($field)*) -- }}; -- ($($dma:ident).* [ $idx:expr ] $($field:tt)* ) => {{ -- $crate::dma_write!($($dma).*, $idx, $($field)*) -+ (@parse [$dma:expr] [$($proj:tt)*] [, $val:expr]) => {{ -+ let dma = &$dma; -+ let ptr = $crate::ptr::project!( -+ mut $crate::dma::CoherentAllocation::as_mut_ptr(dma), $($proj)* -+ ); -+ let val = $val; -+ // SAFETY: The pointer created by the projection is within the DMA region. -+ unsafe { $crate::dma::CoherentAllocation::field_write(dma, ptr, val) } - }}; -- ($dma:expr, $idx: expr, = $val:expr) => { -- (|| -> ::core::result::Result<_, $crate::error::Error> { -- let item = $crate::dma::CoherentAllocation::item_from_index(&$dma, $idx)?; -- // SAFETY: `item_from_index` ensures that `item` is always a valid item. -- unsafe { $crate::dma::CoherentAllocation::field_write(&$dma, item, $val) } -- ::core::result::Result::Ok(()) -- })() -+ (@parse [$dma:expr] [$($proj:tt)*] [.$field:tt $($rest:tt)*]) => { -+ $crate::dma_write!(@parse [$dma] [$($proj)* .$field] [$($rest)*]) -+ }; -+ (@parse [$dma:expr] [$($proj:tt)*] [[$index:expr]? $($rest:tt)*]) => { -+ $crate::dma_write!(@parse [$dma] [$($proj)* [$index]?] [$($rest)*]) -+ }; -+ (@parse [$dma:expr] [$($proj:tt)*] [[$index:expr] $($rest:tt)*]) => { -+ $crate::dma_write!(@parse [$dma] [$($proj)* [$index]] [$($rest)*]) - }; -- ($dma:expr, $idx: expr, $(.$field:ident)* = $val:expr) => { -- (|| -> ::core::result::Result<_, $crate::error::Error> { -- let item = $crate::dma::CoherentAllocation::item_from_index(&$dma, $idx)?; -- // SAFETY: `item_from_index` ensures that `item` is always a valid pointer and can be -- // dereferenced. The compiler also further validates the expression on whether `field` -- // is a member of `item` when expanded by the macro. -- unsafe { -- let ptr_field = ::core::ptr::addr_of_mut!((*item) $(.$field)*); -- $crate::dma::CoherentAllocation::field_write(&$dma, ptr_field, $val) -- } -- ::core::result::Result::Ok(()) -- })() -+ ($dma:expr, $($rest:tt)*) => { -+ $crate::dma_write!(@parse [$dma] [] [$($rest)*]) - }; - } -diff --git a/samples/rust/rust_dma.rs b/samples/rust/rust_dma.rs -index f53bce2a73e3b..bcba1a6e6aaf4 100644 ---- a/samples/rust/rust_dma.rs -+++ b/samples/rust/rust_dma.rs -@@ -68,7 +68,7 @@ impl pci::Driver for DmaSampleDriver { - CoherentAllocation::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,6 +85,20 @@ impl pci::Driver for DmaSampleDriver { - } - } - -+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>) { -@@ -92,19 +106,7 @@ impl PinnedDrop for DmaSampleDriver { - - dev_info!(dev, "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!(dev, "Entry[{}]: DMA address: {:#x}", i, entry.dma_address()); --- -2.51.0 - diff --git a/queue-6.19/series b/queue-6.19/series index 57df1b1198..5f827029de 100644 --- a/queue-6.19/series +++ b/queue-6.19/series @@ -50,10 +50,6 @@ net-sched-teql-fix-null-pointer-dereference-in-iptun.patch rxrpc-afs-fix-missing-error-pointer-check-after-rxrp.patch net-spacemit-fix-error-handling-in-emac_alloc_rx_des.patch net-spacemit-fix-error-handling-in-emac_tx_mem_map.patch -gpu-nova-core-gsp-get-rid-of-redundant-result-in-gsp.patch -gpu-nova-core-gsp-move-appropriate-code-into-pin-ini.patch -gpu-nova-core-align-libosmemoryregioninitargument-si.patch -rust-dma-use-pointer-projection-infra-for-dma_-read-.patch drm-sitronix-st7586-fix-bad-pixel-data-due-to-byte-s.patch firmware-cs_dsp-fix-fragmentation-regression-in-firm.patch spi-amlogic-spifc-a4-fix-dma-mapping-error-handling.patch @@ -92,7 +88,6 @@ nvme-pci-fix-race-bug-in-nvme_poll_irqdisable.patch drivers-net-ice-fix-devlink-parameters-get-without-i.patch iavf-fix-ptp-use-after-free-during-reset.patch iavf-fix-incorrect-reset-handling-in-callbacks.patch -gpu-nova-core-fix-stack-overflow-in-gsp-memory-alloc.patch accel-amdxdna-fix-runtime-suspend-deadlock-when-ther.patch asoc-codecs-rt1011-use-component-to-get-the-dapm-con.patch i40e-fix-src-ip-mask-checks-and-memcpy-argument-name.patch @@ -101,7 +96,6 @@ page_pool-store-detach_time-as-ktime_t-to-avoid-fals.patch net-bcmgenet-fix-broken-eee-by-converting-to-phylib-.patch acpi-osl-fix-__iomem-type-on-return-from-acpi_os_map.patch asoc-amd-acp3x-rt5682-max9836-add-missing-error-chec.patch -gpu-nova-core-gsp-fix-ub-in-dmagspmem-pointer-access.patch asoc-detect-empty-dmi-strings.patch drm-amdkfd-unreserve-bo-if-queue-update-failed.patch asoc-amd-acp-mach-common-add-missing-error-check-for.patch