NVIDIA GPU driver infrastructure
 help / color / mirror / Atom feed
* [PATCH] gpu: nova-core: make pramin/buddy optional
@ 2026-10-26  4:24 Dave Airlie via B4 Relay
  2026-10-26  6:58 ` sashiko-bot
  2026-10-26 18:50 ` Danilo Krummrich
  0 siblings, 2 replies; 3+ messages in thread
From: Dave Airlie via B4 Relay @ 2026-10-26  4:24 UTC (permalink / raw)
  To: Danilo Krummrich, Alexandre Courbot, David Airlie
  Cc: nova-gpu, dri-devel, Dave Airlie

From: Dave Airlie <airlied@redhat.com>

These aren't used on systems with no framebuffer memory.

Signed-off-by: Dave Airlie <airlied@redhat.com>
---
 drivers/gpu/nova-core/gpu.rs               | 15 +++++++------
 drivers/gpu/nova-core/mm.rs                | 34 +++++++++++++++---------------
 drivers/gpu/nova-core/mm/bar_user.rs       | 14 ++++++------
 drivers/gpu/nova-core/mm/pagetable/map.rs  | 10 ++++-----
 drivers/gpu/nova-core/mm/pagetable/walk.rs |  2 +-
 5 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
index 4e59072cab50..5d53fde2cdc1 100644
--- a/drivers/gpu/nova-core/gpu.rs
+++ b/drivers/gpu/nova-core/gpu.rs
@@ -564,18 +564,19 @@ pub(crate) fn new<'a>(
 
             // Create GPU memory manager owning memory management resources.
             mm: {
-                let usable_vram = gsp_static_info.usable_fb_regions.first().ok_or(ENODEV)?;
-                let buddy_params = GpuBuddyParams {
-                    base_offset: usable_vram.start,
-                    size: usable_vram.end - usable_vram.start,
-                    chunk_size: Alignment::new::<SZ_4K>(),
-                };
+                let buddy_params = gsp_static_info.usable_fb_regions.first().map(|usable_vram| {
+                    GpuBuddyParams {
+                        base_offset: usable_vram.start,
+                        size: usable_vram.end - usable_vram.start,
+                        chunk_size: Alignment::new::<SZ_4K>(),
+                    }
+                });
 
                 GpuMm::new(
                     bar,
                     gsp_resources.spec.chipset,
                     buddy_params,
-                    VramAddress::from_raw(gsp_static_info.total_fb_end),
+                    Some(VramAddress::from_raw(gsp_static_info.total_fb_end)),
                 )?
             },
 
diff --git a/drivers/gpu/nova-core/mm.rs b/drivers/gpu/nova-core/mm.rs
index 8a934c55169f..9a2c73c978be 100644
--- a/drivers/gpu/nova-core/mm.rs
+++ b/drivers/gpu/nova-core/mm.rs
@@ -71,12 +71,12 @@ macro_rules! impl_pfn_bounded {
 /// GPU Memory Manager - owns all core MM components.
 ///
 /// Provides centralized ownership of memory management resources:
-/// - [`GpuBuddy`] allocator for VRAM page table allocation.
-/// - [`pramin::Pramin`] for direct VRAM access.
+/// - Optional [`GpuBuddy`] allocator for VRAM page table allocation.
+/// - Optional [`pramin::Pramin`] for direct VRAM access.
 /// - [`Tlb`] manager for translation buffer flush operations.
 pub(crate) struct GpuMm<'gpu> {
-    buddy: GpuBuddy,
-    pramin: pramin::Pramin<'gpu>,
+    buddy: Option<GpuBuddy>,
+    pramin: Option<pramin::Pramin<'gpu>>,
     tlb: Pin<KBox<Tlb<'gpu>>>,
 }
 
@@ -85,28 +85,28 @@ impl<'gpu> GpuMm<'gpu> {
     pub(crate) fn new(
         bar: Bar0<'gpu>,
         chipset: Chipset,
-        buddy_params: GpuBuddyParams,
-        total_fb_end: VramAddress,
+        buddy_params: Option<GpuBuddyParams>,
+        total_fb_end: Option<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 {
-            buddy: GpuBuddy::new(buddy_params)?,
-            pramin: pramin::Pramin::new(bar, chipset, vram_region)?,
+            buddy: buddy_params.map(GpuBuddy::new).transpose()?,
+            // PRAMIN covers all physical VRAM, including GSP-reserved areas above
+            // the usable region, such as the BAR1 page directory.
+            pramin: total_fb_end
+                .map(|end| pramin::Pramin::new(bar, chipset, VramAddress::ZERO..end))
+                .transpose()?,
             tlb: KBox::pin_init(Tlb::new(bar), GFP_KERNEL)?,
         })
     }
 
     /// Access the [`GpuBuddy`] allocator.
-    pub(crate) fn buddy(&self) -> &GpuBuddy {
-        &self.buddy
+    pub(crate) fn buddy(&self) -> Result<&GpuBuddy> {
+        self.buddy.as_ref().ok_or(ENODEV)
     }
 
     /// Access the [`pramin::Pramin`].
-    fn pramin_mut(&mut self) -> &mut pramin::Pramin<'gpu> {
-        &mut self.pramin
+    fn pramin_mut(&mut self) -> Result<&mut pramin::Pramin<'gpu>> {
+        self.pramin.as_mut().ok_or(ENODEV)
     }
 
     /// Access the [`Tlb`] manager.
@@ -329,7 +329,7 @@ pub(crate) fn run(
             return Ok(());
         };
 
-        pramin::selftest::run(dev, mm.pramin_mut(), VramAddress::from_raw(base))?;
+        pramin::selftest::run(dev, mm.pramin_mut()?, VramAddress::from_raw(base))?;
         bar_user::run_self_test(dev, mm, bar_user, bar1_pdb, chipset)
     }
 }
diff --git a/drivers/gpu/nova-core/mm/bar_user.rs b/drivers/gpu/nova-core/mm/bar_user.rs
index 6e9384f06f43..baf9450b93a6 100644
--- a/drivers/gpu/nova-core/mm/bar_user.rs
+++ b/drivers/gpu/nova-core/mm/bar_user.rs
@@ -212,14 +212,14 @@ pub(crate) fn run_self_test(
     let pdb_addr = VramAddress::from_raw(bar1_pdb);
 
     // Check if initial page tables are in VRAM.
-    if crate::mm::pagetable::check_pdb_valid(mm.pramin_mut(), pdb_addr, chipset).is_err() {
+    if crate::mm::pagetable::check_pdb_valid(mm.pramin_mut()?, pdb_addr, chipset).is_err() {
         dev_info!(dev, "MM: Self-test SKIPPED - no valid VRAM page tables\n");
         return Ok(());
     }
 
     // Set up a test page from the buddy allocator.
     let test_page_blocks = KBox::pin_init(
-        mm.buddy().alloc_blocks(
+        mm.buddy()?.alloc_blocks(
             GpuBuddyAllocMode::Simple,
             SZ_4K.into_safe_cast(),
             Alignment::new::<SZ_4K>(),
@@ -245,7 +245,7 @@ pub(crate) fn run_self_test(
     let vram_read_addr = test_vram + 0x100;
 
     // Test 1: Write via PRAMIN, read via BAR1.
-    mm.pramin_mut()
+    mm.pramin_mut()?
         .window_at::<u32>(vram_read_addr)?
         .view()
         .write_val(PATTERN_PRAMIN);
@@ -296,7 +296,7 @@ pub(crate) fn run_self_test(
 
     // Punch a 4K hole at base+16K so the subsequent 32K allocation must split.
     let _hole = KBox::pin_init(
-        mm.buddy().alloc_blocks(
+        mm.buddy()?.alloc_blocks(
             GpuBuddyAllocMode::Range(range_base + sz_16k..range_base + sz_16k + sz_4k),
             SZ_4K.into_safe_cast(),
             Alignment::new::<SZ_4K>(),
@@ -308,7 +308,7 @@ pub(crate) fn run_self_test(
     // Allocate 32K within [base, base+36K). The hole forces the allocator to return
     // split blocks whose sizes are determined by buddy alignment.
     let blocks = KBox::pin_init(
-        mm.buddy().alloc_blocks(
+        mm.buddy()?.alloc_blocks(
             GpuBuddyAllocMode::Range(range_base..range_base + sz_32k_4k),
             SZ_32K.into_safe_cast(),
             Alignment::new::<SZ_4K>(),
@@ -353,7 +353,7 @@ pub(crate) fn run_self_test(
             bar1.try_write32(PATTERN_BAR1, page_bar1_off)?;
 
             let pramin_val = mm
-                .pramin_mut()
+                .pramin_mut()?
                 .window_at::<u32>(VramAddress::from_raw(page_phys))?
                 .view()
                 .read_val();
@@ -391,7 +391,7 @@ pub(crate) fn run_self_test(
     let access = bar_user.map(mm, &[test_pfn], true)?;
 
     // Write pattern via PRAMIN, read via BarUserAccess.
-    mm.pramin_mut()
+    mm.pramin_mut()?
         .window_at::<u32>(test_vram)?
         .view()
         .write_val(PATTERN_BAR1);
diff --git a/drivers/gpu/nova-core/mm/pagetable/map.rs b/drivers/gpu/nova-core/mm/pagetable/map.rs
index 77431c509a89..fd404b0734bb 100644
--- a/drivers/gpu/nova-core/mm/pagetable/map.rs
+++ b/drivers/gpu/nova-core/mm/pagetable/map.rs
@@ -81,7 +81,7 @@ pub(super) fn new(pdb_addr: VramAddress) -> Self {
     /// Allocate and zero a physical page table page.
     fn alloc_and_zero_page(mm: &mut GpuMm<'_>, level: PageTableLevel) -> Result<PreparedPtPage> {
         let blocks = KBox::pin_init(
-            mm.buddy().alloc_blocks(
+            mm.buddy()?.alloc_blocks(
                 GpuBuddyAllocMode::Simple,
                 SZ_4K.into_safe_cast(),
                 Alignment::new::<SZ_4K>(),
@@ -94,7 +94,7 @@ fn alloc_and_zero_page(mm: &mut GpuMm<'_>, level: PageTableLevel) -> Result<Prep
 
         // Zero via PRAMIN.
         let window = mm
-            .pramin_mut()
+            .pramin_mut()?
             .window_at::<[u64; PAGE_SIZE / 8]>(page_vram)?;
         for i in 0..PAGE_SIZE / 8 {
             io_write!(window.view(), [build: i], 0);
@@ -120,7 +120,7 @@ fn ensure_single_pte_path(
         for _ in 0..max_iter {
             let result = self
                 .walker
-                .walk_pde_levels(mm.pramin_mut(), vfn, |install_addr| {
+                .walk_pde_levels(mm.pramin_mut()?, vfn, |install_addr| {
                     pt_pages.get(&install_addr).and_then(|p| {
                         p.alloc
                             .iter()
@@ -197,7 +197,7 @@ pub(super) fn install_mappings(
         writable: bool,
     ) -> Result {
         {
-            let pramin = mm.pramin_mut();
+            let pramin = mm.pramin_mut()?;
 
             // Drain prepared PT pages, install all pending PDEs.
             let mut cursor = pt_pages.cursor_front_mut();
@@ -255,7 +255,7 @@ pub(super) fn invalidate_ptes(
         let invalid_pte = M::Pte::invalid();
 
         {
-            let pramin = mm.pramin_mut();
+            let pramin = mm.pramin_mut()?;
             for i in 0..num_pages {
                 let i_u64: u64 = i.into_safe_cast();
                 let vfn = Vfn::new(vfn_start.raw() + i_u64);
diff --git a/drivers/gpu/nova-core/mm/pagetable/walk.rs b/drivers/gpu/nova-core/mm/pagetable/walk.rs
index 76c1729971f5..19aae75c2c76 100644
--- a/drivers/gpu/nova-core/mm/pagetable/walk.rs
+++ b/drivers/gpu/nova-core/mm/pagetable/walk.rs
@@ -172,7 +172,7 @@ pub(super) fn walk_pde_levels(
     ///
     /// Returns [`WalkResult::PageTableMissing`] if intermediate tables don't exist.
     pub(super) fn walk_to_pte_lookup(&self, mm: &mut GpuMm<'_>, vfn: Vfn) -> Result<WalkResult> {
-        self.walk_to_pte_lookup_with_window(mm.pramin_mut(), vfn)
+        self.walk_to_pte_lookup_with_window(mm.pramin_mut()?, vfn)
     }
 
     /// Walk to PTE using a caller-provided PRAMIN manager (lookup only).

---
base-commit: 3497a403264b094ebd61b8b755165d56e7d9dc37
change-id: 20261026-nova-pramin-option-50cdf1102281

Best regards,
-- 
Dave Airlie <airlied@redhat.com>



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

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

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-26  4:24 [PATCH] gpu: nova-core: make pramin/buddy optional Dave Airlie via B4 Relay
2026-10-26  6:58 ` sashiko-bot
2026-10-26 18:50 ` Danilo Krummrich

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