* [PATCH v11 1/6] rust: device: add device name method
2026-03-19 21:26 [PATCH v11 0/6] gpu: nova-core: expose the logging buffers via debugfs Timur Tabi
@ 2026-03-19 21:26 ` Timur Tabi
2026-03-19 21:26 ` [PATCH v11 2/6] rust: uaccess: add write_dma() for copying from DMA buffers to userspace Timur Tabi
` (5 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Timur Tabi @ 2026-03-19 21:26 UTC (permalink / raw)
To: Miguel Ojeda, Danilo Krummrich, Alice Ryhl, Gary Guo, mmaurer,
John Hubbard, Alexandre Courbot, Joel Fernandes, Eliot Courtney,
rust-for-linux
Add a name() method to the `Device` type, which returns a CStr that
contains the device name.
Signed-off-by: Timur Tabi <ttabi@nvidia.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Tested-by: John Hubbard <jhubbard@nvidia.com>
Tested-by: Eliot Courtney <ecourtney@nvidia.com>
---
rust/helpers/device.c | 5 +++++
rust/kernel/device.rs | 11 +++++++++++
2 files changed, 16 insertions(+)
diff --git a/rust/helpers/device.c b/rust/helpers/device.c
index a8ab931a9bd1..3be4ee590784 100644
--- a/rust/helpers/device.c
+++ b/rust/helpers/device.c
@@ -25,3 +25,8 @@ __rust_helper void rust_helper_dev_set_drvdata(struct device *dev, void *data)
{
dev_set_drvdata(dev, data);
}
+
+__rust_helper const char *rust_helper_dev_name(const struct device *dev)
+{
+ return dev_name(dev);
+}
diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs
index 94e0548e7687..8f6ad4f53101 100644
--- a/rust/kernel/device.rs
+++ b/rust/kernel/device.rs
@@ -489,6 +489,17 @@ pub fn fwnode(&self) -> Option<&property::FwNode> {
// defined as a `#[repr(transparent)]` wrapper around `fwnode_handle`.
Some(unsafe { &*fwnode_handle.cast() })
}
+
+ /// Returns the name of the device.
+ ///
+ /// This is the kobject name of the device, or its initial name if the kobject is not yet
+ /// available.
+ #[inline]
+ pub fn name(&self) -> &CStr {
+ // SAFETY: By its type invariant `self.as_raw()` is a valid pointer to a `struct device`.
+ // The returned string is valid for the lifetime of the device.
+ unsafe { CStr::from_char_ptr(bindings::dev_name(self.as_raw())) }
+ }
}
// SAFETY: `Device` is a transparent wrapper of a type that doesn't depend on `Device`'s generic
--
2.53.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v11 2/6] rust: uaccess: add write_dma() for copying from DMA buffers to userspace
2026-03-19 21:26 [PATCH v11 0/6] gpu: nova-core: expose the logging buffers via debugfs Timur Tabi
2026-03-19 21:26 ` [PATCH v11 1/6] rust: device: add device name method Timur Tabi
@ 2026-03-19 21:26 ` Timur Tabi
2026-03-24 20:00 ` Alice Ryhl
2026-03-19 21:26 ` [PATCH v11 3/6] rust: dma: implement BinaryWriter for CoherentAllocation<u8> Timur Tabi
` (4 subsequent siblings)
6 siblings, 1 reply; 9+ messages in thread
From: Timur Tabi @ 2026-03-19 21:26 UTC (permalink / raw)
To: Miguel Ojeda, Danilo Krummrich, Alice Ryhl, Gary Guo, mmaurer,
John Hubbard, Alexandre Courbot, Joel Fernandes, Eliot Courtney,
rust-for-linux
Add UserSliceWriter::write_dma() to copy data from a CoherentAllocation<u8>
to userspace. This provides a safe interface for copying DMA buffer
contents to userspace without requiring callers to work with raw pointers.
Because write_dma() and write_slice() have common code, factor that code
out into a helper function, write_raw().
The method handles bounds checking and offset calculation internally,
wrapping the unsafe copy_to_user() call.
Signed-off-by: Timur Tabi <ttabi@nvidia.com>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Acked-by: Miguel Ojeda <ojeda@kernel.org>
Tested-by: John Hubbard <jhubbard@nvidia.com>
Tested-by: Eliot Courtney <ecourtney@nvidia.com>
---
rust/kernel/uaccess.rs | 92 +++++++++++++++++++++++++++++++++++++-----
1 file changed, 82 insertions(+), 10 deletions(-)
diff --git a/rust/kernel/uaccess.rs b/rust/kernel/uaccess.rs
index f989539a31b4..c9004167c08d 100644
--- a/rust/kernel/uaccess.rs
+++ b/rust/kernel/uaccess.rs
@@ -7,6 +7,7 @@
use crate::{
alloc::{Allocator, Flags},
bindings,
+ dma::CoherentAllocation,
error::Result,
ffi::{c_char, c_void},
fs::file,
@@ -459,20 +460,20 @@ pub fn is_empty(&self) -> bool {
self.length == 0
}
- /// Writes raw data to this user pointer from a kernel buffer.
+ /// Low-level write from a raw pointer.
///
- /// Fails with [`EFAULT`] if the write happens on a bad address, or if the write goes out of
- /// bounds of this [`UserSliceWriter`]. This call may modify the associated userspace slice even
- /// if it returns an error.
- pub fn write_slice(&mut self, data: &[u8]) -> Result {
- let len = data.len();
- let data_ptr = data.as_ptr().cast::<c_void>();
+ /// # Safety
+ ///
+ /// The caller must ensure that `from` is valid for reads of `len` bytes.
+ unsafe fn write_raw(&mut self, from: *const u8, len: usize) -> Result {
if len > self.length {
return Err(EFAULT);
}
- // SAFETY: `data_ptr` points into an immutable slice of length `len`, so we may read
- // that many bytes from it.
- let res = unsafe { bindings::copy_to_user(self.ptr.as_mut_ptr(), data_ptr, len) };
+
+ // SAFETY: Caller guarantees `from` is valid for `len` bytes (see this function's
+ // safety contract).
+ let res =
+ unsafe { bindings::copy_to_user(self.ptr.as_mut_ptr(), from.cast::<c_void>(), len) };
if res != 0 {
return Err(EFAULT);
}
@@ -481,6 +482,77 @@ pub fn write_slice(&mut self, data: &[u8]) -> Result {
Ok(())
}
+ /// Writes raw data to this user pointer from a kernel buffer.
+ ///
+ /// Fails with [`EFAULT`] if the write happens on a bad address, or if the write goes out of
+ /// bounds of this [`UserSliceWriter`]. This call may modify the associated userspace slice even
+ /// if it returns an error.
+ pub fn write_slice(&mut self, data: &[u8]) -> Result {
+ // SAFETY: `data` is a valid slice, so `data.as_ptr()` is valid for
+ // reading `data.len()` bytes.
+ unsafe { self.write_raw(data.as_ptr(), data.len()) }
+ }
+
+ /// Writes raw data to this user pointer from a DMA coherent allocation.
+ ///
+ /// Copies `count` bytes from `alloc` starting from `offset` into this userspace slice.
+ ///
+ /// # Errors
+ ///
+ /// - [`EOVERFLOW`]: `offset + count` overflows.
+ /// - [`ERANGE`]: `offset + count` exceeds the size of `alloc`, or `count` exceeds the
+ /// size of the user-space buffer.
+ /// - [`EFAULT`]: the write hits a bad address or goes out of bounds of this
+ /// [`UserSliceWriter`].
+ ///
+ /// This call may modify the associated userspace slice even if it returns an error.
+ ///
+ /// Note: The memory may be concurrently modified by hardware (e.g., DMA). In such cases,
+ /// the copied data may be inconsistent, but this does not cause undefined behavior.
+ ///
+ /// # Example
+ ///
+ /// Copy the first 256 bytes of a DMA coherent allocation into a userspace buffer:
+ ///
+ /// ```no_run
+ /// use kernel::uaccess::UserSliceWriter;
+ /// use kernel::dma::CoherentAllocation;
+ ///
+ /// fn copy_dma_to_user(
+ /// mut writer: UserSliceWriter,
+ /// alloc: &CoherentAllocation<u8>,
+ /// ) -> Result {
+ /// writer.write_dma(alloc, 0, 256)
+ /// }
+ /// ```
+ pub fn write_dma(
+ &mut self,
+ alloc: &CoherentAllocation<u8>,
+ offset: usize,
+ count: usize,
+ ) -> Result {
+ let len = alloc.size();
+ if offset.checked_add(count).ok_or(EOVERFLOW)? > len {
+ return Err(ERANGE);
+ }
+
+ if count > self.len() {
+ return Err(ERANGE);
+ }
+
+ // SAFETY: `start_ptr()` returns a valid pointer to a memory region of `count()` bytes,
+ // as guaranteed by the `CoherentAllocation` invariants. The check above ensures
+ // `offset + count <= len`.
+ let src_ptr = unsafe { alloc.start_ptr().add(offset) };
+
+ // Note: Use `write_raw` instead of `write_slice` because the allocation is coherent
+ // memory that hardware may modify (e.g., DMA); we cannot form a `&[u8]` slice over
+ // such volatile memory.
+ //
+ // SAFETY: `src_ptr` points into the allocation and is valid for `count` bytes (see above).
+ unsafe { self.write_raw(src_ptr, count) }
+ }
+
/// Writes raw data to this user pointer from a kernel buffer partially.
///
/// This is the same as [`Self::write_slice`] but considers the given `offset` into `data` and
--
2.53.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH v11 2/6] rust: uaccess: add write_dma() for copying from DMA buffers to userspace
2026-03-19 21:26 ` [PATCH v11 2/6] rust: uaccess: add write_dma() for copying from DMA buffers to userspace Timur Tabi
@ 2026-03-24 20:00 ` Alice Ryhl
0 siblings, 0 replies; 9+ messages in thread
From: Alice Ryhl @ 2026-03-24 20:00 UTC (permalink / raw)
To: Timur Tabi
Cc: Miguel Ojeda, Danilo Krummrich, Gary Guo, mmaurer, John Hubbard,
Alexandre Courbot, Joel Fernandes, Eliot Courtney, rust-for-linux
On Thu, Mar 19, 2026 at 10:27 PM Timur Tabi <ttabi@nvidia.com> wrote:
>
> Add UserSliceWriter::write_dma() to copy data from a CoherentAllocation<u8>
> to userspace. This provides a safe interface for copying DMA buffer
> contents to userspace without requiring callers to work with raw pointers.
>
> Because write_dma() and write_slice() have common code, factor that code
> out into a helper function, write_raw().
>
> The method handles bounds checking and offset calculation internally,
> wrapping the unsafe copy_to_user() call.
>
> Signed-off-by: Timur Tabi <ttabi@nvidia.com>
> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
> Acked-by: Miguel Ojeda <ojeda@kernel.org>
> Tested-by: John Hubbard <jhubbard@nvidia.com>
> Tested-by: Eliot Courtney <ecourtney@nvidia.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
> + // SAFETY: Caller guarantees `from` is valid for `len` bytes (see this function's
> + // safety contract).
> + let res =
> + unsafe { bindings::copy_to_user(self.ptr.as_mut_ptr(), from.cast::<c_void>(), len) };
Please double check if formatting needs to be tweaked for clippy.
Alice
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v11 3/6] rust: dma: implement BinaryWriter for CoherentAllocation<u8>
2026-03-19 21:26 [PATCH v11 0/6] gpu: nova-core: expose the logging buffers via debugfs Timur Tabi
2026-03-19 21:26 ` [PATCH v11 1/6] rust: device: add device name method Timur Tabi
2026-03-19 21:26 ` [PATCH v11 2/6] rust: uaccess: add write_dma() for copying from DMA buffers to userspace Timur Tabi
@ 2026-03-19 21:26 ` Timur Tabi
2026-03-19 21:26 ` [PATCH v11 4/6] gpu: nova-core: Replace module_pci_driver! with explicit module init Timur Tabi
` (3 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Timur Tabi @ 2026-03-19 21:26 UTC (permalink / raw)
To: Miguel Ojeda, Danilo Krummrich, Alice Ryhl, Gary Guo, mmaurer,
John Hubbard, Alexandre Courbot, Joel Fernandes, Eliot Courtney,
rust-for-linux
Implement the BinaryWriter trait for CoherentAllocation<u8>, enabling
DMA coherent allocations to be exposed as readable binary files.
The implementation handles offset tracking and bounds checking, copying
data from the coherent allocation to userspace via write_dma().
Signed-off-by: Timur Tabi <ttabi@nvidia.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Tested-by: John Hubbard <jhubbard@nvidia.com>
Tested-by: Eliot Courtney <ecourtney@nvidia.com>
---
rust/kernel/dma.rs | 35 ++++++++++++++++++++++++++++++++++-
1 file changed, 34 insertions(+), 1 deletion(-)
diff --git a/rust/kernel/dma.rs b/rust/kernel/dma.rs
index a396f8435739..453fc547a0fc 100644
--- a/rust/kernel/dma.rs
+++ b/rust/kernel/dma.rs
@@ -5,12 +5,14 @@
//! C header: [`include/linux/dma-mapping.h`](srctree/include/linux/dma-mapping.h)
use crate::{
- bindings, build_assert, device,
+ bindings, build_assert, debugfs, device,
device::{Bound, Core},
error::{to_result, Result},
+ fs::file,
prelude::*,
sync::aref::ARef,
transmute::{AsBytes, FromBytes},
+ uaccess::UserSliceWriter,
};
use core::ptr::NonNull;
@@ -664,6 +666,37 @@ fn drop(&mut self) {
// can be sent to another thread.
unsafe impl<T: AsBytes + FromBytes + Send> Send for CoherentAllocation<T> {}
+// SAFETY: Sharing `&CoherentAllocation` across threads is safe if `T` is `Sync`, because all
+// methods that access the buffer contents (`field_read`, `field_write`, `as_slice`,
+// `as_slice_mut`) are `unsafe`, and callers are responsible for ensuring no data races occur.
+// The safe methods only return metadata or raw pointers whose use requires `unsafe`.
+unsafe impl<T: AsBytes + FromBytes + Sync> Sync for CoherentAllocation<T> {}
+
+impl debugfs::BinaryWriter for CoherentAllocation<u8> {
+ fn write_to_slice(
+ &self,
+ writer: &mut UserSliceWriter,
+ offset: &mut file::Offset,
+ ) -> Result<usize> {
+ if offset.is_negative() {
+ return Err(EINVAL);
+ }
+
+ // If the offset is too large for a usize (e.g. on 32-bit platforms),
+ // then consider that as past EOF and just return 0 bytes.
+ let Ok(offset_val) = usize::try_from(*offset) else {
+ return Ok(0);
+ };
+
+ let count = self.size().saturating_sub(offset_val).min(writer.len());
+
+ writer.write_dma(self, offset_val, count)?;
+
+ *offset += count as i64;
+ Ok(count)
+ }
+}
+
/// 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
--
2.53.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v11 4/6] gpu: nova-core: Replace module_pci_driver! with explicit module init
2026-03-19 21:26 [PATCH v11 0/6] gpu: nova-core: expose the logging buffers via debugfs Timur Tabi
` (2 preceding siblings ...)
2026-03-19 21:26 ` [PATCH v11 3/6] rust: dma: implement BinaryWriter for CoherentAllocation<u8> Timur Tabi
@ 2026-03-19 21:26 ` Timur Tabi
2026-03-19 21:26 ` [PATCH v11 5/6] gpu: nova-core: create debugfs root in " Timur Tabi
` (2 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Timur Tabi @ 2026-03-19 21:26 UTC (permalink / raw)
To: Miguel Ojeda, Danilo Krummrich, Alice Ryhl, Gary Guo, mmaurer,
John Hubbard, Alexandre Courbot, Joel Fernandes, Eliot Courtney,
rust-for-linux
Replace the module_pci_driver! macro with an explicit module
initialization using the standard module! macro and InPlaceModule
trait implementation. No functional change intended, with the
exception that the driver now prints a message when loaded.
This change is necessary so that we can create a top-level "nova_core"
debugfs entry when the driver is loaded.
Signed-off-by: Timur Tabi <ttabi@nvidia.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Tested-by: John Hubbard <jhubbard@nvidia.com>
Tested-by: Eliot Courtney <ecourtney@nvidia.com>
---
drivers/gpu/nova-core/nova_core.rs | 25 +++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/nova-core/nova_core.rs b/drivers/gpu/nova-core/nova_core.rs
index b5caf1044697..0114a59825aa 100644
--- a/drivers/gpu/nova-core/nova_core.rs
+++ b/drivers/gpu/nova-core/nova_core.rs
@@ -2,6 +2,13 @@
//! Nova Core GPU Driver
+use kernel::{
+ driver::Registration,
+ pci,
+ prelude::*,
+ InPlaceModule, //
+};
+
#[macro_use]
mod bitfield;
@@ -20,8 +27,22 @@
pub(crate) const MODULE_NAME: &core::ffi::CStr = <LocalModule as kernel::ModuleMetadata>::NAME;
-kernel::module_pci_driver! {
- type: driver::NovaCore,
+#[pin_data]
+struct NovaCoreModule {
+ #[pin]
+ _driver: Registration<pci::Adapter<driver::NovaCore>>,
+}
+
+impl InPlaceModule for NovaCoreModule {
+ fn init(module: &'static kernel::ThisModule) -> impl PinInit<Self, Error> {
+ try_pin_init!(Self {
+ _driver <- Registration::new(MODULE_NAME, module),
+ })
+ }
+}
+
+module! {
+ type: NovaCoreModule,
name: "NovaCore",
authors: ["Danilo Krummrich"],
description: "Nova Core GPU driver",
--
2.53.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v11 5/6] gpu: nova-core: create debugfs root in module init
2026-03-19 21:26 [PATCH v11 0/6] gpu: nova-core: expose the logging buffers via debugfs Timur Tabi
` (3 preceding siblings ...)
2026-03-19 21:26 ` [PATCH v11 4/6] gpu: nova-core: Replace module_pci_driver! with explicit module init Timur Tabi
@ 2026-03-19 21:26 ` Timur Tabi
2026-03-19 21:26 ` [PATCH v11 6/6] gpu: nova-core: create GSP-RM logging buffers debugfs entries Timur Tabi
2026-03-25 0:42 ` [PATCH v11 0/6] gpu: nova-core: expose the logging buffers via debugfs Danilo Krummrich
6 siblings, 0 replies; 9+ messages in thread
From: Timur Tabi @ 2026-03-19 21:26 UTC (permalink / raw)
To: Miguel Ojeda, Danilo Krummrich, Alice Ryhl, Gary Guo, mmaurer,
John Hubbard, Alexandre Courbot, Joel Fernandes, Eliot Courtney,
rust-for-linux
Create the 'nova_core' root debugfs entry when the driver loads.
Normally, non-const global variables need to be protected by a
mutex. Instead, we use unsafe code, as we know the entry is never
modified after the driver is loaded. This solves the lifetime
issue of the mutex guard, which would otherwise have required the
use of `pin_init_scope`.
Signed-off-by: Timur Tabi <ttabi@nvidia.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Tested-by: John Hubbard <jhubbard@nvidia.com>
Tested-by: Eliot Courtney <ecourtney@nvidia.com>
---
drivers/gpu/nova-core/nova_core.rs | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/drivers/gpu/nova-core/nova_core.rs b/drivers/gpu/nova-core/nova_core.rs
index 0114a59825aa..d50e5fbce0f2 100644
--- a/drivers/gpu/nova-core/nova_core.rs
+++ b/drivers/gpu/nova-core/nova_core.rs
@@ -3,6 +3,7 @@
//! Nova Core GPU Driver
use kernel::{
+ debugfs,
driver::Registration,
pci,
prelude::*,
@@ -27,16 +28,40 @@
pub(crate) const MODULE_NAME: &core::ffi::CStr = <LocalModule as kernel::ModuleMetadata>::NAME;
+// TODO: Move this into per-module data once that exists
+static mut DEBUGFS_ROOT: Option<debugfs::Dir> = None;
+
+/// Guard that clears `DEBUGFS_ROOT` when dropped.
+struct DebugfsRootGuard;
+
+impl Drop for DebugfsRootGuard {
+ fn drop(&mut self) {
+ // SAFETY: This guard is dropped after `_driver` (due to field order),
+ // so the driver is unregistered and no probe() can be running.
+ unsafe { DEBUGFS_ROOT = None };
+ }
+}
+
#[pin_data]
struct NovaCoreModule {
+ // Fields are dropped in declaration order, so `_driver` is dropped first,
+ // then `_debugfs_guard` clears `DEBUGFS_ROOT`.
#[pin]
_driver: Registration<pci::Adapter<driver::NovaCore>>,
+ _debugfs_guard: DebugfsRootGuard,
}
impl InPlaceModule for NovaCoreModule {
fn init(module: &'static kernel::ThisModule) -> impl PinInit<Self, Error> {
+ let dir = debugfs::Dir::new(kernel::c_str!("nova_core"));
+
+ // SAFETY: We are the only driver code running during init, so there
+ // cannot be any concurrent access to `DEBUGFS_ROOT`.
+ unsafe { DEBUGFS_ROOT = Some(dir) };
+
try_pin_init!(Self {
_driver <- Registration::new(MODULE_NAME, module),
+ _debugfs_guard: DebugfsRootGuard,
})
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v11 6/6] gpu: nova-core: create GSP-RM logging buffers debugfs entries
2026-03-19 21:26 [PATCH v11 0/6] gpu: nova-core: expose the logging buffers via debugfs Timur Tabi
` (4 preceding siblings ...)
2026-03-19 21:26 ` [PATCH v11 5/6] gpu: nova-core: create debugfs root in " Timur Tabi
@ 2026-03-19 21:26 ` Timur Tabi
2026-03-25 0:42 ` [PATCH v11 0/6] gpu: nova-core: expose the logging buffers via debugfs Danilo Krummrich
6 siblings, 0 replies; 9+ messages in thread
From: Timur Tabi @ 2026-03-19 21:26 UTC (permalink / raw)
To: Miguel Ojeda, Danilo Krummrich, Alice Ryhl, Gary Guo, mmaurer,
John Hubbard, Alexandre Courbot, Joel Fernandes, Eliot Courtney,
rust-for-linux
Create read-only debugfs entries for LOGINIT, LOGRM, and LOGINTR, which
are the three primary printf logging buffers from GSP-RM. LOGPMU will
be added at a later date, as it requires support for its RPC message
first.
This patch uses the `pin_init_scope` feature to create the entries.
`pin_init_scope` solves the lifetime issue over the `DEBUGFS_ROOT`
reference by delaying its acquisition until the time the entry is
actually initialized.
Co-developed-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Timur Tabi <ttabi@nvidia.com>
Tested-by: John Hubbard <jhubbard@nvidia.com>
Tested-by: Eliot Courtney <ecourtney@nvidia.com>
---
drivers/gpu/nova-core/gsp.rs | 48 ++++++++++++++++++++++++++++++------
1 file changed, 40 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/nova-core/gsp.rs b/drivers/gpu/nova-core/gsp.rs
index 72f173726f87..9399783ccb8d 100644
--- a/drivers/gpu/nova-core/gsp.rs
+++ b/drivers/gpu/nova-core/gsp.rs
@@ -3,6 +3,7 @@
mod boot;
use kernel::{
+ debugfs,
device,
dma::{
CoherentAllocation,
@@ -102,17 +103,24 @@ fn new(dev: &device::Device<device::Bound>) -> Result<Self> {
}
}
-/// GSP runtime data.
-#[pin_data]
-pub(crate) struct Gsp {
- /// Libos arguments.
- pub(crate) libos: CoherentAllocation<LibosMemoryRegionInitArgument>,
+/// Log buffers used by GSP-RM for debug logging.
+struct LogBuffers {
/// Init log buffer.
loginit: LogBuffer,
/// Interrupts log buffer.
logintr: LogBuffer,
/// RM log buffer.
logrm: LogBuffer,
+}
+
+/// GSP runtime data.
+#[pin_data]
+pub(crate) struct Gsp {
+ /// Libos arguments.
+ pub(crate) libos: CoherentAllocation<LibosMemoryRegionInitArgument>,
+ /// Log buffers, optionally exposed via debugfs.
+ #[pin]
+ logs: debugfs::Scope<LogBuffers>,
/// Command queue.
#[pin]
pub(crate) cmdq: Cmdq,
@@ -126,15 +134,17 @@ pub(crate) fn new(pdev: &pci::Device<device::Bound>) -> impl PinInit<Self, Error
pin_init::pin_init_scope(move || {
let dev = pdev.as_ref();
+ // Create log buffers before try_pin_init! so they're accessible throughout
+ let loginit = LogBuffer::new(dev)?;
+ let logintr = LogBuffer::new(dev)?;
+ let logrm = LogBuffer::new(dev)?;
+
Ok(try_pin_init!(Self {
libos: CoherentAllocation::<LibosMemoryRegionInitArgument>::alloc_coherent(
dev,
GSP_PAGE_SIZE / size_of::<LibosMemoryRegionInitArgument>(),
GFP_KERNEL | __GFP_ZERO,
)?,
- loginit: LogBuffer::new(dev)?,
- logintr: LogBuffer::new(dev)?,
- logrm: LogBuffer::new(dev)?,
cmdq <- Cmdq::new(dev),
rmargs: CoherentAllocation::<GspArgumentsPadded>::alloc_coherent(
dev,
@@ -155,6 +165,28 @@ pub(crate) fn new(pdev: &pci::Device<device::Bound>) -> impl PinInit<Self, Error
dma_write!(rmargs, [0]?.inner, fw::GspArgumentsCached::new(&cmdq));
dma_write!(libos, [3]?, LibosMemoryRegionInitArgument::new("RMARGS", rmargs));
},
+ logs <- {
+ let log_buffers = LogBuffers {
+ loginit,
+ logintr,
+ logrm,
+ };
+
+ #[allow(static_mut_refs)]
+ // SAFETY: `DEBUGFS_ROOT` is created before driver registration and cleared
+ // after driver unregistration, so no probe() can race with its modification.
+ // PANIC: `DEBUGFS_ROOT` cannot be `None` here. It is set before driver
+ // registration and cleared after driver unregistration, so it is always
+ // `Some` for the entire lifetime that probe() can be called.
+ let log_parent: &debugfs::Dir = unsafe { crate::DEBUGFS_ROOT.as_ref() }
+ .expect("DEBUGFS_ROOT not initialized");
+
+ log_parent.scope(log_buffers, dev.name(), |logs, dir| {
+ dir.read_binary_file(c"loginit", &logs.loginit.0);
+ dir.read_binary_file(c"logintr", &logs.logintr.0);
+ dir.read_binary_file(c"logrm", &logs.logrm.0);
+ })
+ },
}))
})
}
--
2.53.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH v11 0/6] gpu: nova-core: expose the logging buffers via debugfs
2026-03-19 21:26 [PATCH v11 0/6] gpu: nova-core: expose the logging buffers via debugfs Timur Tabi
` (5 preceding siblings ...)
2026-03-19 21:26 ` [PATCH v11 6/6] gpu: nova-core: create GSP-RM logging buffers debugfs entries Timur Tabi
@ 2026-03-25 0:42 ` Danilo Krummrich
6 siblings, 0 replies; 9+ messages in thread
From: Danilo Krummrich @ 2026-03-25 0:42 UTC (permalink / raw)
To: Timur Tabi
Cc: Miguel Ojeda, Alice Ryhl, Gary Guo, mmaurer, John Hubbard,
Alexandre Courbot, Joel Fernandes, Eliot Courtney, rust-for-linux
On Thu Mar 19, 2026 at 10:26 PM CET, Timur Tabi wrote:
Applied to drm-rust-next, thanks!
> Timur Tabi (6):
> rust: device: add device name method
> rust: uaccess: add write_dma() for copying from DMA buffers to
> userspace
[ Rebase onto Coherent<T> changes; remove unnecessary turbofish from
cast(). - Danilo ]
> rust: dma: implement BinaryWriter for CoherentAllocation<u8>
[ Rebase onto Coherent<T> changes. - Danilo ]
> gpu: nova-core: Replace module_pci_driver! with explicit module init
> gpu: nova-core: create debugfs root in module init
> gpu: nova-core: create GSP-RM logging buffers debugfs entries
[ Rebase onto Coherent<T> changes. - Danilo ]
There's a small follow-up series in [1].
[1] https://lore.kernel.org/driver-core/20260325003921.3420-1-dakr@kernel.org/
^ permalink raw reply [flat|nested] 9+ messages in thread