* [PATCH v2 00/12] gpu: nova-core: add PRAMIN window support
@ 2026-08-10 13:55 Eliot Courtney
2026-08-10 13:55 ` [PATCH v2 01/12] rust: num: use const_assert! in Bounded Eliot Courtney
` (13 more replies)
0 siblings, 14 replies; 26+ messages in thread
From: Eliot Courtney @ 2026-08-10 13:55 UTC (permalink / raw)
To: Alexandre Courbot, Yury Norov, Miguel Ojeda, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Onur Özkan, David Airlie, Simona Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, Jonathan Corbet, Shuah Khan
Cc: John Hubbard, Alistair Popple, Timur Tabi, rust-for-linux,
linux-kernel, nova-gpu, dri-devel, linux-doc, Eliot Courtney,
Joel Fernandes
This series adds support for the PRAMIN window, plus some documentation.
Some of these patches were originally written by Joel Fernandes [1]. I
have updated them with changelog notes in each patch. For example, I
updated them for the newer IO machinery from Gary Guo.
This series adds a Pramin structure which deals with updating the PRAMIN
window and handing out typed MMIO views. The PRAMIN window is a method
that lets arbitrary VRAM be written over BAR0 by configuring a 1 MiB
window through GPU registers. That 1 MiB window can point anywhere in
VRAM. This is useful for bootstrapping e.g. GPU side page tables.
The Pramin structure hands out typed MMIO views to do writes through
rather than letting callers write directly through it. A follow up
series will add support for GPU side page table entry writing through
this mechanism. This abstraction is important for later since we will
eventually want to write the PTEs via BAR2 not PRAMIN - using a view
that we grab from the Pramin structure can abstract this out.
[1]: https://lore.kernel.org/all/20260518180342.2387845-1-joelagnelf@nvidia.com/
This is based on drm-rust-next.
Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
---
Changes in v2:
- Rebase onto Gary's IO register projection series
- Drop Region::try_subregion patch in favour of Gary's reg projection
- Convert Pramin code to use Gary's reg projection
- Fix const {assert!} -> const_assert! (Gary)
- Add #[inline] to shr_exact (Sashiko, Alex)
- Link to v1: https://patch.msgid.link/20260805-pramin-split-v1-0-ff3e84a75dac@nvidia.com
---
Eliot Courtney (6):
rust: num: use const_assert! in Bounded
rust: num: reject Bounded::shr overshifts at build time
rust: num: add Bounded::shr_exact
gpu: nova-core: mm: Implement Alignable and Debug for VramAddress
gpu: nova-core: mm: Add the memory management HAL
gpu: nova-core: Add self-test assertion macros and config option
Joel Fernandes (6):
gpu: nova-core: mm: Add VramAddress type
gpu: nova-core: mm: Add PRAMIN window registers
gpu: nova-core: mm: Add support to use PRAMIN windows to write to VRAM
docs: gpu: nova-core: Document the PRAMIN aperture mechanism
gpu: nova-core: mm: Add GpuMm centralized memory manager
gpu: nova-core: mm: Add PRAMIN aperture self-tests
Documentation/gpu/nova/core/pramin.rst | 128 +++++++++++++
Documentation/gpu/nova/index.rst | 1 +
drivers/gpu/nova-core/Kconfig | 9 +
drivers/gpu/nova-core/driver.rs | 3 +
drivers/gpu/nova-core/gpu.rs | 30 ++-
drivers/gpu/nova-core/gsp/commands.rs | 4 +
drivers/gpu/nova-core/gsp/fw/commands.rs | 5 +
drivers/gpu/nova-core/mm.rs | 163 ++++++++++++++++
drivers/gpu/nova-core/mm/hal.rs | 56 ++++++
drivers/gpu/nova-core/mm/hal/gb100.rs | 35 ++++
drivers/gpu/nova-core/mm/hal/gh100.rs | 35 ++++
drivers/gpu/nova-core/mm/hal/tu102.rs | 37 ++++
drivers/gpu/nova-core/mm/pramin.rs | 312 +++++++++++++++++++++++++++++++
drivers/gpu/nova-core/mm/regs.rs | 70 +++++++
drivers/gpu/nova-core/nova_core.rs | 3 +
drivers/gpu/nova-core/selftest.rs | 64 +++++++
rust/kernel/num/bounded.rs | 36 +++-
17 files changed, 988 insertions(+), 3 deletions(-)
---
base-commit: 4c9ba407018e8deb06dbc643112bac8f40404f95
change-id: 20260804-pramin-split-950e210b6e3f
prerequisite-change-id: 20260721-typed_register-176eab3abee7:v2
prerequisite-patch-id: d58e4b8a0fabdeb9363b30f1aa28ca0d42d5190e
prerequisite-patch-id: 5f0c85c6bea0600a4b0bd28b389351e71010a846
prerequisite-patch-id: 8094bc0f51da3764837321c84d71d9c49ac2ac3f
prerequisite-patch-id: cc38839e9c3d9866bd889d89b7e2fdfe609ffc5b
prerequisite-patch-id: 2e919d4f6db02e9d9ed51081a1a803b12f67535f
prerequisite-patch-id: af8a6b3f4bed0953fa8d8f7c1b9e52d746aeb6b2
prerequisite-patch-id: 131291b0a4dc1ee7e43dd038f6f99fc5dc0eb99b
prerequisite-patch-id: 12288c2ebdd58989c5fdabab6237137dd12da566
prerequisite-patch-id: 8224018b7cfec0b00cce46b238abd9f68240e187
prerequisite-patch-id: c7676cbc77ff50b2b7bf13b28c8b7c971285cc9d
prerequisite-patch-id: 1aaed2df7816f907a9403d693be068ddc9a2e43c
prerequisite-patch-id: 04d879d32289f6d715c97ba0cc94b5e94371cc92
prerequisite-patch-id: 127be60ba6331574f6784cc8a5013d4f91b47df4
prerequisite-patch-id: 97fde91d1a5eb35efbbd43e99f595d8bba844cb5
prerequisite-patch-id: 77292e35e0b794e12c0ba7eea16f89c76d899757
prerequisite-patch-id: 95bfd46c2861a2da0179630b02565398d79d55a3
Best regards,
--
Eliot Courtney <ecourtney@nvidia.com>
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH v2 01/12] rust: num: use const_assert! in Bounded
2026-08-10 13:55 [PATCH v2 00/12] gpu: nova-core: add PRAMIN window support Eliot Courtney
@ 2026-08-10 13:55 ` Eliot Courtney
2026-08-10 14:07 ` sashiko-bot
` (2 more replies)
2026-08-10 13:55 ` [PATCH v2 02/12] rust: num: reject Bounded::shr overshifts at build time Eliot Courtney
` (12 subsequent siblings)
13 siblings, 3 replies; 26+ messages in thread
From: Eliot Courtney @ 2026-08-10 13:55 UTC (permalink / raw)
To: Alexandre Courbot, Yury Norov, Miguel Ojeda, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Onur Özkan, David Airlie, Simona Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, Jonathan Corbet, Shuah Khan
Cc: John Hubbard, Alistair Popple, Timur Tabi, rust-for-linux,
linux-kernel, nova-gpu, dri-devel, linux-doc, Eliot Courtney
Convert the const-block asserts in bounded.rs to const_assert!,
matching the rest of the file.
Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
---
rust/kernel/num/bounded.rs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/rust/kernel/num/bounded.rs b/rust/kernel/num/bounded.rs
index dafe77782d79..9ad7df1a243d 100644
--- a/rust/kernel/num/bounded.rs
+++ b/rust/kernel/num/bounded.rs
@@ -485,7 +485,7 @@ pub fn cast<U>(self) -> Bounded<U, N>
/// assert_eq!(v_shifted.get(), 0xff);
/// ```
pub fn shr<const SHIFT: u32, const RES: u32>(self) -> Bounded<T, RES> {
- const { assert!(RES + SHIFT >= N) }
+ const_assert!(RES + SHIFT >= N);
// SAFETY: We shift the value right by `SHIFT`, reducing the number of bits needed to
// represent the shifted value by as much, and just asserted that `RES >= N - SHIFT`.
@@ -506,7 +506,7 @@ pub fn shr<const SHIFT: u32, const RES: u32>(self) -> Bounded<T, RES> {
/// assert_eq!(v_shifted.get(), 0xff00);
/// ```
pub fn shl<const SHIFT: u32, const RES: u32>(self) -> Bounded<T, RES> {
- const { assert!(RES >= N + SHIFT) }
+ const_assert!(RES >= N + SHIFT);
// SAFETY: We shift the value left by `SHIFT`, augmenting the number of bits needed to
// represent the shifted value by as much, and just asserted that `RES >= N + SHIFT`.
--
2.55.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 02/12] rust: num: reject Bounded::shr overshifts at build time
2026-08-10 13:55 [PATCH v2 00/12] gpu: nova-core: add PRAMIN window support Eliot Courtney
2026-08-10 13:55 ` [PATCH v2 01/12] rust: num: use const_assert! in Bounded Eliot Courtney
@ 2026-08-10 13:55 ` Eliot Courtney
2026-08-10 14:23 ` Gary Guo
2026-08-10 22:25 ` Danilo Krummrich
2026-08-10 13:55 ` [PATCH v2 03/12] rust: num: add Bounded::shr_exact Eliot Courtney
` (11 subsequent siblings)
13 siblings, 2 replies; 26+ messages in thread
From: Eliot Courtney @ 2026-08-10 13:55 UTC (permalink / raw)
To: Alexandre Courbot, Yury Norov, Miguel Ojeda, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Onur Özkan, David Airlie, Simona Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, Jonathan Corbet, Shuah Khan
Cc: John Hubbard, Alistair Popple, Timur Tabi, rust-for-linux,
linux-kernel, nova-gpu, dri-devel, linux-doc, Eliot Courtney
Make `shr` reject shifts of at least the type's bit width at build
time, instead of panicking or masking the shift amount at runtime.
Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
Acked-by: Alexandre Courbot <acourbot@nvidia.com>
---
rust/kernel/num/bounded.rs | 1 +
1 file changed, 1 insertion(+)
diff --git a/rust/kernel/num/bounded.rs b/rust/kernel/num/bounded.rs
index 9ad7df1a243d..90483d2c5374 100644
--- a/rust/kernel/num/bounded.rs
+++ b/rust/kernel/num/bounded.rs
@@ -485,6 +485,7 @@ pub fn cast<U>(self) -> Bounded<U, N>
/// assert_eq!(v_shifted.get(), 0xff);
/// ```
pub fn shr<const SHIFT: u32, const RES: u32>(self) -> Bounded<T, RES> {
+ const_assert!(SHIFT < T::BITS);
const_assert!(RES + SHIFT >= N);
// SAFETY: We shift the value right by `SHIFT`, reducing the number of bits needed to
--
2.55.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 03/12] rust: num: add Bounded::shr_exact
2026-08-10 13:55 [PATCH v2 00/12] gpu: nova-core: add PRAMIN window support Eliot Courtney
2026-08-10 13:55 ` [PATCH v2 01/12] rust: num: use const_assert! in Bounded Eliot Courtney
2026-08-10 13:55 ` [PATCH v2 02/12] rust: num: reject Bounded::shr overshifts at build time Eliot Courtney
@ 2026-08-10 13:55 ` Eliot Courtney
2026-08-10 22:25 ` Danilo Krummrich
2026-08-10 13:55 ` [PATCH v2 04/12] gpu: nova-core: mm: Add VramAddress type Eliot Courtney
` (10 subsequent siblings)
13 siblings, 1 reply; 26+ messages in thread
From: Eliot Courtney @ 2026-08-10 13:55 UTC (permalink / raw)
To: Alexandre Courbot, Yury Norov, Miguel Ojeda, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Onur Özkan, David Airlie, Simona Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, Jonathan Corbet, Shuah Khan
Cc: John Hubbard, Alistair Popple, Timur Tabi, rust-for-linux,
linux-kernel, nova-gpu, dri-devel, linux-doc, Eliot Courtney
Add `shr_exact` in the vein of `try_shrink` which shifts a bounded right
only if it loses no set bits. This is useful for getting a shifted down
integer while simultaneously checking that it's aligned.
Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
Acked-by: Alexandre Courbot <acourbot@nvidia.com>
---
rust/kernel/num/bounded.rs | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/rust/kernel/num/bounded.rs b/rust/kernel/num/bounded.rs
index 90483d2c5374..d192610a687d 100644
--- a/rust/kernel/num/bounded.rs
+++ b/rust/kernel/num/bounded.rs
@@ -493,6 +493,37 @@ pub fn shr<const SHIFT: u32, const RES: u32>(self) -> Bounded<T, RES> {
unsafe { Bounded::__new(self.0 >> SHIFT) }
}
+ /// Right-shifts `self` by `SHIFT` if that loses no set bits, and returns the result as a
+ /// `Bounded<_, RES>`, where `RES >= N - SHIFT`.
+ ///
+ /// Returns [`None`] if any of the `SHIFT` least significant bits of `self` is set.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use kernel::num::Bounded;
+ ///
+ /// let v = Bounded::<u32, 16>::new::<0xff00>();
+ /// let v_shifted: Option<Bounded<u32, 8>> = v.shr_exact::<8, _>();
+ ///
+ /// assert_eq!(v_shifted.map(|v| v.get()), Some(0xff));
+ ///
+ /// // A set bit would be shifted out.
+ /// let v = Bounded::<u32, 16>::new::<0xff01>();
+ /// let v_shifted: Option<Bounded<u32, 8>> = v.shr_exact::<8, _>();
+ ///
+ /// assert!(v_shifted.is_none());
+ /// ```
+ #[inline]
+ pub fn shr_exact<const SHIFT: u32, const RES: u32>(self) -> Option<Bounded<T, RES>> {
+ let shifted = self.shr::<SHIFT, RES>();
+ if shifted.get() << SHIFT == self.0 {
+ Some(shifted)
+ } else {
+ None
+ }
+ }
+
/// Left-shifts `self` by `SHIFT` and returns the result as a `Bounded<_, RES>`, where `RES >=
/// N + SHIFT`.
///
--
2.55.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 04/12] gpu: nova-core: mm: Add VramAddress type
2026-08-10 13:55 [PATCH v2 00/12] gpu: nova-core: add PRAMIN window support Eliot Courtney
` (2 preceding siblings ...)
2026-08-10 13:55 ` [PATCH v2 03/12] rust: num: add Bounded::shr_exact Eliot Courtney
@ 2026-08-10 13:55 ` Eliot Courtney
2026-08-10 22:24 ` Danilo Krummrich
2026-08-10 13:55 ` [PATCH v2 05/12] gpu: nova-core: mm: Implement Alignable and Debug for VramAddress Eliot Courtney
` (9 subsequent siblings)
13 siblings, 1 reply; 26+ messages in thread
From: Eliot Courtney @ 2026-08-10 13:55 UTC (permalink / raw)
To: Alexandre Courbot, Yury Norov, Miguel Ojeda, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Onur Özkan, David Airlie, Simona Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, Jonathan Corbet, Shuah Khan
Cc: John Hubbard, Alistair Popple, Timur Tabi, rust-for-linux,
linux-kernel, nova-gpu, dri-devel, linux-doc, Eliot Courtney,
Joel Fernandes
From: Joel Fernandes <joelagnelf@nvidia.com>
Add the `VramAddress` type representing a physical address in VRAM. Also
add an arithmetic helper, comparison, and operator overloads which are
required in later patches for address arithmetic.
Signed-off-by: Joel Fernandes <joelagnelf@nvidia.com>
[ecourtney: create mm.rs here, squashing in the arithmetic patch]
[ecourtney: splice the two commit bodies]
[ecourtney: drop the Pfn fields, open-coding what bitfield! generated]
[ecourtney: drop align_down and the IntoVramOffset/IntoVramRange traits]
[ecourtney: make checked_add() const over a plain u64, derive the ordering]
[ecourtney: doc wording, header, import, and signature cleanups]
Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
---
drivers/gpu/nova-core/mm.rs | 60 ++++++++++++++++++++++++++++++++++++++
drivers/gpu/nova-core/nova_core.rs | 1 +
2 files changed, 61 insertions(+)
diff --git a/drivers/gpu/nova-core/mm.rs b/drivers/gpu/nova-core/mm.rs
new file mode 100644
index 000000000000..dcd5e5e919bf
--- /dev/null
+++ b/drivers/gpu/nova-core/mm.rs
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0
+// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+
+//! Memory management subsystems.
+
+#![expect(dead_code)]
+
+use core::{
+ fmt::LowerHex,
+ ops, //
+};
+
+use kernel::fmt;
+
+/// Physical VRAM address in GPU video memory.
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
+#[repr(transparent)]
+pub(crate) struct VramAddress(u64);
+
+impl VramAddress {
+ /// Creates an address from a raw value.
+ pub(crate) const fn from_raw(addr: u64) -> Self {
+ Self(addr)
+ }
+
+ /// Returns the address as a raw value.
+ pub(crate) const fn into_raw(self) -> u64 {
+ self.0
+ }
+
+ /// Adds `rhs` to this address, returning [`None`] on overflow.
+ pub(crate) const fn checked_add(self, rhs: u64) -> Option<Self> {
+ match self.into_raw().checked_add(rhs) {
+ Some(addr) => Some(Self::from_raw(addr)),
+ None => None,
+ }
+ }
+}
+
+impl LowerHex for VramAddress {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ LowerHex::fmt(&self.into_raw(), f)
+ }
+}
+
+impl ops::Add<u64> for VramAddress {
+ type Output = Self;
+
+ fn add(self, rhs: u64) -> Self::Output {
+ Self::from_raw(self.into_raw() + rhs)
+ }
+}
+
+impl ops::Sub for VramAddress {
+ type Output = u64;
+
+ fn sub(self, rhs: Self) -> Self::Output {
+ self.into_raw() - rhs.into_raw()
+ }
+}
diff --git a/drivers/gpu/nova-core/nova_core.rs b/drivers/gpu/nova-core/nova_core.rs
index 35a8b1214b0e..8f59cfa97017 100644
--- a/drivers/gpu/nova-core/nova_core.rs
+++ b/drivers/gpu/nova-core/nova_core.rs
@@ -18,6 +18,7 @@
mod gpu;
mod gsp;
mod mctp;
+mod mm;
#[macro_use]
mod num;
mod regs;
--
2.55.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 05/12] gpu: nova-core: mm: Implement Alignable and Debug for VramAddress
2026-08-10 13:55 [PATCH v2 00/12] gpu: nova-core: add PRAMIN window support Eliot Courtney
` (3 preceding siblings ...)
2026-08-10 13:55 ` [PATCH v2 04/12] gpu: nova-core: mm: Add VramAddress type Eliot Courtney
@ 2026-08-10 13:55 ` Eliot Courtney
2026-08-10 13:55 ` [PATCH v2 06/12] gpu: nova-core: mm: Add PRAMIN window registers Eliot Courtney
` (8 subsequent siblings)
13 siblings, 0 replies; 26+ messages in thread
From: Eliot Courtney @ 2026-08-10 13:55 UTC (permalink / raw)
To: Alexandre Courbot, Yury Norov, Miguel Ojeda, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Onur Özkan, David Airlie, Simona Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, Jonathan Corbet, Shuah Khan
Cc: John Hubbard, Alistair Popple, Timur Tabi, rust-for-linux,
linux-kernel, nova-gpu, dri-devel, linux-doc, Eliot Courtney
Later patches align VRAM addresses down to the PRAMIN window. Implement
`Alignable` trait for `VramAddress` and plus add a `ZERO` constant.
Also print the address in hex under `{:?}`, so it reads well in debug
output.
Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
---
drivers/gpu/nova-core/mm.rs | 28 +++++++++++++++++++++++++++-
1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/nova-core/mm.rs b/drivers/gpu/nova-core/mm.rs
index dcd5e5e919bf..f9d80ffbe01d 100644
--- a/drivers/gpu/nova-core/mm.rs
+++ b/drivers/gpu/nova-core/mm.rs
@@ -10,7 +10,14 @@
ops, //
};
-use kernel::fmt;
+use kernel::{
+ fmt,
+ prelude::*,
+ ptr::{
+ Alignable,
+ Alignment, //
+ },
+};
/// Physical VRAM address in GPU video memory.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
@@ -18,6 +25,9 @@
pub(crate) struct VramAddress(u64);
impl VramAddress {
+ /// The zero address.
+ pub(crate) const ZERO: Self = Self::from_raw(0);
+
/// Creates an address from a raw value.
pub(crate) const fn from_raw(addr: u64) -> Self {
Self(addr)
@@ -37,12 +47,28 @@ pub(crate) const fn checked_add(self, rhs: u64) -> Option<Self> {
}
}
+impl Alignable for VramAddress {
+ fn align_down(self, alignment: Alignment) -> Self {
+ Self::from_raw(self.into_raw().align_down(alignment))
+ }
+
+ fn align_up(self, alignment: Alignment) -> Option<Self> {
+ self.into_raw().align_up(alignment).map(Self::from_raw)
+ }
+}
+
impl LowerHex for VramAddress {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
LowerHex::fmt(&self.into_raw(), f)
}
}
+impl fmt::Debug for VramAddress {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.write_fmt(fmt!("{:#x}", self))
+ }
+}
+
impl ops::Add<u64> for VramAddress {
type Output = Self;
--
2.55.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 06/12] gpu: nova-core: mm: Add PRAMIN window registers
2026-08-10 13:55 [PATCH v2 00/12] gpu: nova-core: add PRAMIN window support Eliot Courtney
` (4 preceding siblings ...)
2026-08-10 13:55 ` [PATCH v2 05/12] gpu: nova-core: mm: Implement Alignable and Debug for VramAddress Eliot Courtney
@ 2026-08-10 13:55 ` Eliot Courtney
2026-08-10 13:55 ` [PATCH v2 07/12] gpu: nova-core: mm: Add the memory management HAL Eliot Courtney
` (7 subsequent siblings)
13 siblings, 0 replies; 26+ messages in thread
From: Eliot Courtney @ 2026-08-10 13:55 UTC (permalink / raw)
To: Alexandre Courbot, Yury Norov, Miguel Ojeda, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Onur Özkan, David Airlie, Simona Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, Jonathan Corbet, Shuah Khan
Cc: John Hubbard, Alistair Popple, Timur Tabi, rust-for-linux,
linux-kernel, nova-gpu, dri-devel, linux-doc, Eliot Courtney,
Joel Fernandes
From: Joel Fernandes <joelagnelf@nvidia.com>
PRAMIN apertures are a crucial mechanism for direct CPU read/write to
VRAM. Add the BAR0 window registers that position the PRAMIN aperture
on all supported GPU architectures: Turing, Ampere, Ada (via
`NV_PBUS_BAR0_WINDOW`), Hopper (via `gh100::NV_XAL_EP_BAR0_WINDOW`),
and Blackwell (via `gb100::NV_XAL_EP_BAR0_WINDOW`).
Hopper/Blackwell window-base registers are based on Eliot Courtney's
offlist reference patch.
Signed-off-by: Joel Fernandes <joelagnelf@nvidia.com>
[ecourtney: split the registers out of the PRAMIN patch into mm/regs.rs]
[ecourtney: drop the register read path]
[ecourtney: reword the message for the split, narrow visibility to mm]
[ecourtney: plain base fields, as the bitfield cast+shift patch is dropped]
[ecourtney: rename the target to VidMem, fix derives, redo the target docs]
[ecourtney: annotate the register base types]
Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
---
drivers/gpu/nova-core/mm.rs | 2 ++
drivers/gpu/nova-core/mm/regs.rs | 70 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 72 insertions(+)
diff --git a/drivers/gpu/nova-core/mm.rs b/drivers/gpu/nova-core/mm.rs
index f9d80ffbe01d..7d24ad790310 100644
--- a/drivers/gpu/nova-core/mm.rs
+++ b/drivers/gpu/nova-core/mm.rs
@@ -19,6 +19,8 @@
},
};
+mod regs;
+
/// Physical VRAM address in GPU video memory.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
#[repr(transparent)]
diff --git a/drivers/gpu/nova-core/mm/regs.rs b/drivers/gpu/nova-core/mm/regs.rs
new file mode 100644
index 000000000000..82de6dfa4e8b
--- /dev/null
+++ b/drivers/gpu/nova-core/mm/regs.rs
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: GPL-2.0
+// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+
+//! Registers used by the memory management subsystems: the BAR0 PRAMIN window.
+
+use kernel::io::register;
+
+use crate::{
+ bounded_enum,
+ driver::NovaRegisters, //
+};
+
+// PRAMIN window
+
+bounded_enum! {
+ /// Target memory type for the BAR0 window register.
+ ///
+ /// Only VRAM is needed by the driver. Pre-Hopper window registers also define
+ /// system-memory targets that are unused here; Hopper+ uses a separate register
+ /// without a target field.
+ #[derive(Debug, Copy, Clone)]
+ pub(super) enum Bar0WindowTarget with TryFrom<Bounded<u32, 2>> {
+ /// Video memory (GPU framebuffer memory).
+ VidMem = 0,
+ }
+}
+
+register! {
+ base: NovaRegisters;
+
+ /// BAR0 window control for PRAMIN access.
+ pub(super) NV_PBUS_BAR0_WINDOW(u32) @ 0x00001700 {
+ /// Target memory aperture for the window.
+ 25:24 target ?=> Bar0WindowTarget;
+ /// PRAMIN window base bits 39:16.
+ 23:0 base;
+ }
+}
+
+pub(super) mod gh100 {
+ use kernel::io::register;
+
+ use crate::driver::NovaRegisters;
+
+ register! {
+ base: NovaRegisters;
+
+ /// Hopper register for PRAMIN window.
+ pub(crate) NV_XAL_EP_BAR0_WINDOW(u32) @ 0x0010fd40 {
+ /// PRAMIN window base bits 37:16.
+ 21:0 base;
+ }
+ }
+}
+
+pub(super) mod gb100 {
+ use kernel::io::register;
+
+ use crate::driver::NovaRegisters;
+
+ register! {
+ base: NovaRegisters;
+
+ /// Blackwell GB10x/GB20x register for PRAMIN window.
+ pub(crate) NV_XAL_EP_BAR0_WINDOW(u32) @ 0x0010fd40 {
+ /// PRAMIN window base bits 38:16.
+ 22:0 base;
+ }
+ }
+}
--
2.55.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 07/12] gpu: nova-core: mm: Add the memory management HAL
2026-08-10 13:55 [PATCH v2 00/12] gpu: nova-core: add PRAMIN window support Eliot Courtney
` (5 preceding siblings ...)
2026-08-10 13:55 ` [PATCH v2 06/12] gpu: nova-core: mm: Add PRAMIN window registers Eliot Courtney
@ 2026-08-10 13:55 ` Eliot Courtney
2026-08-10 13:55 ` [PATCH v2 08/12] gpu: nova-core: mm: Add support to use PRAMIN windows to write to VRAM Eliot Courtney
` (6 subsequent siblings)
13 siblings, 0 replies; 26+ messages in thread
From: Eliot Courtney @ 2026-08-10 13:55 UTC (permalink / raw)
To: Alexandre Courbot, Yury Norov, Miguel Ojeda, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Onur Özkan, David Airlie, Simona Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, Jonathan Corbet, Shuah Khan
Cc: John Hubbard, Alistair Popple, Timur Tabi, rust-for-linux,
linux-kernel, nova-gpu, dri-devel, linux-doc, Eliot Courtney
Positioning the PRAMIN window requires writing an architecture-specific
register: `NV_PBUS_BAR0_WINDOW` on Turing, Ampere and Ada, and
`NV_XAL_EP_BAR0_WINDOW` with a different field width on Hopper and on
Blackwell.
A `MmHal` trait with one implementation per hardware family hides the
register choice from the rest of the mm code, matching the layout of
the driver's other HALs.
Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
---
drivers/gpu/nova-core/mm.rs | 1 +
drivers/gpu/nova-core/mm/hal.rs | 56 +++++++++++++++++++++++++++++++++++
drivers/gpu/nova-core/mm/hal/gb100.rs | 35 ++++++++++++++++++++++
drivers/gpu/nova-core/mm/hal/gh100.rs | 35 ++++++++++++++++++++++
drivers/gpu/nova-core/mm/hal/tu102.rs | 37 +++++++++++++++++++++++
5 files changed, 164 insertions(+)
diff --git a/drivers/gpu/nova-core/mm.rs b/drivers/gpu/nova-core/mm.rs
index 7d24ad790310..07dce4ce2473 100644
--- a/drivers/gpu/nova-core/mm.rs
+++ b/drivers/gpu/nova-core/mm.rs
@@ -19,6 +19,7 @@
},
};
+mod hal;
mod regs;
/// Physical VRAM address in GPU video memory.
diff --git a/drivers/gpu/nova-core/mm/hal.rs b/drivers/gpu/nova-core/mm/hal.rs
new file mode 100644
index 000000000000..e7fd1e38bd38
--- /dev/null
+++ b/drivers/gpu/nova-core/mm/hal.rs
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0
+// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+
+//! Memory management HAL.
+
+use kernel::{
+ num::Bounded,
+ prelude::*, //
+};
+
+use crate::{
+ driver::Bar0,
+ gpu::{
+ Architecture,
+ Chipset, //
+ },
+ mm::VramAddress, //
+};
+
+mod gb100;
+mod gh100;
+mod tu102;
+
+/// Trait implemented by per-architecture MM HALs.
+///
+/// `Sync` is required so that the `&'static dyn MmHal` references can be stored in `Send`
+/// structures.
+pub(super) trait MmHal: Sync {
+ /// Positions the PRAMIN window at `base`.
+ ///
+ /// This fails if `base` is not aligned to the 64 KiB window alignment or is too large for
+ /// the receiving register.
+ fn write_pramin_window_base(&self, bar: Bar0<'_>, base: VramAddress) -> Result;
+}
+
+/// Returns the HAL corresponding to `chipset`.
+pub(super) fn mm_hal(chipset: Chipset) -> &'static dyn MmHal {
+ match chipset.arch() {
+ Architecture::Turing | Architecture::Ampere | Architecture::Ada => tu102::TU102_HAL,
+ Architecture::Hopper => gh100::GH100_HAL,
+ Architecture::BlackwellGB10x | Architecture::BlackwellGB20x => gb100::GB100_HAL,
+ }
+}
+
+/// Converts `base` into the value of the window-base register field.
+///
+/// Fails with [`EINVAL`] if `base` is not aligned to the window alignment required by the register
+/// field's shift, or if the shifted value does not fit within `RES` bits.
+fn window_base<const RES: u32>(base: VramAddress) -> Result<Bounded<u64, RES>> {
+ const WINDOW_BASE_SHIFT: u32 = 16;
+
+ Bounded::<u64, 64>::from(base.into_raw())
+ .shr_exact::<WINDOW_BASE_SHIFT, { 64 - WINDOW_BASE_SHIFT }>()
+ .and_then(Bounded::try_shrink)
+ .ok_or(EINVAL)
+}
diff --git a/drivers/gpu/nova-core/mm/hal/gb100.rs b/drivers/gpu/nova-core/mm/hal/gb100.rs
new file mode 100644
index 000000000000..3781e143dea7
--- /dev/null
+++ b/drivers/gpu/nova-core/mm/hal/gb100.rs
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0
+// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+
+//! Blackwell GB10x/GB20x memory management HAL.
+
+use kernel::{
+ io::Io,
+ prelude::*, //
+};
+
+use crate::{
+ driver::Bar0,
+ mm::{
+ hal::{
+ window_base,
+ MmHal, //
+ },
+ regs,
+ VramAddress, //
+ },
+};
+
+struct Gb100;
+
+impl MmHal for Gb100 {
+ fn write_pramin_window_base(&self, bar: Bar0<'_>, base: VramAddress) -> Result {
+ bar.write_reg(
+ regs::gb100::NV_XAL_EP_BAR0_WINDOW::zeroed().with_base(window_base(base)?.cast()),
+ );
+ Ok(())
+ }
+}
+
+const GB100: Gb100 = Gb100;
+pub(super) const GB100_HAL: &dyn MmHal = &GB100;
diff --git a/drivers/gpu/nova-core/mm/hal/gh100.rs b/drivers/gpu/nova-core/mm/hal/gh100.rs
new file mode 100644
index 000000000000..8af384db2921
--- /dev/null
+++ b/drivers/gpu/nova-core/mm/hal/gh100.rs
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0
+// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+
+//! Hopper memory management HAL.
+
+use kernel::{
+ io::Io,
+ prelude::*, //
+};
+
+use crate::{
+ driver::Bar0,
+ mm::{
+ hal::{
+ window_base,
+ MmHal, //
+ },
+ regs,
+ VramAddress, //
+ },
+};
+
+struct Gh100;
+
+impl MmHal for Gh100 {
+ fn write_pramin_window_base(&self, bar: Bar0<'_>, base: VramAddress) -> Result {
+ bar.write_reg(
+ regs::gh100::NV_XAL_EP_BAR0_WINDOW::zeroed().with_base(window_base(base)?.cast()),
+ );
+ Ok(())
+ }
+}
+
+const GH100: Gh100 = Gh100;
+pub(super) const GH100_HAL: &dyn MmHal = &GH100;
diff --git a/drivers/gpu/nova-core/mm/hal/tu102.rs b/drivers/gpu/nova-core/mm/hal/tu102.rs
new file mode 100644
index 000000000000..e4fe7561223c
--- /dev/null
+++ b/drivers/gpu/nova-core/mm/hal/tu102.rs
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0
+// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+
+//! Turing, Ampere and Ada memory management HAL.
+
+use kernel::{
+ io::Io,
+ prelude::*, //
+};
+
+use crate::{
+ driver::Bar0,
+ mm::{
+ hal::{
+ window_base,
+ MmHal, //
+ },
+ regs,
+ VramAddress, //
+ },
+};
+
+struct Tu102;
+
+impl MmHal for Tu102 {
+ fn write_pramin_window_base(&self, bar: Bar0<'_>, base: VramAddress) -> Result {
+ bar.write_reg(
+ regs::NV_PBUS_BAR0_WINDOW::zeroed()
+ .with_target(regs::Bar0WindowTarget::VidMem)
+ .with_base(window_base(base)?.cast()),
+ );
+ Ok(())
+ }
+}
+
+const TU102: Tu102 = Tu102;
+pub(super) const TU102_HAL: &dyn MmHal = &TU102;
--
2.55.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 08/12] gpu: nova-core: mm: Add support to use PRAMIN windows to write to VRAM
2026-08-10 13:55 [PATCH v2 00/12] gpu: nova-core: add PRAMIN window support Eliot Courtney
` (6 preceding siblings ...)
2026-08-10 13:55 ` [PATCH v2 07/12] gpu: nova-core: mm: Add the memory management HAL Eliot Courtney
@ 2026-08-10 13:55 ` Eliot Courtney
2026-08-10 13:55 ` [PATCH v2 09/12] docs: gpu: nova-core: Document the PRAMIN aperture mechanism Eliot Courtney
` (5 subsequent siblings)
13 siblings, 0 replies; 26+ messages in thread
From: Eliot Courtney @ 2026-08-10 13:55 UTC (permalink / raw)
To: Alexandre Courbot, Yury Norov, Miguel Ojeda, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Onur Özkan, David Airlie, Simona Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, Jonathan Corbet, Shuah Khan
Cc: John Hubbard, Alistair Popple, Timur Tabi, rust-for-linux,
linux-kernel, nova-gpu, dri-devel, linux-doc, Eliot Courtney,
Joel Fernandes
From: Joel Fernandes <joelagnelf@nvidia.com>
PRAMIN apertures are a crucial mechanism for direct CPU read/write to
VRAM. Add a `Pramin` manager whose `window_at()` returns a typed MMIO
view of VRAM through the 1 MiB PRAMIN aperture in BAR0, validating the
view against the VRAM region and repositioning the window as needed for
the accessed address.
A view borrows `Pramin` mutably, so the window cannot move while
the view is in use, and it inserts an ordering point on Drop.
Signed-off-by: Joel Fernandes <joelagnelf@nvidia.com>
[ecourtney: split the registers and HAL into the two preceding patches]
[ecourtney: rebase w.r.t. Bar0 lifetime changes and register projections]
[ecourtney: drop the window guard and mutex, use &mut self]
[ecourtney: position at init to avoid reads, reposition in window_offset]
[ecourtney: return typed MMIO views instead of read/write accessors]
[ecourtney: insert an ordering read when a view drops]
[ecourtney: declare the window location, drop the doc examples]
[ecourtney: add the copyright header, doc and naming cleanups]
[ecourtney: the pramin module is mm-internal]
Co-developed-by: Eliot Courtney <ecourtney@nvidia.com>
Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
---
drivers/gpu/nova-core/mm.rs | 1 +
drivers/gpu/nova-core/mm/pramin.rs | 178 +++++++++++++++++++++++++++++++++++++
2 files changed, 179 insertions(+)
diff --git a/drivers/gpu/nova-core/mm.rs b/drivers/gpu/nova-core/mm.rs
index 07dce4ce2473..ef5b1cad56c3 100644
--- a/drivers/gpu/nova-core/mm.rs
+++ b/drivers/gpu/nova-core/mm.rs
@@ -20,6 +20,7 @@
};
mod hal;
+mod pramin;
mod regs;
/// Physical VRAM address in GPU video memory.
diff --git a/drivers/gpu/nova-core/mm/pramin.rs b/drivers/gpu/nova-core/mm/pramin.rs
new file mode 100644
index 000000000000..20be3fc471ba
--- /dev/null
+++ b/drivers/gpu/nova-core/mm/pramin.rs
@@ -0,0 +1,178 @@
+// SPDX-License-Identifier: GPL-2.0
+// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+
+//! Utilities for accessing VRAM through the PRAMIN window.
+
+use core::ops::Range;
+
+use kernel::{
+ io::{
+ io_project,
+ register,
+ register::OffsetLoc,
+ Io,
+ Mmio, //
+ },
+ prelude::*,
+ ptr::{
+ Alignable,
+ Alignment, //
+ },
+ sizes::{
+ SZ_1M,
+ SZ_64K, //
+ },
+};
+
+use crate::{
+ driver::{
+ Bar0,
+ NovaRegisters, //
+ },
+ gpu::Chipset,
+ mm::{
+ hal::{
+ self,
+ MmHal, //
+ },
+ VramAddress, //
+ },
+ num::IntoSafeCast, //
+};
+
+/// Size of the PRAMIN window (1 MiB).
+const WINDOW_SIZE: usize = SZ_1M;
+
+/// The PRAMIN window, which is a 1 MiB window into VRAM at a fixed BAR0 offset.
+#[derive(FromBytes, IntoBytes)]
+struct PraminWindow([u8; WINDOW_SIZE]);
+
+register! {
+ base: NovaRegisters;
+
+ /// Location of the window inside BAR0.
+ PRAMIN: PraminWindow @ 0x700000;
+}
+
+/// Owner of the PRAMIN window state.
+///
+/// [`Pramin::window_at()`] repositions the window as needed and returns a typed MMIO view into
+/// it, holding the manager borrowed for the lifetime of the view.
+pub(super) struct Pramin<'gpu> {
+ bar: Bar0<'gpu>,
+ hal: &'static dyn MmHal,
+ /// MMIO view of the PRAMIN window in BAR0.
+ window: Mmio<'gpu, PraminWindow>,
+ /// VRAM range to keep the PRAMIN window inside.
+ vram_range: Range<VramAddress>,
+ /// Cached window position.
+ window_range: Range<VramAddress>,
+}
+
+/// Typed view of VRAM through the PRAMIN window.
+///
+/// Inserts an ordering point after previous writes through the window on drop. Views returned
+/// by [`PraminAccess::view()`] cannot outlive this access, so the ordering point covers every
+/// write made through them.
+pub(super) struct PraminAccess<'a, T>
+where
+ T: FromBytes + IntoBytes,
+{
+ view: Mmio<'a, T>,
+}
+
+impl<T> PraminAccess<'_, T>
+where
+ T: FromBytes + IntoBytes,
+{
+ /// Returns the MMIO view of the accessed location.
+ pub(super) fn view(&self) -> Mmio<'_, T> {
+ self.view
+ }
+}
+
+impl<T> Drop for PraminAccess<'_, T>
+where
+ T: FromBytes + IntoBytes,
+{
+ fn drop(&mut self) {
+ // Insert an ordering point after previous writes through this window.
+ self.view.cast::<u8>().read_val();
+ }
+}
+
+impl<'gpu> Pramin<'gpu> {
+ /// Alignment required by the PRAMIN window.
+ const BASE_ALIGN: Alignment = Alignment::new::<SZ_64K>();
+
+ /// Creates the window manager for the given VRAM region.
+ pub(super) fn new(
+ bar: Bar0<'gpu>,
+ chipset: Chipset,
+ vram_range: Range<VramAddress>,
+ ) -> Result<Self> {
+ let hal = hal::mm_hal(chipset);
+ let window = io_project!(bar, build: PRAMIN);
+ let base = vram_range.start.align_down(Self::BASE_ALIGN);
+ let window_range = Self::window_range(base)?;
+ hal.write_pramin_window_base(bar, base)?;
+
+ Ok(Self {
+ bar,
+ hal,
+ window,
+ vram_range,
+ window_range,
+ })
+ }
+
+ /// Returns the VRAM range a window based at `base` exposes.
+ fn window_range(base: VramAddress) -> Result<Range<VramAddress>> {
+ let end = base
+ .checked_add(WINDOW_SIZE.into_safe_cast())
+ .ok_or(EINVAL)?;
+ Ok(base..end)
+ }
+
+ /// Check the window covers `len` bytes at `addr`, moving it if needed.
+ ///
+ /// Returns the window offset at which to perform the access.
+ fn window_offset(&mut self, addr: VramAddress, len: usize) -> Result<usize> {
+ let end = addr.checked_add(len.into_safe_cast()).ok_or(EINVAL)?;
+
+ let inside = |r: &Range<VramAddress>| r.contains(&addr) && end <= r.end;
+ if !inside(&self.vram_range) {
+ return Err(EINVAL);
+ }
+
+ // Reposition the window if the access falls outside it.
+ if !inside(&self.window_range) {
+ let base = addr.align_down(Self::BASE_ALIGN);
+ let window_range = Self::window_range(base)?;
+ if !inside(&window_range) {
+ return Err(EINVAL);
+ }
+ self.hal.write_pramin_window_base(self.bar, base)?;
+ self.window_range = window_range;
+ }
+
+ Ok((addr - self.window_range.start).into_safe_cast())
+ }
+
+ /// Return a typed MMIO view of a `T` at `vram_addr`.
+ ///
+ /// Returns an error if `vram_addr` is not aligned to `T`'s alignment, or if
+ /// a `T` at `vram_addr` does not fit within the VRAM region.
+ pub(super) fn window_at<'a, T>(
+ &'a mut self,
+ vram_addr: VramAddress,
+ ) -> Result<PraminAccess<'a, T>>
+ where
+ T: FromBytes + IntoBytes,
+ {
+ let offset = self.window_offset(vram_addr, size_of::<T>())?;
+ let view = io_project!(self.window, try: OffsetLoc::new(offset));
+
+ Ok(PraminAccess { view })
+ }
+}
--
2.55.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 09/12] docs: gpu: nova-core: Document the PRAMIN aperture mechanism
2026-08-10 13:55 [PATCH v2 00/12] gpu: nova-core: add PRAMIN window support Eliot Courtney
` (7 preceding siblings ...)
2026-08-10 13:55 ` [PATCH v2 08/12] gpu: nova-core: mm: Add support to use PRAMIN windows to write to VRAM Eliot Courtney
@ 2026-08-10 13:55 ` Eliot Courtney
2026-08-10 13:55 ` [PATCH v2 10/12] gpu: nova-core: mm: Add GpuMm centralized memory manager Eliot Courtney
` (4 subsequent siblings)
13 siblings, 0 replies; 26+ messages in thread
From: Eliot Courtney @ 2026-08-10 13:55 UTC (permalink / raw)
To: Alexandre Courbot, Yury Norov, Miguel Ojeda, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Onur Özkan, David Airlie, Simona Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, Jonathan Corbet, Shuah Khan
Cc: John Hubbard, Alistair Popple, Timur Tabi, rust-for-linux,
linux-kernel, nova-gpu, dri-devel, linux-doc, Eliot Courtney,
Joel Fernandes
From: Joel Fernandes <joelagnelf@nvidia.com>
Add documentation for the PRAMIN aperture mechanism used by nova-core
for direct VRAM access.
Nova only uses TARGET=VRAM for VRAM access. The SYS_MEM target values
are documented for completeness but not used by the driver.
Signed-off-by: Joel Fernandes <joelagnelf@nvidia.com>
[ecourtney: fix the TARGET encodings, KiB/MiB units, wording nits]
[ecourtney: wrap at 80 columns]
Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
---
Documentation/gpu/nova/core/pramin.rst | 128 +++++++++++++++++++++++++++++++++
Documentation/gpu/nova/index.rst | 1 +
2 files changed, 129 insertions(+)
diff --git a/Documentation/gpu/nova/core/pramin.rst b/Documentation/gpu/nova/core/pramin.rst
new file mode 100644
index 000000000000..f50b052d73ba
--- /dev/null
+++ b/Documentation/gpu/nova/core/pramin.rst
@@ -0,0 +1,128 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=========================
+PRAMIN aperture mechanism
+=========================
+
+.. note::
+ The following description is approximate and current as of the Ampere
+ family. It may change for future generations and is intended to assist in
+ understanding the driver code.
+
+Introduction
+============
+
+PRAMIN is a hardware aperture mechanism that provides CPU access to GPU Video
+RAM (VRAM) before the GPU's Memory Management Unit (MMU) and page tables are
+initialized. This 1 MiB sliding window, located at a fixed offset within BAR0,
+is essential for setting up page tables and other critical GPU data structures
+without relying on the GPU's MMU.
+
+Architecture Overview
+=====================
+
+The PRAMIN aperture mechanism is logically implemented by the GPU's PBUS (PCIe
+Bus Controller Unit) and provides a CPU-accessible window into VRAM through the
+PCIe interface::
+
+ +-----------------+ PCIe +------------------------------+
+ | CPU |<----------->| GPU |
+ +-----------------+ | |
+ | +----------------------+ |
+ | | PBUS | |
+ | | (Bus Controller) | |
+ | | | |
+ | | +--------------+ <------------ [1]
+ | | | PRAMIN | | |
+ | | | Window | | |
+ | | | (1 MiB) | | |
+ | | +--------------+ | |
+ | | | | |
+ | +---------|------------+ |
+ | | |
+ | v |
+ | +----------------------+ <------- [2]
+ | | VRAM | |
+ | | (Several GiB) | |
+ | | | |
+ | | FB[0x0000000000] | |
+ | | ... | |
+ | | FB[0xFFFFFFFFFF] | |
+ | +----------------------+ |
+ +------------------------------+
+
+ [1] Window starts at BAR0 + 0x700000.
+ [2] Program PRAMIN to any 64 KiB-aligned VRAM boundary.
+
+PBUS is responsible for, among other things, handling MMIO
+accesses to the BAR registers.
+
+PRAMIN Window Operation
+=======================
+
+The PRAMIN window provides a 1 MiB sliding aperture that can be repositioned
+over the entire VRAM address space using the ``NV_PBUS_BAR0_WINDOW`` register.
+
+Window Control Mechanism
+-------------------------
+
+::
+
+ NV_PBUS_BAR0_WINDOW Register (0x1700):
+ +-------+--------+--------------------------------------+
+ | 31:26 | 25:24 | 23:0 |
+ | RSVD | TARGET | BASE_ADDR |
+ | | | (bits 39:16 of VRAM address) |
+ +-------+--------+--------------------------------------+
+
+ The 24-bit BASE_ADDR field encodes bits [39:16] of the target VRAM address,
+ providing 40-bit (1 TiB) address space coverage with 64 KiB alignment.
+
+ TARGET field (bits 25:24):
+ - 0x0: VRAM (Video Memory)
+ - 0x1: Reserved (unused)
+ - 0x2: SYS_MEM_COH (Coherent System Memory)
+ - 0x3: SYS_MEM_NONCOH (Non-coherent System Memory)
+
+.. note::
+ Nova only uses TARGET=VRAM (0x0) for video memory access. The SYS_MEM
+ target values are documented here for hardware completeness but are
+ not used by the driver.
+
+64 KiB Alignment Requirement
+----------------------------
+
+The PRAMIN window must be aligned to 64 KiB boundaries in VRAM. This is enforced
+by the ``BASE_ADDR`` field representing bits [39:16] of the target address::
+
+ VRAM Address Calculation:
+ actual_vram_addr = (BASE_ADDR << 16) + pramin_offset
+ Where:
+ - BASE_ADDR: 24-bit value from NV_PBUS_BAR0_WINDOW[23:0]
+ - pramin_offset: 20-bit offset within the PRAMIN window [0x00000-0xFFFFF]
+
+ Example Window Positioning:
+ +---------------------------------------------------------+
+ | VRAM Space |
+ | |
+ | 0x0000000000 +-----------------+ <-- 64 KiB aligned |
+ | | PRAMIN Window | |
+ | | (1 MiB) | |
+ | 0x00000FFFFF +-----------------+ |
+ | |
+ | | ^ |
+ | | | Window can slide |
+ | v | to any 64 KiB-aligned boundary |
+ | |
+ | 0x0123400000 +-----------------+ <-- 64 KiB aligned |
+ | | PRAMIN Window | |
+ | | (1 MiB) | |
+ | 0x01234FFFFF +-----------------+ |
+ | |
+ | ... |
+ | |
+ | 0xFFFFF00000 +-----------------+ <-- 64 KiB aligned |
+ | | PRAMIN Window | |
+ | | (1 MiB) | |
+ | 0xFFFFFFFFFF +-----------------+ |
+ +---------------------------------------------------------+
diff --git a/Documentation/gpu/nova/index.rst b/Documentation/gpu/nova/index.rst
index 2afa58e8f08d..59b206238498 100644
--- a/Documentation/gpu/nova/index.rst
+++ b/Documentation/gpu/nova/index.rst
@@ -34,3 +34,4 @@ vGPU manager VFIO driver and the nova-drm driver.
core/fwsec
core/falcon
core/tlv
+ core/pramin
--
2.55.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 10/12] gpu: nova-core: mm: Add GpuMm centralized memory manager
2026-08-10 13:55 [PATCH v2 00/12] gpu: nova-core: add PRAMIN window support Eliot Courtney
` (8 preceding siblings ...)
2026-08-10 13:55 ` [PATCH v2 09/12] docs: gpu: nova-core: Document the PRAMIN aperture mechanism Eliot Courtney
@ 2026-08-10 13:55 ` Eliot Courtney
2026-08-10 14:09 ` sashiko-bot
2026-08-10 13:55 ` [PATCH v2 11/12] gpu: nova-core: Add self-test assertion macros and config option Eliot Courtney
` (3 subsequent siblings)
13 siblings, 1 reply; 26+ messages in thread
From: Eliot Courtney @ 2026-08-10 13:55 UTC (permalink / raw)
To: Alexandre Courbot, Yury Norov, Miguel Ojeda, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Onur Özkan, David Airlie, Simona Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, Jonathan Corbet, Shuah Khan
Cc: John Hubbard, Alistair Popple, Timur Tabi, rust-for-linux,
linux-kernel, nova-gpu, dri-devel, linux-doc, Eliot Courtney,
Joel Fernandes
From: Joel Fernandes <joelagnelf@nvidia.com>
Introduce GpuMm as the centralized GPU memory manager. At this point in
the series, GpuMm only owns the PRAMIN window for direct VRAM access;
the buddy allocator and TLB manager are added later when those backing
types become available.
This provides a clean ownership model where GpuMm provides accessor
methods for its components that can be used for memory management
operations, and lets follow-on patches (such as the PRAMIN aperture
self-tests) reference `pramin_mut()` cleanly.
Signed-off-by: Joel Fernandes <joelagnelf@nvidia.com>
[ecourtney: squash the total VRAM end patch, drop its dev_info print]
[ecourtney: take the maximum FB limit before adding one, fail with EINVAL]
[ecourtney: rebase for the Bar0 lifetime and ownership changes, drop Arcs]
[ecourtney: source the chipset through gsp_resources]
[ecourtney: build the VRAM region in new(), pramin() becomes pramin_mut()]
[ecourtney: declare mm before gsp_resources, doc wording cleanups]
Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
---
drivers/gpu/nova-core/gpu.rs | 18 +++++++++++++++-
drivers/gpu/nova-core/gsp/commands.rs | 4 ++++
drivers/gpu/nova-core/gsp/fw/commands.rs | 5 +++++
drivers/gpu/nova-core/mm.rs | 35 ++++++++++++++++++++++++++++++++
4 files changed, 61 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
index 42a4cd7971fa..e29e07488e78 100644
--- a/drivers/gpu/nova-core/gpu.rs
+++ b/drivers/gpu/nova-core/gpu.rs
@@ -29,6 +29,10 @@
Gsp,
GspBootContext, //
},
+ mm::{
+ GpuMm,
+ VramAddress, //
+ },
regs,
vgpu::VgpuManager, //
};
@@ -283,6 +287,11 @@ pub(crate) struct Gpu<'gpu> {
spec: Spec,
/// Static GPU information as provided by the GSP.
gsp_static_info: GetGspStaticInfoReply,
+ /// GPU memory manager owning memory management resources.
+ ///
+ /// Must be kept declared *before* `gsp_resources`, so that its components are dropped while
+ /// the GSP is still operational.
+ mm: GpuMm<'gpu>,
/// GSP and its resources.
#[pin]
gsp_resources: GspResources<'gpu>,
@@ -410,7 +419,14 @@ pub(crate) fn new(
}
info
- }
+ },
+
+ // Create GPU memory manager owning memory management resources.
+ mm: GpuMm::new(
+ bar,
+ gsp_resources.spec.chipset,
+ VramAddress::from_raw(gsp_static_info.total_fb_end),
+ )?,
})
}
}
diff --git a/drivers/gpu/nova-core/gsp/commands.rs b/drivers/gpu/nova-core/gsp/commands.rs
index ffc25fd8c47b..eea1c9ed4684 100644
--- a/drivers/gpu/nova-core/gsp/commands.rs
+++ b/drivers/gpu/nova-core/gsp/commands.rs
@@ -216,6 +216,8 @@ pub(crate) struct GetGspStaticInfoReply {
gpu_name: [u8; 64],
/// Usable FB (VRAM) regions for driver memory allocation.
pub(crate) usable_fb_regions: KVec<Range<u64>>,
+ /// Exclusive end of the FB physical address space.
+ pub(crate) total_fb_end: u64,
}
impl MessageFromGsp for GetGspStaticInfoReply {
@@ -231,10 +233,12 @@ fn read(
for region in msg.usable_fb_regions() {
usable_fb_regions.push(region, GFP_KERNEL)?;
}
+ let total_fb_end = msg.total_fb_end().ok_or(EINVAL)?;
Ok(GetGspStaticInfoReply {
gpu_name: msg.gpu_name_str(),
usable_fb_regions,
+ total_fb_end,
})
}
}
diff --git a/drivers/gpu/nova-core/gsp/fw/commands.rs b/drivers/gpu/nova-core/gsp/fw/commands.rs
index 6dc31d1bf5ae..6e85442a4b13 100644
--- a/drivers/gpu/nova-core/gsp/fw/commands.rs
+++ b/drivers/gpu/nova-core/gsp/fw/commands.rs
@@ -165,6 +165,11 @@ pub(crate) fn usable_fb_regions(&self) -> impl Iterator<Item = Range<u64>> + '_
}
})
}
+
+ /// Computes the exclusive end of the FB physical address space.
+ pub(crate) fn total_fb_end(&self) -> Option<u64> {
+ self.fb_regions().map(|reg| reg.limit).max()?.checked_add(1)
+ }
}
// SAFETY: Padding is explicit and will not contain uninitialized data.
diff --git a/drivers/gpu/nova-core/mm.rs b/drivers/gpu/nova-core/mm.rs
index ef5b1cad56c3..58dce211a337 100644
--- a/drivers/gpu/nova-core/mm.rs
+++ b/drivers/gpu/nova-core/mm.rs
@@ -19,10 +19,45 @@
},
};
+use crate::{
+ driver::Bar0,
+ gpu::Chipset, //
+};
+
mod hal;
mod pramin;
mod regs;
+/// GPU Memory Manager - owns all core MM components.
+///
+/// Provides centralized ownership of memory management resources:
+/// - [`pramin::Pramin`] for direct VRAM access.
+pub(crate) struct GpuMm<'gpu> {
+ pramin: pramin::Pramin<'gpu>,
+}
+
+impl<'gpu> GpuMm<'gpu> {
+ /// Creates the GPU memory manager.
+ pub(crate) fn new(
+ bar: Bar0<'gpu>,
+ chipset: Chipset,
+ total_fb_end: VramAddress,
+ ) -> Result<Self> {
+ // PRAMIN covers all physical VRAM (including GSP-reserved areas
+ // above the usable region, e.g. the BAR1 page directory).
+ let vram_region = VramAddress::ZERO..total_fb_end;
+
+ Ok(Self {
+ pramin: pramin::Pramin::new(bar, chipset, vram_region)?,
+ })
+ }
+
+ /// Access the [`pramin::Pramin`].
+ fn pramin_mut(&mut self) -> &mut pramin::Pramin<'gpu> {
+ &mut self.pramin
+ }
+}
+
/// Physical VRAM address in GPU video memory.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
#[repr(transparent)]
--
2.55.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 11/12] gpu: nova-core: Add self-test assertion macros and config option
2026-08-10 13:55 [PATCH v2 00/12] gpu: nova-core: add PRAMIN window support Eliot Courtney
` (9 preceding siblings ...)
2026-08-10 13:55 ` [PATCH v2 10/12] gpu: nova-core: mm: Add GpuMm centralized memory manager Eliot Courtney
@ 2026-08-10 13:55 ` Eliot Courtney
2026-08-10 14:09 ` sashiko-bot
2026-08-10 13:55 ` [PATCH v2 12/12] gpu: nova-core: mm: Add PRAMIN aperture self-tests Eliot Courtney
` (2 subsequent siblings)
13 siblings, 1 reply; 26+ messages in thread
From: Eliot Courtney @ 2026-08-10 13:55 UTC (permalink / raw)
To: Alexandre Courbot, Yury Norov, Miguel Ojeda, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Onur Özkan, David Airlie, Simona Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, Jonathan Corbet, Shuah Khan
Cc: John Hubbard, Alistair Popple, Timur Tabi, rust-for-linux,
linux-kernel, nova-gpu, dri-devel, linux-doc, Eliot Courtney
The existing assert! and assert_eq! macros cause a panic. For self tests
in nova-core, it's inconvenient to cause a panic since these need to be
run on actual hardware. Instead, define similar macros that log an error
then return an Err.
Also add the NOVA_CORE_SELFTESTS Kconfig option that gates the driver
self-tests.
Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
---
drivers/gpu/nova-core/Kconfig | 9 ++++++
drivers/gpu/nova-core/nova_core.rs | 2 ++
drivers/gpu/nova-core/selftest.rs | 64 ++++++++++++++++++++++++++++++++++++++
3 files changed, 75 insertions(+)
diff --git a/drivers/gpu/nova-core/Kconfig b/drivers/gpu/nova-core/Kconfig
index f918f69e0599..cb7f0b00f796 100644
--- a/drivers/gpu/nova-core/Kconfig
+++ b/drivers/gpu/nova-core/Kconfig
@@ -15,3 +15,12 @@ config NOVA_CORE
This driver is work in progress and may not be functional.
If M is selected, the module will be called nova-core.
+
+config NOVA_CORE_SELFTESTS
+ bool "Nova Core driver self-tests"
+ depends on NOVA_CORE
+ default n
+ help
+ Build the driver self-tests and run them when the GPU is probed.
+
+ If unsure, say N.
diff --git a/drivers/gpu/nova-core/nova_core.rs b/drivers/gpu/nova-core/nova_core.rs
index 8f59cfa97017..1133c6ce5c55 100644
--- a/drivers/gpu/nova-core/nova_core.rs
+++ b/drivers/gpu/nova-core/nova_core.rs
@@ -23,6 +23,8 @@
mod num;
mod regs;
mod sbuffer;
+#[cfg(CONFIG_NOVA_CORE_SELFTESTS)]
+mod selftest;
mod vbios;
mod vgpu;
diff --git a/drivers/gpu/nova-core/selftest.rs b/drivers/gpu/nova-core/selftest.rs
new file mode 100644
index 000000000000..f5b5965b7e6a
--- /dev/null
+++ b/drivers/gpu/nova-core/selftest.rs
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0
+// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+
+//! Assertion macros for driver self-tests.
+//!
+//! Self-tests run against live hardware during probe, so a failed assertion should not panic. These
+//! macros log the failure on the device and fail the enclosing test by returning
+//! [`EIO`](kernel::error::code::EIO) instead.
+
+/// Like [`assert!`], but logs the failure via `dev` and fails the enclosing test instead of
+/// panicking.
+///
+/// As with [`assert!`], a custom message with format arguments can follow the condition.
+#[macro_export]
+macro_rules! selftest_assert {
+ ($dev:expr, $cond:expr $(,)?) => {
+ $crate::selftest_assert!($dev, $cond, "assertion failed: {}", ::core::stringify!($cond))
+ };
+ ($dev:expr, $cond:expr, $($arg:tt)+) => {{
+ if !$cond {
+ ::kernel::dev_err!(
+ $dev,
+ "Selftest: {}:{}: {}\n",
+ ::core::file!(),
+ ::core::line!(),
+ ::kernel::prelude::fmt!($($arg)+)
+ );
+ return Err(::kernel::error::code::EIO);
+ }
+ }};
+}
+
+/// Like [`assert_eq!`], but logs the failure via `dev` and fails the enclosing test instead of
+/// panicking.
+///
+/// As with [`assert_eq!`], a custom message with format arguments can follow the compared values.
+#[macro_export]
+macro_rules! selftest_assert_eq {
+ ($dev:expr, $left:expr, $right:expr $(,)?) => {
+ match (&$left, &$right) {
+ (left, right) => $crate::selftest_assert!(
+ $dev,
+ left == right,
+ "assertion `{} == {}` failed: left {:?}, right {:?}",
+ ::core::stringify!($left),
+ ::core::stringify!($right),
+ left,
+ right
+ ),
+ }
+ };
+ ($dev:expr, $left:expr, $right:expr, $($arg:tt)+) => {
+ match (&$left, &$right) {
+ (left, right) => $crate::selftest_assert!(
+ $dev,
+ left == right,
+ "assertion `left == right` failed: {}: left {:?}, right {:?}",
+ ::kernel::prelude::fmt!($($arg)+),
+ left,
+ right
+ ),
+ }
+ };
+}
--
2.55.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 12/12] gpu: nova-core: mm: Add PRAMIN aperture self-tests
2026-08-10 13:55 [PATCH v2 00/12] gpu: nova-core: add PRAMIN window support Eliot Courtney
` (10 preceding siblings ...)
2026-08-10 13:55 ` [PATCH v2 11/12] gpu: nova-core: Add self-test assertion macros and config option Eliot Courtney
@ 2026-08-10 13:55 ` Eliot Courtney
2026-08-10 14:16 ` sashiko-bot
2026-08-10 22:26 ` [PATCH v2 00/12] gpu: nova-core: add PRAMIN window support Danilo Krummrich
2026-08-11 12:31 ` Miguel Ojeda
13 siblings, 1 reply; 26+ messages in thread
From: Eliot Courtney @ 2026-08-10 13:55 UTC (permalink / raw)
To: Alexandre Courbot, Yury Norov, Miguel Ojeda, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Onur Özkan, David Airlie, Simona Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, Jonathan Corbet, Shuah Khan
Cc: John Hubbard, Alistair Popple, Timur Tabi, rust-for-linux,
linux-kernel, nova-gpu, dri-devel, linux-doc, Eliot Courtney,
Joel Fernandes
From: Joel Fernandes <joelagnelf@nvidia.com>
Add self-tests for the PRAMIN aperture mechanism to verify correct
operation during GPU probe. The tests validate various alignment
requirements and corner cases.
The tests are default disabled and behind CONFIG_NOVA_CORE_SELFTESTS.
When enabled, tests run after GSP boot during probe.
Signed-off-by: Joel Fernandes <joelagnelf@nvidia.com>
[ecourtney: convert the tests to window_at(), macros, and the new types]
[ecourtney: cfg-gate the tests and expect(dead_code), not a runtime no-op]
[ecourtney: run the self-tests on all architectures, drop the chipset arg]
[ecourtney: test within a usable FB region, skip when none is large enough]
[ecourtney: report failures without failing probe, start banner at dev_dbg]
[ecourtney: removed the mm-specific Kconfig option]
Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
---
drivers/gpu/nova-core/driver.rs | 3 +
drivers/gpu/nova-core/gpu.rs | 12 ++++
drivers/gpu/nova-core/mm.rs | 40 ++++++++++-
drivers/gpu/nova-core/mm/pramin.rs | 134 +++++++++++++++++++++++++++++++++++++
4 files changed, 188 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/nova-core/driver.rs b/drivers/gpu/nova-core/driver.rs
index eddd5e7aeec8..f012bea2b5bf 100644
--- a/drivers/gpu/nova-core/driver.rs
+++ b/drivers/gpu/nova-core/driver.rs
@@ -87,6 +87,9 @@ 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) }),
+ // Run optional GPU selftests.
+ #[cfg(CONFIG_NOVA_CORE_SELFTESTS)]
+ _: { gpu.run_selftests(pdev) },
_reg: auxiliary::Registration::new(
pdev.as_ref(),
c"nova-drm",
diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
index e29e07488e78..04e1e30eeed7 100644
--- a/drivers/gpu/nova-core/gpu.rs
+++ b/drivers/gpu/nova-core/gpu.rs
@@ -429,4 +429,16 @@ pub(crate) fn new(
)?,
})
}
+
+ /// Runs self-tests on the constructed [`Gpu`], logging failures without failing probe.
+ #[cfg(CONFIG_NOVA_CORE_SELFTESTS)]
+ pub(crate) fn run_selftests(self: Pin<&mut Self>, pdev: &pci::Device<device::Bound>) {
+ let this = self.project();
+ let dev = pdev.as_ref();
+ let regions = &this.gsp_static_info.usable_fb_regions;
+
+ if let Err(err) = crate::mm::selftest::run(dev, this.mm, regions) {
+ dev_err!(dev, "self-tests failed: {:?}\n", err);
+ }
+ }
}
diff --git a/drivers/gpu/nova-core/mm.rs b/drivers/gpu/nova-core/mm.rs
index 58dce211a337..9e4338c7c393 100644
--- a/drivers/gpu/nova-core/mm.rs
+++ b/drivers/gpu/nova-core/mm.rs
@@ -3,7 +3,7 @@
//! Memory management subsystems.
-#![expect(dead_code)]
+#![cfg_attr(not(CONFIG_NOVA_CORE_SELFTESTS), expect(dead_code))]
use core::{
fmt::LowerHex,
@@ -123,3 +123,41 @@ fn sub(self, rhs: Self) -> Self::Output {
self.into_raw() - rhs.into_raw()
}
}
+
+#[cfg(CONFIG_NOVA_CORE_SELFTESTS)]
+pub(crate) mod selftest {
+ use core::ops::Range;
+
+ use kernel::{
+ device,
+ sizes::SizeConstants, //
+ };
+
+ use super::*;
+
+ /// Run MM subsystem self-tests during probe.
+ pub(crate) fn run(
+ dev: &device::Device<device::Bound>,
+ mm: &mut GpuMm<'_>,
+ usable_fb_regions: &[Range<u64>],
+ ) -> Result {
+ // VRAM span the self-tests are free to overwrite, from the chosen test base.
+ const SELFTEST_SPAN: u64 = u64::SZ_64M;
+
+ let base = usable_fb_regions.iter().find_map(|region| {
+ // Tests rely on this being 8 byte aligned for checking misalignment handling.
+ let base = region.start.align_up(Alignment::new::<8>())?;
+ (base.checked_add(SELFTEST_SPAN)? <= region.end).then_some(base)
+ });
+ let Some(base) = base else {
+ dev_warn!(
+ dev,
+ "PRAMIN: skipping self-tests, no usable VRAM region of {:#x} bytes\n",
+ SELFTEST_SPAN
+ );
+ return Ok(());
+ };
+
+ pramin::selftest::run(dev, mm.pramin_mut(), VramAddress::from_raw(base))
+ }
+}
diff --git a/drivers/gpu/nova-core/mm/pramin.rs b/drivers/gpu/nova-core/mm/pramin.rs
index 20be3fc471ba..7f89c093d591 100644
--- a/drivers/gpu/nova-core/mm/pramin.rs
+++ b/drivers/gpu/nova-core/mm/pramin.rs
@@ -176,3 +176,137 @@ pub(super) fn window_at<'a, T>(
Ok(PraminAccess { view })
}
}
+
+#[cfg(CONFIG_NOVA_CORE_SELFTESTS)]
+pub(super) mod selftest {
+ use kernel::{
+ device,
+ io::io_read,
+ sizes::SizeConstants, //
+ };
+
+ use super::*;
+ use crate::{
+ selftest_assert,
+ selftest_assert_eq, //
+ };
+
+ /// Test read/write at byte granularity, at unaligned addresses.
+ fn test_byte_readwrite(
+ dev: &device::Device<device::Bound>,
+ pramin: &mut Pramin<'_>,
+ base: VramAddress,
+ ) -> Result {
+ for i in 0u8..4 {
+ let addr = base + 1 + u64::from(i);
+ pramin.window_at::<u8>(addr)?.view().write_val(0xA0 + i);
+ }
+
+ for i in 0u8..4 {
+ let addr = base + 1 + u64::from(i);
+ selftest_assert_eq!(
+ dev,
+ pramin.window_at::<u8>(addr)?.view().read_val(),
+ 0xA0 + i
+ );
+ }
+ Ok(())
+ }
+
+ /// Test writing a `u32` and reading back as individual `u8`s.
+ fn test_u32_as_bytes(
+ dev: &device::Device<device::Bound>,
+ pramin: &mut Pramin<'_>,
+ base: VramAddress,
+ ) -> Result {
+ let addr = base + 0x10;
+ let val: u32 = 0xDEADBEEF;
+ pramin.window_at::<u32>(addr)?.view().write_val(val);
+
+ let window = pramin.window_at::<[u8; 4]>(addr)?;
+ for (i, &expected) in val.to_le_bytes().iter().enumerate() {
+ selftest_assert_eq!(dev, io_read!(window.view(), [build: i]), expected);
+ }
+ Ok(())
+ }
+
+ /// Test window repositioning across 1 MiB boundaries.
+ fn test_window_reposition(
+ dev: &device::Device<device::Bound>,
+ pramin: &mut Pramin<'_>,
+ base: VramAddress,
+ ) -> Result {
+ let addr_a = base;
+ let addr_b = base + u64::SZ_2M; // base + 2 MiB (different 1 MiB region).
+ let val_a: u32 = 0x11111111;
+ let val_b: u32 = 0x22222222;
+
+ pramin.window_at::<u32>(addr_a)?.view().write_val(val_a);
+ pramin.window_at::<u32>(addr_b)?.view().write_val(val_b);
+
+ selftest_assert_eq!(
+ dev,
+ pramin.window_at::<u32>(addr_a)?.view().read_val(),
+ val_a
+ );
+ selftest_assert_eq!(
+ dev,
+ pramin.window_at::<u32>(addr_b)?.view().read_val(),
+ val_b
+ );
+ Ok(())
+ }
+
+ /// Test that offsets outside the VRAM region are rejected.
+ fn test_invalid_offset(
+ dev: &device::Device<device::Bound>,
+ pramin: &mut Pramin<'_>,
+ vram_end: VramAddress,
+ ) -> Result {
+ selftest_assert!(dev, pramin.window_at::<u32>(vram_end).is_err());
+ Ok(())
+ }
+
+ /// Test that misaligned accesses are rejected.
+ fn test_misaligned_access(
+ dev: &device::Device<device::Bound>,
+ pramin: &mut Pramin<'_>,
+ base: VramAddress,
+ ) -> Result {
+ // `u16` at odd offset (not 2-byte aligned).
+ selftest_assert!(dev, pramin.window_at::<u16>(base + 0x21).is_err());
+
+ // `u32` at 2-byte-aligned (not 4-byte-aligned) offset.
+ selftest_assert!(dev, pramin.window_at::<u32>(base + 2).is_err());
+
+ // `u64` at a 4-byte-aligned (not 8-byte-aligned) address.
+ selftest_assert!(dev, pramin.window_at::<u64>(base + 0x44).is_err());
+
+ // A `u16` view at an even address is allowed.
+ pramin.window_at::<u16>(base + 0x22)?;
+ Ok(())
+ }
+
+ /// Run PRAMIN self-tests during probe.
+ ///
+ /// `base` is the start of a driver-usable VRAM span that the tests are free to
+ /// overwrite.
+ pub(crate) fn run(
+ dev: &device::Device<device::Bound>,
+ pramin: &mut Pramin<'_>,
+ base: VramAddress,
+ ) -> Result {
+ dev_dbg!(dev, "PRAMIN: starting self-tests\n");
+
+ let vram_end = pramin.vram_range.end;
+
+ test_byte_readwrite(dev, pramin, base)?;
+ test_u32_as_bytes(dev, pramin, base)?;
+ test_window_reposition(dev, pramin, base)?;
+ test_invalid_offset(dev, pramin, vram_end)?;
+ test_misaligned_access(dev, pramin, base)?;
+
+ dev_info!(dev, "PRAMIN: self-tests passed\n");
+ Ok(())
+ }
+}
--
2.55.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH v2 01/12] rust: num: use const_assert! in Bounded
2026-08-10 13:55 ` [PATCH v2 01/12] rust: num: use const_assert! in Bounded Eliot Courtney
@ 2026-08-10 14:07 ` sashiko-bot
2026-08-10 14:23 ` Gary Guo
2026-08-10 22:24 ` Danilo Krummrich
2 siblings, 0 replies; 26+ messages in thread
From: sashiko-bot @ 2026-08-10 14:07 UTC (permalink / raw)
To: Eliot Courtney; +Cc: Danilo Krummrich, ojeda, dri-devel, Alexandre Courbot
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [Critical] This problem wasn't introduced by this patch, but Bounded::shr lacks a bound check for SHIFT < T::BITS, allowing wrapping shifts that break safety invariants and lead to Undefined Behavior.
--
--- Patch [1]: [PATCH v2 01/12] rust: num: use const_assert! in Bounded ---
commit afcfa782abd748c8cc818867c320e813e00f8278
Author: Eliot Courtney <ecourtney@nvidia.com>
rust: num: use const_assert! in Bounded
This patch converts the const-block asserts in bounded.rs to use the
const_assert! macro, matching the styling in the rest of the file.
> diff --git a/rust/kernel/num/bounded.rs b/rust/kernel/num/bounded.rs
> index dafe77782d797..9ad7df1a243d9 100644
> --- a/rust/kernel/num/bounded.rs
> +++ b/rust/kernel/num/bounded.rs
> @@ -485,7 +485,7 @@ pub fn cast<U>(self) -> Bounded<U, N>
> /// assert_eq!(v_shifted.get(), 0xff);
> /// ```
> pub fn shr<const SHIFT: u32, const RES: u32>(self) -> Bounded<T, RES> {
> - const { assert!(RES + SHIFT >= N) }
> + const_assert!(RES + SHIFT >= N);
[Severity: Critical]
This isn't a bug introduced by this patch, but does Bounded::shr lack a
bounds check for SHIFT being less than the number of bits in the type?
If a caller invokes Bounded::shr with a SHIFT value greater than or equal to
the bit width of the type, the shift amount can be masked in release builds
without overflow checks. This would leave the original value unchanged.
Because the condition RES + SHIFT >= N would still be satisfied, this
unchanged value is unsafely wrapped in the returned Bounded type. If the
value exceeds RES bits, it breaks the safety invariant of the struct.
Subsequent safe calls like Bounded::cast could then trigger undefined
behavior when encountering unwrap_unchecked on a failed try_from conversion.
Could we add an additional bounds check here to prevent wrapping shifts?
>
> // SAFETY: We shift the value right by `SHIFT`, reducing the number of bits needed to
> // represent the shifted value by as much, and just asserted that `RES >= N - SHIFT`.
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260810-pramin-split-v2-0-65a00b3c7309@nvidia.com?part=1
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 10/12] gpu: nova-core: mm: Add GpuMm centralized memory manager
2026-08-10 13:55 ` [PATCH v2 10/12] gpu: nova-core: mm: Add GpuMm centralized memory manager Eliot Courtney
@ 2026-08-10 14:09 ` sashiko-bot
0 siblings, 0 replies; 26+ messages in thread
From: sashiko-bot @ 2026-08-10 14:09 UTC (permalink / raw)
To: Eliot Courtney; +Cc: Danilo Krummrich, Alexandre Courbot, ojeda, dri-devel
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The `pramin_mut` method in `GpuMm` is missing the `pub(crate)` visibility modifier, despite the commit message claiming it is exposed for follow-on patches.
--
--- Patch [10]: [PATCH v2 10/12] gpu: nova-core: mm: Add GpuMm centralized memory manager ---
commit 454fed327c5dab971b01225656d96fa09a0fc921
Author: Joel Fernandes <joelagnelf@nvidia.com>
gpu: nova-core: mm: Add GpuMm centralized memory manager
Introduce GpuMm as the centralized GPU memory manager. At this point in
the series, GpuMm only owns the PRAMIN window for direct VRAM access. This
provides a clean ownership model where GpuMm provides accessor methods for
its components.
> diff --git a/drivers/gpu/nova-core/mm.rs b/drivers/gpu/nova-core/mm.rs
> index ef5b1cad56c31..58dce211a3373 100644
> --- a/drivers/gpu/nova-core/mm.rs
> +++ b/drivers/gpu/nova-core/mm.rs
[ ... ]
> +
> + /// Access the [`pramin::Pramin`].
> + fn pramin_mut(&mut self) -> &mut pramin::Pramin<'gpu> {
> + &mut self.pramin
> + }
> +}
[Severity: Medium]
The commit message mentions this provides accessor methods so that follow-on
patches can reference pramin_mut() cleanly. However, GpuMm::pramin_mut() is
defined without the pub(crate) visibility modifier, making it strictly private
to the mm module.
Will this prevent cross-subsystem access from gpu.rs or external tests as
intended by the commit message?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260810-pramin-split-v2-0-65a00b3c7309@nvidia.com?part=10
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 11/12] gpu: nova-core: Add self-test assertion macros and config option
2026-08-10 13:55 ` [PATCH v2 11/12] gpu: nova-core: Add self-test assertion macros and config option Eliot Courtney
@ 2026-08-10 14:09 ` sashiko-bot
0 siblings, 0 replies; 26+ messages in thread
From: sashiko-bot @ 2026-08-10 14:09 UTC (permalink / raw)
To: Eliot Courtney; +Cc: Alexandre Courbot, dri-devel, Danilo Krummrich, ojeda
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The `$dev` expression in `selftest_assert!` is conditionally evaluated only when the assertion fails, which can lead to inconsistent side effects.
--
--- Patch [11]: [PATCH v2 11/12] gpu: nova-core: Add self-test assertion macros and config option ---
commit 205e1404103e41ca5c6fd34482ac0f24c1d05216
Author: Eliot Courtney <ecourtney@nvidia.com>
gpu: nova-core: Add self-test assertion macros and config option
The existing assert! and assert_eq! macros cause a panic. For self tests
in nova-core, it's inconvenient to cause a panic since these need to be
run on actual hardware. Instead, define similar macros that log an error
then return an Err.
> diff --git a/drivers/gpu/nova-core/selftest.rs b/drivers/gpu/nova-core/selftest.rs
> new file mode 100644
> index 0000000000000..f5b5965b7e6ad
> --- /dev/null
> +++ b/drivers/gpu/nova-core/selftest.rs
[ ... ]
> @@ -0,0 +1,64 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
[ ... ]
> +#[macro_export]
> +macro_rules! selftest_assert {
> + ($dev:expr, $cond:expr $(,)?) => {
> + $crate::selftest_assert!($dev, $cond, "assertion failed: {}", ::core::stringify!($cond))
> + };
> + ($dev:expr, $cond:expr, $($arg:tt)+) => {{
> + if !$cond {
> + ::kernel::dev_err!(
> + $dev,
[Severity: Low]
Could this lead to inconsistent side effects if the $dev expression contains
them?
Since $dev is only evaluated inside the if !$cond block, any side effects in
the expression passed as $dev will only occur on the error path when the
assertion fails. They will be skipped on the happy path.
Would it be safer to evaluate $dev outside the condition, for instance by
binding it to a local variable like let dev = $dev; before the check?
> + "Selftest: {}:{}: {}\n",
> + ::core::file!(),
> + ::core::line!(),
> + ::kernel::prelude::fmt!($($arg)+)
> + );
> + return Err(::kernel::error::code::EIO);
> + }
> + }};
> +}
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260810-pramin-split-v2-0-65a00b3c7309@nvidia.com?part=11
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 12/12] gpu: nova-core: mm: Add PRAMIN aperture self-tests
2026-08-10 13:55 ` [PATCH v2 12/12] gpu: nova-core: mm: Add PRAMIN aperture self-tests Eliot Courtney
@ 2026-08-10 14:16 ` sashiko-bot
0 siblings, 0 replies; 26+ messages in thread
From: sashiko-bot @ 2026-08-10 14:16 UTC (permalink / raw)
To: Eliot Courtney; +Cc: ojeda, dri-devel, Danilo Krummrich, Alexandre Courbot
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The `io_read!` macro invocation uses a runtime loop variable `i` with the `[build: i]` syntax, which relies on the optimizer to eliminate the bounds check and may cause a build failure.
--
--- Patch [12]: [PATCH v2 12/12] gpu: nova-core: mm: Add PRAMIN aperture self-tests ---
commit e3c26c738212001e40a3ab7fef15d2c8cf5421b5
Author: Joel Fernandes <joelagnelf@nvidia.com>
gpu: nova-core: mm: Add PRAMIN aperture self-tests
This commit adds self-tests for the PRAMIN aperture mechanism to verify
correct operation, alignment requirements, and corner cases during GPU probe.
The tests are default disabled and gated behind CONFIG_NOVA_CORE_SELFTESTS.
> diff --git a/drivers/gpu/nova-core/mm/pramin.rs b/drivers/gpu/nova-core/mm/pramin.rs
> --- a/drivers/gpu/nova-core/mm/pramin.rs
> +++ b/drivers/gpu/nova-core/mm/pramin.rs
[ ... ]
> + fn test_u32_as_bytes(
> + dev: &device::Device<device::Bound>,
> + pramin: &mut Pramin<'_>,
> + base: VramAddress,
> + ) -> Result {
> + let addr = base + 0x10;
> + let val: u32 = 0xDEADBEEF;
> + pramin.window_at::<u32>(addr)?.view().write_val(val);
> +
> + let window = pramin.window_at::<[u8; 4]>(addr)?;
> + for (i, &expected) in val.to_le_bytes().iter().enumerate() {
> + selftest_assert_eq!(dev, io_read!(window.view(), [build: i]), expected);
[Severity: Low]
Will this cause a link-time build failure if the optimizer does not unroll
the loop?
The io_read! macro invocation in test_u32_as_bytes uses the runtime loop
variable i with the [build: i] syntax. This relies on LLVM optimization
heuristics to unroll the loop and resolve the value statically at build
time.
If the compiler fails to unroll this loop, the code will retain a call to
rust_build_error, which results in an undefined symbol linker error unless
CONFIG_RUST_BUILD_ASSERT_ALLOW is explicitly enabled.
Should this be rewritten to manually unroll the four reads, or use a
runtime index rather than [build: i]?
> + }
> + Ok(())
> + }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260810-pramin-split-v2-0-65a00b3c7309@nvidia.com?part=12
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 01/12] rust: num: use const_assert! in Bounded
2026-08-10 13:55 ` [PATCH v2 01/12] rust: num: use const_assert! in Bounded Eliot Courtney
2026-08-10 14:07 ` sashiko-bot
@ 2026-08-10 14:23 ` Gary Guo
2026-08-10 22:24 ` Danilo Krummrich
2 siblings, 0 replies; 26+ messages in thread
From: Gary Guo @ 2026-08-10 14:23 UTC (permalink / raw)
To: Eliot Courtney, Alexandre Courbot, Yury Norov, Miguel Ojeda,
Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich,
Daniel Almeida, Tamir Duberstein, Onur Özkan, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Jonathan Corbet, Shuah Khan
Cc: John Hubbard, Alistair Popple, Timur Tabi, rust-for-linux,
linux-kernel, nova-gpu, dri-devel, linux-doc
On Mon Aug 10, 2026 at 2:55 PM BST, Eliot Courtney wrote:
> Convert the const-block asserts in bounded.rs to const_assert!,
> matching the rest of the file.
>
> Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
> ---
> rust/kernel/num/bounded.rs | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 02/12] rust: num: reject Bounded::shr overshifts at build time
2026-08-10 13:55 ` [PATCH v2 02/12] rust: num: reject Bounded::shr overshifts at build time Eliot Courtney
@ 2026-08-10 14:23 ` Gary Guo
2026-08-10 22:25 ` Danilo Krummrich
1 sibling, 0 replies; 26+ messages in thread
From: Gary Guo @ 2026-08-10 14:23 UTC (permalink / raw)
To: Eliot Courtney, Alexandre Courbot, Yury Norov, Miguel Ojeda,
Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich,
Daniel Almeida, Tamir Duberstein, Onur Özkan, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Jonathan Corbet, Shuah Khan
Cc: John Hubbard, Alistair Popple, Timur Tabi, rust-for-linux,
linux-kernel, nova-gpu, dri-devel, linux-doc
On Mon Aug 10, 2026 at 2:55 PM BST, Eliot Courtney wrote:
> Make `shr` reject shifts of at least the type's bit width at build
> time, instead of panicking or masking the shift amount at runtime.
>
> Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
> Acked-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
> ---
> rust/kernel/num/bounded.rs | 1 +
> 1 file changed, 1 insertion(+)
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 04/12] gpu: nova-core: mm: Add VramAddress type
2026-08-10 13:55 ` [PATCH v2 04/12] gpu: nova-core: mm: Add VramAddress type Eliot Courtney
@ 2026-08-10 22:24 ` Danilo Krummrich
0 siblings, 0 replies; 26+ messages in thread
From: Danilo Krummrich @ 2026-08-10 22:24 UTC (permalink / raw)
To: Eliot Courtney
Cc: Alexandre Courbot, Yury Norov, Miguel Ojeda, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Daniel Almeida, Tamir Duberstein, Onur Özkan,
David Airlie, Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Jonathan Corbet, Shuah Khan, John Hubbard,
Alistair Popple, Timur Tabi, rust-for-linux, linux-kernel,
nova-gpu, dri-devel, linux-doc, Joel Fernandes
On Mon Aug 10, 2026 at 3:55 PM CEST, Eliot Courtney wrote:
> +/// Physical VRAM address in GPU video memory.
> +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
> +#[repr(transparent)]
> +pub(crate) struct VramAddress(u64);
Let's move this into generic code, maybe rust/kernel/gpu/types.rs? I wouldn't
mind doing this as a follow-up though. Will go over the rest of the series soon.
Thanks,
Danilo
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 01/12] rust: num: use const_assert! in Bounded
2026-08-10 13:55 ` [PATCH v2 01/12] rust: num: use const_assert! in Bounded Eliot Courtney
2026-08-10 14:07 ` sashiko-bot
2026-08-10 14:23 ` Gary Guo
@ 2026-08-10 22:24 ` Danilo Krummrich
2 siblings, 0 replies; 26+ messages in thread
From: Danilo Krummrich @ 2026-08-10 22:24 UTC (permalink / raw)
To: Eliot Courtney
Cc: Alexandre Courbot, Yury Norov, Miguel Ojeda, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Daniel Almeida, Tamir Duberstein, Onur Özkan,
David Airlie, Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Jonathan Corbet, Shuah Khan, John Hubbard,
Alistair Popple, Timur Tabi, rust-for-linux, linux-kernel,
nova-gpu, dri-devel, linux-doc
On Mon Aug 10, 2026 at 3:55 PM CEST, Eliot Courtney wrote:
> Convert the const-block asserts in bounded.rs to const_assert!,
> matching the rest of the file.
>
> Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
Reviewed-by: Danilo Krummrich <dakr@kernel.org>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 02/12] rust: num: reject Bounded::shr overshifts at build time
2026-08-10 13:55 ` [PATCH v2 02/12] rust: num: reject Bounded::shr overshifts at build time Eliot Courtney
2026-08-10 14:23 ` Gary Guo
@ 2026-08-10 22:25 ` Danilo Krummrich
1 sibling, 0 replies; 26+ messages in thread
From: Danilo Krummrich @ 2026-08-10 22:25 UTC (permalink / raw)
To: Eliot Courtney
Cc: Alexandre Courbot, Yury Norov, Miguel Ojeda, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Daniel Almeida, Tamir Duberstein, Onur Özkan,
David Airlie, Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Jonathan Corbet, Shuah Khan, John Hubbard,
Alistair Popple, Timur Tabi, rust-for-linux, linux-kernel,
nova-gpu, dri-devel, linux-doc
On Mon Aug 10, 2026 at 3:55 PM CEST, Eliot Courtney wrote:
> Make `shr` reject shifts of at least the type's bit width at build
> time, instead of panicking or masking the shift amount at runtime.
>
> Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
> Acked-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Danilo Krummrich <dakr@kernel.org>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 03/12] rust: num: add Bounded::shr_exact
2026-08-10 13:55 ` [PATCH v2 03/12] rust: num: add Bounded::shr_exact Eliot Courtney
@ 2026-08-10 22:25 ` Danilo Krummrich
0 siblings, 0 replies; 26+ messages in thread
From: Danilo Krummrich @ 2026-08-10 22:25 UTC (permalink / raw)
To: Eliot Courtney
Cc: Alexandre Courbot, Yury Norov, Miguel Ojeda, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Daniel Almeida, Tamir Duberstein, Onur Özkan,
David Airlie, Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Jonathan Corbet, Shuah Khan, John Hubbard,
Alistair Popple, Timur Tabi, rust-for-linux, linux-kernel,
nova-gpu, dri-devel, linux-doc
On Mon Aug 10, 2026 at 3:55 PM CEST, Eliot Courtney wrote:
> Add `shr_exact` in the vein of `try_shrink` which shifts a bounded right
> only if it loses no set bits. This is useful for getting a shifted down
> integer while simultaneously checking that it's aligned.
>
> Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
> Acked-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Danilo Krummrich <dakr@kernel.org>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 00/12] gpu: nova-core: add PRAMIN window support
2026-08-10 13:55 [PATCH v2 00/12] gpu: nova-core: add PRAMIN window support Eliot Courtney
` (11 preceding siblings ...)
2026-08-10 13:55 ` [PATCH v2 12/12] gpu: nova-core: mm: Add PRAMIN aperture self-tests Eliot Courtney
@ 2026-08-10 22:26 ` Danilo Krummrich
2026-08-11 12:31 ` Miguel Ojeda
2026-08-11 12:31 ` Miguel Ojeda
13 siblings, 1 reply; 26+ messages in thread
From: Danilo Krummrich @ 2026-08-10 22:26 UTC (permalink / raw)
To: Eliot Courtney
Cc: Alexandre Courbot, Yury Norov, Miguel Ojeda, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Daniel Almeida, Tamir Duberstein, Onur Özkan,
David Airlie, Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Jonathan Corbet, Shuah Khan, John Hubbard,
Alistair Popple, Timur Tabi, rust-for-linux, linux-kernel,
nova-gpu, dri-devel, linux-doc, Joel Fernandes
On Mon Aug 10, 2026 at 3:55 PM CEST, Eliot Courtney wrote:
> rust: num: use const_assert! in Bounded
> rust: num: reject Bounded::shr overshifts at build time
> rust: num: add Bounded::shr_exact
I think it would make sense to route them through the Rust tree this cycle.
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 00/12] gpu: nova-core: add PRAMIN window support
2026-08-10 22:26 ` [PATCH v2 00/12] gpu: nova-core: add PRAMIN window support Danilo Krummrich
@ 2026-08-11 12:31 ` Miguel Ojeda
0 siblings, 0 replies; 26+ messages in thread
From: Miguel Ojeda @ 2026-08-11 12:31 UTC (permalink / raw)
To: Danilo Krummrich
Cc: Eliot Courtney, Alexandre Courbot, Yury Norov, Miguel Ojeda,
Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
Andreas Hindborg, Alice Ryhl, Trevor Gross, Daniel Almeida,
Tamir Duberstein, Onur Özkan, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
Jonathan Corbet, Shuah Khan, John Hubbard, Alistair Popple,
Timur Tabi, rust-for-linux, linux-kernel, nova-gpu, dri-devel,
linux-doc, Joel Fernandes
On Tue, Aug 11, 2026 at 12:26 AM Danilo Krummrich <dakr@kernel.org> wrote:
>
> I think it would make sense to route them through the Rust tree this cycle.
Yeah, I asked Alex in v1.
Cheers,
Miguel
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 00/12] gpu: nova-core: add PRAMIN window support
2026-08-10 13:55 [PATCH v2 00/12] gpu: nova-core: add PRAMIN window support Eliot Courtney
` (12 preceding siblings ...)
2026-08-10 22:26 ` [PATCH v2 00/12] gpu: nova-core: add PRAMIN window support Danilo Krummrich
@ 2026-08-11 12:31 ` Miguel Ojeda
13 siblings, 0 replies; 26+ messages in thread
From: Miguel Ojeda @ 2026-08-11 12:31 UTC (permalink / raw)
To: Eliot Courtney, Alexandre Courbot
Cc: Yury Norov, Miguel Ojeda, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Onur Özkan, David Airlie, Simona Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, Jonathan Corbet, Shuah Khan,
John Hubbard, Alistair Popple, Timur Tabi, rust-for-linux,
linux-kernel, nova-gpu, dri-devel, linux-doc, Joel Fernandes
On Mon, Aug 10, 2026 at 3:57 PM Eliot Courtney <ecourtney@nvidia.com> wrote:
>
> rust: num: use const_assert! in Bounded
> rust: num: reject Bounded::shr overshifts at build time
> rust: num: add Bounded::shr_exact
Applied to `rust-next` -- thanks everyone!
Alex: I didn't add an implicit Acked-by to the first one but I assume
you are OK with it:
Suggested-by: Gary Guo <gary@garyguo.net>
Link: https://lore.kernel.org/rust-for-linux/DKIY9YGIPUUE.SZD2DUQM9NGK@garyguo.net/
The second one is actually fairly important so I did:
[ This implies we can break the type invariant, which in turn means
we can trigger UB via `Deref`, e.g.:
rust_kernel: panicked at rust/kernel/num/bounded.rs:528:22:
unsafe precondition(s) violated: hint::unreachable_unchecked
must never be reached
- Miguel ]
Cc: stable@vger.kernel.org
Fixes: c59a2d14cd24 ("rust: num: add `shr` and `shl` methods to `Bounded`")
Cheers,
Miguel
^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2026-08-11 12:32 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-10 13:55 [PATCH v2 00/12] gpu: nova-core: add PRAMIN window support Eliot Courtney
2026-08-10 13:55 ` [PATCH v2 01/12] rust: num: use const_assert! in Bounded Eliot Courtney
2026-08-10 14:07 ` sashiko-bot
2026-08-10 14:23 ` Gary Guo
2026-08-10 22:24 ` Danilo Krummrich
2026-08-10 13:55 ` [PATCH v2 02/12] rust: num: reject Bounded::shr overshifts at build time Eliot Courtney
2026-08-10 14:23 ` Gary Guo
2026-08-10 22:25 ` Danilo Krummrich
2026-08-10 13:55 ` [PATCH v2 03/12] rust: num: add Bounded::shr_exact Eliot Courtney
2026-08-10 22:25 ` Danilo Krummrich
2026-08-10 13:55 ` [PATCH v2 04/12] gpu: nova-core: mm: Add VramAddress type Eliot Courtney
2026-08-10 22:24 ` Danilo Krummrich
2026-08-10 13:55 ` [PATCH v2 05/12] gpu: nova-core: mm: Implement Alignable and Debug for VramAddress Eliot Courtney
2026-08-10 13:55 ` [PATCH v2 06/12] gpu: nova-core: mm: Add PRAMIN window registers Eliot Courtney
2026-08-10 13:55 ` [PATCH v2 07/12] gpu: nova-core: mm: Add the memory management HAL Eliot Courtney
2026-08-10 13:55 ` [PATCH v2 08/12] gpu: nova-core: mm: Add support to use PRAMIN windows to write to VRAM Eliot Courtney
2026-08-10 13:55 ` [PATCH v2 09/12] docs: gpu: nova-core: Document the PRAMIN aperture mechanism Eliot Courtney
2026-08-10 13:55 ` [PATCH v2 10/12] gpu: nova-core: mm: Add GpuMm centralized memory manager Eliot Courtney
2026-08-10 14:09 ` sashiko-bot
2026-08-10 13:55 ` [PATCH v2 11/12] gpu: nova-core: Add self-test assertion macros and config option Eliot Courtney
2026-08-10 14:09 ` sashiko-bot
2026-08-10 13:55 ` [PATCH v2 12/12] gpu: nova-core: mm: Add PRAMIN aperture self-tests Eliot Courtney
2026-08-10 14:16 ` sashiko-bot
2026-08-10 22:26 ` [PATCH v2 00/12] gpu: nova-core: add PRAMIN window support Danilo Krummrich
2026-08-11 12:31 ` Miguel Ojeda
2026-08-11 12:31 ` Miguel Ojeda
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.