Rust for Linux List
 help / color / mirror / Atom feed
* [PATCH 0/4] gpu: nova: Export parameters from nova-core to nova-drm
@ 2026-07-06  5:34 Alistair Popple
  2026-07-06  5:34 ` [PATCH 1/4] gpu: nova-core: Add public driver API to nova-core Alistair Popple
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Alistair Popple @ 2026-07-06  5:34 UTC (permalink / raw)
  To: nova-gpu
  Cc: Alistair Popple, Danilo Krummrich, Alice Ryhl, David Airlie,
	Alexandre Courbot, Benno Lossin, Gary Guo, Eliot Courtney,
	John Hubbard, linux-kernel, dri-devel, rust-for-linux

This patch series adds some basic GPU properties to the existing nova-drm
GETPARAM ioctl. It builds on top of the "drm: Higher-Ranked Lifetime
private data" series[1] to correctly manage lifetimes of registration
data shared between DRM, auxbus and nova-core. It's also based on top of
"ForLt/CovariantForLt split, auxiliary closure API and DevresLt"[2] although the
functionality of that series isn't actually required.

A tree with this series applied on top of all pre-requisites is available at
[3].

Properties are exported via a new NovaCoreApi type which implements methods to
read data from the GPU. This has been implemented in a separate module to make
the public API implementations obvious and to keep them in one place. Auxiliary
bus drivers can obtain a handle to this type using NovaCoreApi::of().

This handle can then be stored as part of the DRM registration data and used to
interact with the GPU via the nova-core driver.

[1] - https://lore.kernel.org/rust-for-linux/20260628145406.2107056-1-dakr@kernel.org/
[2] - https://lore.kernel.org/driver-core/20260626183630.2585057-1-dakr@kernel.org/
[3] - https://github.com/apopple-nvidia/linux/tree/nova-drm

Cc: Danilo Krummrich <dakr@kernel.org>
Cc: Alice Ryhl <aliceryhl@google.com>
Cc: David Airlie <airlied@gmail.com>
Cc: Alexandre Courbot <acourbot@nvidia.com>
Cc: Benno Lossin <lossin@kernel.org>
Cc: Gary Guo <gary@garyguo.net>
Cc: Eliot Courtney <ecourtney@nvidia.com>
Cc: John Hubbard <jhubbard@nvidia.com>
Cc: linux-kernel@vger.kernel.org
Cc: nova-gpu@lists.linux.dev
Cc: dri-devel@lists.freedesktop.org
Cc: rust-for-linux@vger.kernel.org

Alistair Popple (4):
  gpu: nova-core: Add public driver API to nova-core
  gpu: nova: Add DRM registration data
  drm: nova: Add GETPARAM parameter to read the GPU chipset
  drm: nova: Add a GETPARAM parameter to read usable VRAM size

 drivers/gpu/drm/nova/driver.rs        | 15 +++++++--
 drivers/gpu/drm/nova/file.rs          | 15 ++++-----
 drivers/gpu/nova-core/api.rs          | 39 +++++++++++++++++++++++
 drivers/gpu/nova-core/driver.rs       | 45 ++++++++++++++++++++-------
 drivers/gpu/nova-core/gpu.rs          | 16 +++++-----
 drivers/gpu/nova-core/gsp/commands.rs |  8 +++++
 drivers/gpu/nova-core/gsp/hal.rs      |  2 +-
 drivers/gpu/nova-core/nova_core.rs    |  1 +
 include/uapi/drm/nova_drm.h           | 14 +++++++++
 9 files changed, 125 insertions(+), 30 deletions(-)
 create mode 100644 drivers/gpu/nova-core/api.rs

-- 
2.54.0


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/4] gpu: nova-core: Add public driver API to nova-core
  2026-07-06  5:34 [PATCH 0/4] gpu: nova: Export parameters from nova-core to nova-drm Alistair Popple
@ 2026-07-06  5:34 ` Alistair Popple
  2026-07-06 17:56   ` Danilo Krummrich
  2026-07-06  5:34 ` [PATCH 2/4] gpu: nova: Add DRM registration data Alistair Popple
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 11+ messages in thread
From: Alistair Popple @ 2026-07-06  5:34 UTC (permalink / raw)
  To: nova-gpu
  Cc: Alistair Popple, Danilo Krummrich, Alice Ryhl, David Airlie,
	Alexandre Courbot, Benno Lossin, Gary Guo, Eliot Courtney,
	John Hubbard, linux-kernel, dri-devel, rust-for-linux

Nova core will be used to export core functionality to other drivers
which will bind to it via auxiliary bus devices. Add a NovaCoreApi type
which drivers can use to call nova-core methods.

Auxiliary bus drivers can obtain a handle to call nova-core methods on
a particular GPU using NovaCoreApi::of(). This takes a reference to a
bound auxiliary bus device and returns a handle to NovaCoreApi.

Signed-off-by: Alistair Popple <apopple@nvidia.com>
---
 drivers/gpu/nova-core/api.rs       | 29 +++++++++++++++++++
 drivers/gpu/nova-core/driver.rs    | 45 ++++++++++++++++++++++--------
 drivers/gpu/nova-core/gsp/hal.rs   |  2 +-
 drivers/gpu/nova-core/nova_core.rs |  1 +
 4 files changed, 65 insertions(+), 12 deletions(-)
 create mode 100644 drivers/gpu/nova-core/api.rs

diff --git a/drivers/gpu/nova-core/api.rs b/drivers/gpu/nova-core/api.rs
new file mode 100644
index 000000000000..68ba8bda800a
--- /dev/null
+++ b/drivers/gpu/nova-core/api.rs
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Nova-core auxbus data. Contains all the methods used by the auxbus drivers
+//! to interact with nova-core.
+
+use core::pin::Pin;
+
+use kernel::{
+    auxiliary,
+    device::Bound,
+    prelude::*,
+    types::CovariantForLt, //
+};
+
+use crate::gpu::Gpu;
+
+/// API handle for the auxiliary bus child drivers to interact with nova-core.
+pub struct NovaCoreApi<'bound> {
+    #[allow(dead_code)]
+    pub(crate) gpu: Pin<&'bound Gpu<'bound>>,
+}
+
+impl NovaCoreApi<'_> {
+    /// Obtain a [`NovaCoreApi`] handle from an auxiliary device registered
+    /// by nova-core.
+    pub fn of(adev: &auxiliary::Device<Bound>) -> Result<Pin<&NovaCoreApi<'_>>> {
+        adev.registration_data::<CovariantForLt!(NovaCoreApi<'_>)>()
+    }
+}
diff --git a/drivers/gpu/nova-core/driver.rs b/drivers/gpu/nova-core/driver.rs
index 48380ac15f68..c3c2acd72368 100644
--- a/drivers/gpu/nova-core/driver.rs
+++ b/drivers/gpu/nova-core/driver.rs
@@ -18,6 +18,7 @@
     types::CovariantForLt,
 };
 
+use crate::api::NovaCoreApi;
 use crate::gpu::Gpu;
 
 /// Counter for generating unique auxiliary device IDs.
@@ -25,11 +26,14 @@
 
 #[pin_data]
 pub(crate) struct NovaCore<'bound> {
+    // Fields are dropped in declaration order: unregister the auxiliary
+    // device before dropping `gpu`, and drop `gpu` before `bar` because `Gpu`
+    // borrows `bar`.
+    #[allow(clippy::type_complexity)]
+    _reg: auxiliary::Registration<'bound, CovariantForLt!(NovaCoreApi<'_>)>,
     #[pin]
     pub(crate) gpu: Gpu<'bound>,
     bar: pci::Bar<'bound, BAR0_SIZE>,
-    #[allow(clippy::type_complexity)]
-    _reg: auxiliary::Registration<'bound, CovariantForLt!(())>,
 }
 
 pub(crate) struct NovaCoreDriver;
@@ -86,15 +90,34 @@ fn probe<'bound>(
                 // (`try_pin_init!()` initializes fields in declaration order), lives at a pinned
                 // stable address, and is dropped after `gpu` (struct field drop order).
                 gpu <- Gpu::new(pdev, unsafe { &*core::ptr::from_ref(bar) }),
-                _reg: auxiliary::Registration::new(
-                    pdev.as_ref(),
-                    c"nova-drm",
-                    // TODO[XARR]: Use XArray or perhaps IDA for proper ID allocation/recycling. For
-                    // now, use a simple atomic counter that never recycles IDs.
-                    AUXILIARY_ID_COUNTER.fetch_add(1, Relaxed),
-                    crate::MODULE_NAME,
-                    (),
-                )?,
+
+                // SAFETY:
+                // - `NovaCore` is dropped when the device is unbound; i.e.
+                //   `mem::forget()` is never called on it.
+                // - `gpu` is initialized above, lives at a pinned stable
+                //   address, and is dropped after `_reg` (struct field drop
+                //   order).
+                _reg: unsafe {
+                    auxiliary::Registration::new_with_lt(
+                        pdev.as_ref(),
+                        c"nova-drm",
+                        // TODO[XARR]: Use XArray or perhaps IDA for proper ID allocation/recycling.
+                        // For now, use a simple atomic counter that never recycles IDs.
+                        AUXILIARY_ID_COUNTER.fetch_add(1, Relaxed),
+                        crate::MODULE_NAME,
+                        NovaCoreApi {
+                            // TODO: Use `&gpu` self-referential pin-init syntax once available.
+                            //
+                            // SAFETY: `gpu` is initialized before this expression is evaluated
+                            // (`try_pin_init!()` initializes fields in declaration order), lives at
+                            // a pinned stable address, and is dropped after `_reg` (struct field
+                            // drop order).
+                            gpu: Pin::new_unchecked(
+                                &*core::ptr::from_ref(gpu.as_ref().get_ref()),
+                            ),
+                        },
+                    )?
+                },
             }))
         })
     }
diff --git a/drivers/gpu/nova-core/gsp/hal.rs b/drivers/gpu/nova-core/gsp/hal.rs
index d3e47ef206de..06647b2b7894 100644
--- a/drivers/gpu/nova-core/gsp/hal.rs
+++ b/drivers/gpu/nova-core/gsp/hal.rs
@@ -36,7 +36,7 @@
 /// The GSP unload code might run in a situation where we cannot load firmware dynamically (e.g.
 /// because we are in shutdown and the file system is not accessible anymore). Thus, the firmware
 /// required for unloading is prepared at load time, and stored here until it needs to be run.
-pub(super) trait UnloadBundle: Send {
+pub(super) trait UnloadBundle: Send + Sync {
     /// Performs the steps required to properly reset the GSP after it has been stopped.
     fn run(
         &self,
diff --git a/drivers/gpu/nova-core/nova_core.rs b/drivers/gpu/nova-core/nova_core.rs
index 735b8e17c6b6..2d48d16a6ee8 100644
--- a/drivers/gpu/nova-core/nova_core.rs
+++ b/drivers/gpu/nova-core/nova_core.rs
@@ -13,6 +13,7 @@
 #[macro_use]
 mod bitfield;
 
+pub mod api;
 mod driver;
 mod falcon;
 mod fb;
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/4] gpu: nova: Add DRM registration data
  2026-07-06  5:34 [PATCH 0/4] gpu: nova: Export parameters from nova-core to nova-drm Alistair Popple
  2026-07-06  5:34 ` [PATCH 1/4] gpu: nova-core: Add public driver API to nova-core Alistair Popple
@ 2026-07-06  5:34 ` Alistair Popple
  2026-07-06 18:01   ` Danilo Krummrich
  2026-07-06  5:34 ` [PATCH 3/4] drm: nova: Add GETPARAM parameter to read the GPU chipset Alistair Popple
  2026-07-06  5:34 ` [PATCH 4/4] drm: nova: Add a GETPARAM parameter to read usable VRAM size Alistair Popple
  3 siblings, 1 reply; 11+ messages in thread
From: Alistair Popple @ 2026-07-06  5:34 UTC (permalink / raw)
  To: nova-gpu
  Cc: Alistair Popple, Danilo Krummrich, Alice Ryhl, David Airlie,
	Alexandre Courbot, Benno Lossin, Gary Guo, Eliot Courtney,
	John Hubbard, linux-kernel, dri-devel, rust-for-linux

Currently the nova-drm stub driver doesn't really interact with a real
device, so it doesn't have any registration data and has no way to call
into nova-core.

To allow for this add a DrmRegData type which will hold a reference to
the NovaCoreApi associated with the auxbus device.

Signed-off-by: Alistair Popple <apopple@nvidia.com>
Suggested-by: Danilo Krummrich <dakr@kernel.org>
---
 drivers/gpu/drm/nova/driver.rs | 16 ++++++++++++++--
 drivers/gpu/drm/nova/file.rs   | 13 ++++++-------
 2 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/nova/driver.rs b/drivers/gpu/drm/nova/driver.rs
index 739690bc2db5..3ae719540e4d 100644
--- a/drivers/gpu/drm/nova/driver.rs
+++ b/drivers/gpu/drm/nova/driver.rs
@@ -1,5 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 
+use core::pin::Pin;
+
 use kernel::{
     auxiliary,
     device::{
@@ -17,6 +19,7 @@
 
 use crate::file::File;
 use crate::gem::NovaObject;
+use nova_core::api::NovaCoreApi;
 
 pub(crate) struct NovaDriver;
 
@@ -26,6 +29,12 @@ pub(crate) struct Nova<'bound> {
     _reg: drm::Registration<'bound, NovaDriver>,
 }
 
+/// DRM registration data, accessible from ioctl handlers via the registration guard.
+pub(crate) struct DrmRegData<'bound> {
+    #[allow(dead_code)]
+    pub(crate) api: Pin<&'bound NovaCoreApi<'bound>>,
+}
+
 /// Convienence type alias for the DRM device type for this driver
 pub(crate) type NovaDevice<Ctx = drm::Normal> = drm::Device<NovaDriver, Ctx>;
 
@@ -60,9 +69,12 @@ fn probe<'bound>(
         _info: &'bound Self::IdInfo,
     ) -> impl PinInit<Self::Data<'bound>, Error> + 'bound {
         let drm = drm::UnregisteredDevice::<Self>::new(adev, Ok(()))?;
+        let reg_data = DrmRegData {
+            api: NovaCoreApi::of(adev)?,
+        };
         // SAFETY: `reg` is stored in `Nova` and dropped when the driver is unbound; it is
         // never forgotten.
-        let reg = unsafe { drm::Registration::new(adev.as_ref(), drm, (), 0)? };
+        let reg = unsafe { drm::Registration::new(adev.as_ref(), drm, reg_data, 0)? };
 
         Ok(Nova {
             drm: reg.device().into(),
@@ -74,7 +86,7 @@ fn probe<'bound>(
 #[vtable]
 impl drm::Driver for NovaDriver {
     type Data = ();
-    type RegistrationData<'a> = ();
+    type RegistrationData<'a> = DrmRegData<'a>;
     type File = File;
     type Object = gem::Object<NovaObject>;
     type ParentDevice<Ctx: DeviceContext> = auxiliary::Device<Ctx>;
diff --git a/drivers/gpu/drm/nova/file.rs b/drivers/gpu/drm/nova/file.rs
index 298c02bacb4b..855b6ffe696f 100644
--- a/drivers/gpu/drm/nova/file.rs
+++ b/drivers/gpu/drm/nova/file.rs
@@ -1,11 +1,10 @@
 // SPDX-License-Identifier: GPL-2.0
 
-use crate::driver::{NovaDevice, NovaDriver};
+use crate::driver::{DrmRegData, NovaDevice, NovaDriver};
 use crate::gem::NovaObject;
 use kernel::{
     alloc::flags::*,
     auxiliary,
-    device::Bound,
     drm::{
         self,
         gem::BaseObject,
@@ -30,12 +29,12 @@ impl File {
     /// IOCTL: get_param: Query GPU / driver metadata.
     pub(crate) fn get_param(
         dev: &NovaDevice<Registered>,
-        _reg_data: &(),
+        _reg_data: &DrmRegData<'_>,
         getparam: &mut uapi::drm_nova_getparam,
         _file: &drm::File<File>,
     ) -> Result<u32> {
-        let adev: &auxiliary::Device<Bound> = dev.as_ref();
-        let pdev: &pci::Device<Bound> = adev.parent().try_into()?;
+        let adev: &auxiliary::Device<_> = dev.as_ref();
+        let pdev: &pci::Device<_> = adev.parent().try_into()?;
 
         let value = match getparam.param as u32 {
             uapi::NOVA_GETPARAM_VRAM_BAR_SIZE => pdev.resource_len(1)?,
@@ -50,7 +49,7 @@ pub(crate) fn get_param(
     /// IOCTL: gem_create: Create a new DRM GEM object.
     pub(crate) fn gem_create(
         dev: &NovaDevice<Registered>,
-        _reg_data: &(),
+        _reg_data: &DrmRegData<'_>,
         req: &mut uapi::drm_nova_gem_create,
         file: &drm::File<File>,
     ) -> Result<u32> {
@@ -64,7 +63,7 @@ pub(crate) fn gem_create(
     /// IOCTL: gem_info: Query GEM metadata.
     pub(crate) fn gem_info(
         _dev: &NovaDevice<Registered>,
-        _reg_data: &(),
+        _reg_data: &DrmRegData<'_>,
         req: &mut uapi::drm_nova_gem_info,
         file: &drm::File<File>,
     ) -> Result<u32> {
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/4] drm: nova: Add GETPARAM parameter to read the GPU chipset
  2026-07-06  5:34 [PATCH 0/4] gpu: nova: Export parameters from nova-core to nova-drm Alistair Popple
  2026-07-06  5:34 ` [PATCH 1/4] gpu: nova-core: Add public driver API to nova-core Alistair Popple
  2026-07-06  5:34 ` [PATCH 2/4] gpu: nova: Add DRM registration data Alistair Popple
@ 2026-07-06  5:34 ` Alistair Popple
  2026-07-06 17:35   ` Timur Tabi
  2026-07-06 18:16   ` Danilo Krummrich
  2026-07-06  5:34 ` [PATCH 4/4] drm: nova: Add a GETPARAM parameter to read usable VRAM size Alistair Popple
  3 siblings, 2 replies; 11+ messages in thread
From: Alistair Popple @ 2026-07-06  5:34 UTC (permalink / raw)
  To: nova-gpu
  Cc: Alistair Popple, Danilo Krummrich, Alice Ryhl, David Airlie,
	Alexandre Courbot, Benno Lossin, Gary Guo, Eliot Courtney,
	John Hubbard, linux-kernel, dri-devel, rust-for-linux

One of the first things a user needs to know about a GPU is its chipset,
so add an ioctl to return that.

Signed-off-by: Alistair Popple <apopple@nvidia.com>
---
 drivers/gpu/drm/nova/driver.rs |  1 -
 drivers/gpu/drm/nova/file.rs   |  3 ++-
 drivers/gpu/nova-core/api.rs   |  7 ++++++-
 drivers/gpu/nova-core/gpu.rs   | 10 +++++-----
 include/uapi/drm/nova_drm.h    |  7 +++++++
 5 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/nova/driver.rs b/drivers/gpu/drm/nova/driver.rs
index 3ae719540e4d..42f8845ed6b4 100644
--- a/drivers/gpu/drm/nova/driver.rs
+++ b/drivers/gpu/drm/nova/driver.rs
@@ -31,7 +31,6 @@ pub(crate) struct Nova<'bound> {
 
 /// DRM registration data, accessible from ioctl handlers via the registration guard.
 pub(crate) struct DrmRegData<'bound> {
-    #[allow(dead_code)]
     pub(crate) api: Pin<&'bound NovaCoreApi<'bound>>,
 }
 
diff --git a/drivers/gpu/drm/nova/file.rs b/drivers/gpu/drm/nova/file.rs
index 855b6ffe696f..e573be34bb96 100644
--- a/drivers/gpu/drm/nova/file.rs
+++ b/drivers/gpu/drm/nova/file.rs
@@ -29,7 +29,7 @@ impl File {
     /// IOCTL: get_param: Query GPU / driver metadata.
     pub(crate) fn get_param(
         dev: &NovaDevice<Registered>,
-        _reg_data: &DrmRegData<'_>,
+        reg_data: &DrmRegData<'_>,
         getparam: &mut uapi::drm_nova_getparam,
         _file: &drm::File<File>,
     ) -> Result<u32> {
@@ -38,6 +38,7 @@ pub(crate) fn get_param(
 
         let value = match getparam.param as u32 {
             uapi::NOVA_GETPARAM_VRAM_BAR_SIZE => pdev.resource_len(1)?,
+            uapi::NOVA_GETPARAM_GPU_CHIPSET => reg_data.api.chipset() as u64,
             _ => return Err(EINVAL),
         };
 
diff --git a/drivers/gpu/nova-core/api.rs b/drivers/gpu/nova-core/api.rs
index 68ba8bda800a..14ca26e257d3 100644
--- a/drivers/gpu/nova-core/api.rs
+++ b/drivers/gpu/nova-core/api.rs
@@ -12,11 +12,11 @@
     types::CovariantForLt, //
 };
 
+use crate::gpu::Chipset;
 use crate::gpu::Gpu;
 
 /// API handle for the auxiliary bus child drivers to interact with nova-core.
 pub struct NovaCoreApi<'bound> {
-    #[allow(dead_code)]
     pub(crate) gpu: Pin<&'bound Gpu<'bound>>,
 }
 
@@ -26,4 +26,9 @@ impl NovaCoreApi<'_> {
     pub fn of(adev: &auxiliary::Device<Bound>) -> Result<Pin<&NovaCoreApi<'_>>> {
         adev.registration_data::<CovariantForLt!(NovaCoreApi<'_>)>()
     }
+
+    /// Returns the chipset of this GPU.
+    pub fn chipset(&self) -> Chipset {
+        self.gpu.spec.chipset
+    }
 }
diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
index 43c3f4f8df71..d4a71a1be6f1 100644
--- a/drivers/gpu/nova-core/gpu.rs
+++ b/drivers/gpu/nova-core/gpu.rs
@@ -38,7 +38,7 @@ macro_rules! define_chipset {
     {
         /// Enum representation of the GPU chipset.
         #[derive(fmt::Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq)]
-        pub(crate) enum Chipset {
+        pub enum Chipset {
             $($variant = $value),*,
         }
 
@@ -114,7 +114,7 @@ fn try_from(value: u32) -> Result<Self, Self::Error> {
 });
 
 impl Chipset {
-    pub(crate) const fn arch(self) -> Architecture {
+    pub const fn arch(self) -> Architecture {
         match self {
             Self::TU102 | Self::TU104 | Self::TU106 | Self::TU117 | Self::TU116 => {
                 Architecture::Turing
@@ -172,7 +172,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 bounded_enum! {
     /// Enum representation of the GPU generation.
     #[derive(fmt::Debug, Copy, Clone)]
-    pub(crate) enum Architecture with TryFrom<Bounded<u32, 6>> {
+    pub enum Architecture with TryFrom<Bounded<u32, 6>> {
         Turing = 0x16,
         Ampere = 0x17,
         Hopper = 0x18,
@@ -206,7 +206,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 /// Structure holding a basic description of the GPU: `Chipset` and `Revision`.
 #[derive(Clone, Copy)]
 pub(crate) struct Spec {
-    chipset: Chipset,
+    pub(crate) chipset: Chipset,
     revision: Revision,
 }
 
@@ -286,7 +286,7 @@ struct GspResources<'gpu> {
 /// Structure holding the resources required to operate the GPU.
 #[pin_data]
 pub(crate) struct Gpu<'gpu> {
-    spec: Spec,
+    pub(crate) spec: Spec,
     /// Static GPU information as provided by the GSP.
     gsp_static_info: GetGspStaticInfoReply,
     /// GSP and its resources.
diff --git a/include/uapi/drm/nova_drm.h b/include/uapi/drm/nova_drm.h
index 3ca90ed9d2bb..63440f5dca9b 100644
--- a/include/uapi/drm/nova_drm.h
+++ b/include/uapi/drm/nova_drm.h
@@ -25,6 +25,13 @@ extern "C" {
  */
 #define NOVA_GETPARAM_VRAM_BAR_SIZE	0x1
 
+/*
+ * NOVA_GETPARAM_GPU_CHIPSET
+ *
+ * Query the GPU chipset architecture/implementation.
+ */
+#define NOVA_GETPARAM_GPU_CHIPSET	0x2
+
 /**
  * struct drm_nova_getparam - query GPU and driver metadata
  */
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 4/4] drm: nova: Add a GETPARAM parameter to read usable VRAM size
  2026-07-06  5:34 [PATCH 0/4] gpu: nova: Export parameters from nova-core to nova-drm Alistair Popple
                   ` (2 preceding siblings ...)
  2026-07-06  5:34 ` [PATCH 3/4] drm: nova: Add GETPARAM parameter to read the GPU chipset Alistair Popple
@ 2026-07-06  5:34 ` Alistair Popple
  2026-07-06 18:26   ` Danilo Krummrich
  3 siblings, 1 reply; 11+ messages in thread
From: Alistair Popple @ 2026-07-06  5:34 UTC (permalink / raw)
  To: nova-gpu
  Cc: Alistair Popple, Danilo Krummrich, Alice Ryhl, David Airlie,
	Alexandre Courbot, Benno Lossin, Gary Guo, Eliot Courtney,
	John Hubbard, linux-kernel, dri-devel, rust-for-linux

Add a GET_PARAM ioctl to return the total usable framebuffer size. The
usable framebuffer excludes GSP carveouts and other protected regions so
may differ in size from BAR size and total physical VRAM.

Signed-off-by: Alistair Popple <apopple@nvidia.com>
---
 drivers/gpu/drm/nova/file.rs          | 1 +
 drivers/gpu/nova-core/api.rs          | 5 +++++
 drivers/gpu/nova-core/gpu.rs          | 6 ++----
 drivers/gpu/nova-core/gsp/commands.rs | 8 ++++++++
 include/uapi/drm/nova_drm.h           | 7 +++++++
 5 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/nova/file.rs b/drivers/gpu/drm/nova/file.rs
index e573be34bb96..26d7bc198c30 100644
--- a/drivers/gpu/drm/nova/file.rs
+++ b/drivers/gpu/drm/nova/file.rs
@@ -39,6 +39,7 @@ pub(crate) fn get_param(
         let value = match getparam.param as u32 {
             uapi::NOVA_GETPARAM_VRAM_BAR_SIZE => pdev.resource_len(1)?,
             uapi::NOVA_GETPARAM_GPU_CHIPSET => reg_data.api.chipset() as u64,
+            uapi::NOVA_GETPARAM_VRAM_SIZE => reg_data.api.vram_size(),
             _ => return Err(EINVAL),
         };
 
diff --git a/drivers/gpu/nova-core/api.rs b/drivers/gpu/nova-core/api.rs
index 14ca26e257d3..f55226afbd3b 100644
--- a/drivers/gpu/nova-core/api.rs
+++ b/drivers/gpu/nova-core/api.rs
@@ -31,4 +31,9 @@ pub fn of(adev: &auxiliary::Device<Bound>) -> Result<Pin<&NovaCoreApi<'_>>> {
     pub fn chipset(&self) -> Chipset {
         self.gpu.spec.chipset
     }
+
+    /// Returns the total usable VRAM size of this GPU in bytes.
+    pub fn vram_size(&self) -> u64 {
+        self.gpu.gsp_static_info.vram_size()
+    }
 }
diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
index d4a71a1be6f1..a089843f6d0a 100644
--- a/drivers/gpu/nova-core/gpu.rs
+++ b/drivers/gpu/nova-core/gpu.rs
@@ -288,7 +288,7 @@ struct GspResources<'gpu> {
 pub(crate) struct Gpu<'gpu> {
     pub(crate) spec: Spec,
     /// Static GPU information as provided by the GSP.
-    gsp_static_info: GetGspStaticInfoReply,
+    pub(crate) gsp_static_info: GetGspStaticInfoReply,
     /// GSP and its resources.
     #[pin]
     gsp_resources: GspResources<'gpu>,
@@ -388,9 +388,7 @@ pub(crate) fn new(
                     dev_dbg!(
                         pdev,
                         "Total usable VRAM: {} MiB\n",
-                        info.usable_fb_regions.iter().fold(0u64, |res, region| res
-                            .saturating_add(region.end - region.start))
-                            / u64::SZ_1M
+                        info.vram_size() / u64::SZ_1M
                     );
                 }
 
diff --git a/drivers/gpu/nova-core/gsp/commands.rs b/drivers/gpu/nova-core/gsp/commands.rs
index 86a3747cd31c..e41227fc015d 100644
--- a/drivers/gpu/nova-core/gsp/commands.rs
+++ b/drivers/gpu/nova-core/gsp/commands.rs
@@ -242,6 +242,14 @@ pub(crate) fn gpu_name(&self) -> core::result::Result<&str, GpuNameError> {
             .to_str()
             .map_err(GpuNameError::InvalidUtf8)
     }
+
+    /// Returns the total usable VRAM size in bytes, i.e. the summed lengths of all usable FB
+    /// regions.
+    pub(crate) fn vram_size(&self) -> u64 {
+        self.usable_fb_regions
+            .iter()
+            .fold(0, |size, region| size.saturating_add(region.end - region.start))
+    }
 }
 
 pub(crate) use fw::commands::PowerStateLevel;
diff --git a/include/uapi/drm/nova_drm.h b/include/uapi/drm/nova_drm.h
index 63440f5dca9b..eb98817906a8 100644
--- a/include/uapi/drm/nova_drm.h
+++ b/include/uapi/drm/nova_drm.h
@@ -32,6 +32,13 @@ extern "C" {
  */
 #define NOVA_GETPARAM_GPU_CHIPSET	0x2
 
+/*
+ * NOVA_GETPARAM_VRAM_SIZE
+ *
+ * Query the total usable VRAM size in bytes.
+ */
+#define NOVA_GETPARAM_VRAM_SIZE	0x3
+
 /**
  * struct drm_nova_getparam - query GPU and driver metadata
  */
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/4] drm: nova: Add GETPARAM parameter to read the GPU chipset
  2026-07-06  5:34 ` [PATCH 3/4] drm: nova: Add GETPARAM parameter to read the GPU chipset Alistair Popple
@ 2026-07-06 17:35   ` Timur Tabi
  2026-07-06 18:24     ` Danilo Krummrich
  2026-07-06 18:16   ` Danilo Krummrich
  1 sibling, 1 reply; 11+ messages in thread
From: Timur Tabi @ 2026-07-06 17:35 UTC (permalink / raw)
  To: Alistair Popple, nova-gpu@lists.linux.dev
  Cc: John Hubbard, gary@garyguo.net, Eliot Courtney, lossin@kernel.org,
	airlied@gmail.com, linux-kernel@vger.kernel.org, dakr@kernel.org,
	rust-for-linux@vger.kernel.org, aliceryhl@google.com,
	Alexandre Courbot, dri-devel@lists.freedesktop.org

On Mon, 2026-07-06 at 15:34 +1000, Alistair Popple wrote:
> @@ -38,6 +38,7 @@ pub(crate) fn get_param(
>  
>          let value = match getparam.param as u32 {
>              uapi::NOVA_GETPARAM_VRAM_BAR_SIZE => pdev.resource_len(1)?,
> +            uapi::NOVA_GETPARAM_GPU_CHIPSET => reg_data.api.chipset() as u64,

Can we assign these IOCtl values to match Nouveau as much as possible?  I think it would make
everyone's life easier if we could use the same user-space tools/libraries for Nova that we do for
Nouveau.

#define DRM_NOUVEAU_GETPARAM           0x00
#define DRM_NOUVEAU_SETPARAM           0x01 /* deprecated */
#define DRM_NOUVEAU_CHANNEL_ALLOC      0x02
#define DRM_NOUVEAU_CHANNEL_FREE       0x03
#define DRM_NOUVEAU_GROBJ_ALLOC        0x04 /* deprecated */
#define DRM_NOUVEAU_NOTIFIEROBJ_ALLOC  0x05 /* deprecated */
#define DRM_NOUVEAU_GPUOBJ_FREE        0x06 /* deprecated */
#define DRM_NOUVEAU_NVIF               0x07
#define DRM_NOUVEAU_SVM_INIT           0x08
#define DRM_NOUVEAU_SVM_BIND           0x09
#define DRM_NOUVEAU_VM_INIT            0x10
#define DRM_NOUVEAU_VM_BIND            0x11
#define DRM_NOUVEAU_EXEC               0x12
#define DRM_NOUVEAU_GET_ZCULL_INFO     0x13
#define DRM_NOUVEAU_GEM_NEW            0x40
#define DRM_NOUVEAU_GEM_PUSHBUF        0x41
#define DRM_NOUVEAU_GEM_CPU_PREP       0x42
#define DRM_NOUVEAU_GEM_CPU_FINI       0x43
#define DRM_NOUVEAU_GEM_INFO           0x44


#define NOUVEAU_GETPARAM_PCI_VENDOR      3
#define NOUVEAU_GETPARAM_PCI_DEVICE      4
#define NOUVEAU_GETPARAM_BUS_TYPE        5
#define NOUVEAU_GETPARAM_FB_SIZE         8
#define NOUVEAU_GETPARAM_AGP_SIZE        9
#define NOUVEAU_GETPARAM_CHIPSET_ID      11
#define NOUVEAU_GETPARAM_VM_VRAM_BASE    12
#define NOUVEAU_GETPARAM_GRAPH_UNITS     13
#define NOUVEAU_GETPARAM_PTIMER_TIME     14
#define NOUVEAU_GETPARAM_HAS_BO_USAGE    15
#define NOUVEAU_GETPARAM_HAS_PAGEFLIP    16

#define NOUVEAU_GETPARAM_EXEC_PUSH_MAX   17
#define NOUVEAU_GETPARAM_VRAM_BAR_SIZE 18
#define NOUVEAU_GETPARAM_VRAM_USED 19
#define NOUVEAU_GETPARAM_HAS_VMA_TILEMODE 20

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/4] gpu: nova-core: Add public driver API to nova-core
  2026-07-06  5:34 ` [PATCH 1/4] gpu: nova-core: Add public driver API to nova-core Alistair Popple
@ 2026-07-06 17:56   ` Danilo Krummrich
  0 siblings, 0 replies; 11+ messages in thread
From: Danilo Krummrich @ 2026-07-06 17:56 UTC (permalink / raw)
  To: Alistair Popple
  Cc: nova-gpu, Alice Ryhl, David Airlie, Alexandre Courbot,
	Benno Lossin, Gary Guo, Eliot Courtney, John Hubbard,
	linux-kernel, dri-devel, rust-for-linux

On Mon Jul 6, 2026 at 7:34 AM CEST, Alistair Popple wrote:
> @@ -86,15 +90,34 @@ fn probe<'bound>(
>                  // (`try_pin_init!()` initializes fields in declaration order), lives at a pinned
>                  // stable address, and is dropped after `gpu` (struct field drop order).
>                  gpu <- Gpu::new(pdev, unsafe { &*core::ptr::from_ref(bar) }),
> -                _reg: auxiliary::Registration::new(
> -                    pdev.as_ref(),
> -                    c"nova-drm",
> -                    // TODO[XARR]: Use XArray or perhaps IDA for proper ID allocation/recycling. For
> -                    // now, use a simple atomic counter that never recycles IDs.
> -                    AUXILIARY_ID_COUNTER.fetch_add(1, Relaxed),
> -                    crate::MODULE_NAME,
> -                    (),
> -                )?,
> +
> +                // SAFETY:
> +                // - `NovaCore` is dropped when the device is unbound; i.e.
> +                //   `mem::forget()` is never called on it.
> +                // - `gpu` is initialized above, lives at a pinned stable
> +                //   address, and is dropped after `_reg` (struct field drop
> +                //   order).
> +                _reg: unsafe {
> +                    auxiliary::Registration::new_with_lt(
> +                        pdev.as_ref(),
> +                        c"nova-drm",
> +                        // TODO[XARR]: Use XArray or perhaps IDA for proper ID allocation/recycling.
> +                        // For now, use a simple atomic counter that never recycles IDs.
> +                        AUXILIARY_ID_COUNTER.fetch_add(1, Relaxed),
> +                        crate::MODULE_NAME,
> +                        NovaCoreApi {
> +                            // TODO: Use `&gpu` self-referential pin-init syntax once available.
> +                            //
> +                            // SAFETY: `gpu` is initialized before this expression is evaluated
> +                            // (`try_pin_init!()` initializes fields in declaration order), lives at
> +                            // a pinned stable address, and is dropped after `_reg` (struct field
> +                            // drop order).
> +                            gpu: Pin::new_unchecked(
> +                                &*core::ptr::from_ref(gpu.as_ref().get_ref()),
> +                            ),

Hm...it's a bit messy to have this justified in two separate places. It would be
better to have separate unsafe blocks for this until pin-init solves this
properly. So, let's just do this.

+                _reg: {
+                    // SAFETY: `gpu` is initialized before this expression is evaluated
+                    // (`try_pin_init!()` initializes fields in declaration order), lives at
+                    // a pinned stable address, and is dropped after `_reg` (struct field
+                    // drop order).
+                    let gpu = unsafe {
+                        Pin::new_unchecked(
+                            &*core::ptr::from_ref(gpu.as_ref().get_ref()),
+                        )
+                    };
+
+                    // SAFETY: `NovaCore` is dropped when the device is unbound; i.e.
+                    // `mem::forget()` is never called on it.
+                    unsafe {
+                        auxiliary::Registration::new_with_lt(
+                            pdev.as_ref(),
+                            c"nova-drm",
+                            // TODO[XARR]: Use XArray or perhaps IDA for proper ID allocation/recycling.
+                            // For now, use a simple atomic counter that never recycles IDs.
+                            AUXILIARY_ID_COUNTER.fetch_add(1, Relaxed),
+                            crate::MODULE_NAME,
+                            NovaCoreApi { gpu },
+                        )?
+                    }
                 },

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/4] gpu: nova: Add DRM registration data
  2026-07-06  5:34 ` [PATCH 2/4] gpu: nova: Add DRM registration data Alistair Popple
@ 2026-07-06 18:01   ` Danilo Krummrich
  0 siblings, 0 replies; 11+ messages in thread
From: Danilo Krummrich @ 2026-07-06 18:01 UTC (permalink / raw)
  To: Alistair Popple
  Cc: nova-gpu, Alice Ryhl, David Airlie, Alexandre Courbot,
	Benno Lossin, Gary Guo, Eliot Courtney, John Hubbard,
	linux-kernel, dri-devel, rust-for-linux

On Mon Jul 6, 2026 at 7:34 AM CEST, Alistair Popple wrote:
> diff --git a/drivers/gpu/drm/nova/file.rs b/drivers/gpu/drm/nova/file.rs
> index 298c02bacb4b..855b6ffe696f 100644
> --- a/drivers/gpu/drm/nova/file.rs
> +++ b/drivers/gpu/drm/nova/file.rs
> @@ -1,11 +1,10 @@
>  // SPDX-License-Identifier: GPL-2.0
>  
> -use crate::driver::{NovaDevice, NovaDriver};
> +use crate::driver::{DrmRegData, NovaDevice, NovaDriver};

Please switch to vertical import style.

>  use crate::gem::NovaObject;
>  use kernel::{
>      alloc::flags::*,
>      auxiliary,
> -    device::Bound,
>      drm::{
>          self,
>          gem::BaseObject,
> @@ -30,12 +29,12 @@ impl File {
>      /// IOCTL: get_param: Query GPU / driver metadata.
>      pub(crate) fn get_param(
>          dev: &NovaDevice<Registered>,
> -        _reg_data: &(),
> +        _reg_data: &DrmRegData<'_>,
>          getparam: &mut uapi::drm_nova_getparam,
>          _file: &drm::File<File>,
>      ) -> Result<u32> {
> -        let adev: &auxiliary::Device<Bound> = dev.as_ref();
> -        let pdev: &pci::Device<Bound> = adev.parent().try_into()?;
> +        let adev: &auxiliary::Device<_> = dev.as_ref();
> +        let pdev: &pci::Device<_> = adev.parent().try_into()?;

Nothing for this patch, but now that we can call into nova-core we can obtain
the information from the pci::Device via NovaCoreApi.

The advantage is that NovaCoreApi can store the pci::Device<Bound> from
nova-core directly, i.e. we get rid of the try_into() dance to obtain the
correct parent device type.

Subsequently, we can remove this TryInto impl entirely. :)

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/4] drm: nova: Add GETPARAM parameter to read the GPU chipset
  2026-07-06  5:34 ` [PATCH 3/4] drm: nova: Add GETPARAM parameter to read the GPU chipset Alistair Popple
  2026-07-06 17:35   ` Timur Tabi
@ 2026-07-06 18:16   ` Danilo Krummrich
  1 sibling, 0 replies; 11+ messages in thread
From: Danilo Krummrich @ 2026-07-06 18:16 UTC (permalink / raw)
  To: Alistair Popple
  Cc: nova-gpu, Alice Ryhl, David Airlie, Alexandre Courbot,
	Benno Lossin, Gary Guo, Eliot Courtney, John Hubbard,
	linux-kernel, dri-devel, rust-for-linux

On Mon Jul 6, 2026 at 7:34 AM CEST, Alistair Popple wrote:
> @@ -31,7 +31,6 @@ pub(crate) struct Nova<'bound> {
>  
>  /// DRM registration data, accessible from ioctl handlers via the registration guard.
>  pub(crate) struct DrmRegData<'bound> {
> -    #[allow(dead_code)]

Forgot to mention that in the previous patch, please use expect instead.

> @@ -12,11 +12,11 @@
>      types::CovariantForLt, //
>  };
>  
> +use crate::gpu::Chipset;
>  use crate::gpu::Gpu;

Vertical import style.

> @@ -25,6 +25,13 @@ extern "C" {
>   */
>  #define NOVA_GETPARAM_VRAM_BAR_SIZE	0x1
>  
> +/*
> + * NOVA_GETPARAM_GPU_CHIPSET
> + *
> + * Query the GPU chipset architecture/implementation.
> + */
> +#define NOVA_GETPARAM_GPU_CHIPSET	0x2

We could provide an enum for the chipset values and use it in the definition of
nova-core's Chipset type, which guarantees a single source of truth.

	define_chipset!({
	    TU102 = uapi::NOVA_CHIPSET_TU102,
	    TU104 = uapi::NOVA_CHIPSET_TU104,
	    // ...
	});

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/4] drm: nova: Add GETPARAM parameter to read the GPU chipset
  2026-07-06 17:35   ` Timur Tabi
@ 2026-07-06 18:24     ` Danilo Krummrich
  0 siblings, 0 replies; 11+ messages in thread
From: Danilo Krummrich @ 2026-07-06 18:24 UTC (permalink / raw)
  To: Timur Tabi
  Cc: Alistair Popple, nova-gpu@lists.linux.dev, John Hubbard,
	gary@garyguo.net, Eliot Courtney, lossin@kernel.org,
	airlied@gmail.com, linux-kernel@vger.kernel.org,
	rust-for-linux@vger.kernel.org, aliceryhl@google.com,
	Alexandre Courbot, dri-devel@lists.freedesktop.org

On Mon Jul 6, 2026 at 7:35 PM CEST, Timur Tabi wrote:
> On Mon, 2026-07-06 at 15:34 +1000, Alistair Popple wrote:
>> @@ -38,6 +38,7 @@ pub(crate) fn get_param(
>>  
>>          let value = match getparam.param as u32 {
>>              uapi::NOVA_GETPARAM_VRAM_BAR_SIZE => pdev.resource_len(1)?,
>> +            uapi::NOVA_GETPARAM_GPU_CHIPSET => reg_data.api.chipset() as u64,
>
> Can we assign these IOCtl values to match Nouveau as much as possible?  I think it would make
> everyone's life easier if we could use the same user-space tools/libraries for Nova that we do for
> Nouveau.

I don't mind using the same numbers where it doesn't matter too much, but for
this to work, it would also require us to retain layout compatibility with
structures, semantics, etc., which I think we should not bother with at all.

Let's build a clean new uAPI, it will get messy over time by itself. :)

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 4/4] drm: nova: Add a GETPARAM parameter to read usable VRAM size
  2026-07-06  5:34 ` [PATCH 4/4] drm: nova: Add a GETPARAM parameter to read usable VRAM size Alistair Popple
@ 2026-07-06 18:26   ` Danilo Krummrich
  0 siblings, 0 replies; 11+ messages in thread
From: Danilo Krummrich @ 2026-07-06 18:26 UTC (permalink / raw)
  To: Alistair Popple
  Cc: nova-gpu, Alice Ryhl, David Airlie, Alexandre Courbot,
	Benno Lossin, Gary Guo, Eliot Courtney, John Hubbard,
	linux-kernel, dri-devel, rust-for-linux

On Mon Jul 6, 2026 at 7:34 AM CEST, Alistair Popple wrote:
> +    /// Returns the total usable VRAM size in bytes, i.e. the summed lengths of all usable FB
> +    /// regions.
> +    pub(crate) fn vram_size(&self) -> u64 {
> +        self.usable_fb_regions
> +            .iter()
> +            .fold(0, |size, region| size.saturating_add(region.end - region.start))
> +    }
>  }

Please make sure to run the rustfmt make target.

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2026-07-06 18:26 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-06  5:34 [PATCH 0/4] gpu: nova: Export parameters from nova-core to nova-drm Alistair Popple
2026-07-06  5:34 ` [PATCH 1/4] gpu: nova-core: Add public driver API to nova-core Alistair Popple
2026-07-06 17:56   ` Danilo Krummrich
2026-07-06  5:34 ` [PATCH 2/4] gpu: nova: Add DRM registration data Alistair Popple
2026-07-06 18:01   ` Danilo Krummrich
2026-07-06  5:34 ` [PATCH 3/4] drm: nova: Add GETPARAM parameter to read the GPU chipset Alistair Popple
2026-07-06 17:35   ` Timur Tabi
2026-07-06 18:24     ` Danilo Krummrich
2026-07-06 18:16   ` Danilo Krummrich
2026-07-06  5:34 ` [PATCH 4/4] drm: nova: Add a GETPARAM parameter to read usable VRAM size Alistair Popple
2026-07-06 18:26   ` Danilo Krummrich

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox