[PATCH v9 05/23] gpu: nova-core: gsp: Expose total physical VRAM end from FB region info

From: Joel Fernandes

Date: Tue Mar 10 2026 - 20:41:10 EST


Add `total_fb_end()` to `GspStaticConfigInfo` that computes the exclusive end
address of the highest valid FB region covering both usable and GSP-reserved
areas.

This allows callers to know the full physical VRAM extent, not just the
allocatable portion.

Signed-off-by: Joel Fernandes <joelagnelf@xxxxxxxxxx>
---
drivers/gpu/nova-core/gsp/commands.rs | 6 ++++++
drivers/gpu/nova-core/gsp/fw/commands.rs | 19 +++++++++++++++++++
2 files changed, 25 insertions(+)

diff --git a/drivers/gpu/nova-core/gsp/commands.rs b/drivers/gpu/nova-core/gsp/commands.rs
index 8d5780d9cace..389d215098c6 100644
--- a/drivers/gpu/nova-core/gsp/commands.rs
+++ b/drivers/gpu/nova-core/gsp/commands.rs
@@ -193,6 +193,9 @@ pub(crate) struct GetGspStaticInfoReply {
/// Usable FB (VRAM) region for driver memory allocation.
#[expect(dead_code)]
pub(crate) usable_fb_region: Range<u64>,
+ /// End of VRAM.
+ #[expect(dead_code)]
+ pub(crate) total_fb_end: u64,
}

impl MessageFromGsp for GetGspStaticInfoReply {
@@ -206,9 +209,12 @@ fn read(
) -> Result<Self, Self::InitError> {
let (base, size) = msg.first_usable_fb_region().ok_or(ENODEV)?;

+ let total_fb_end = msg.total_fb_end().ok_or(ENODEV)?;
+
Ok(GetGspStaticInfoReply {
gpu_name: msg.gpu_name_str(),
usable_fb_region: base..base.saturating_add(size),
+ total_fb_end,
})
}
}
diff --git a/drivers/gpu/nova-core/gsp/fw/commands.rs b/drivers/gpu/nova-core/gsp/fw/commands.rs
index cef86cab8a12..acaf92cd6735 100644
--- a/drivers/gpu/nova-core/gsp/fw/commands.rs
+++ b/drivers/gpu/nova-core/gsp/fw/commands.rs
@@ -147,6 +147,25 @@ pub(crate) fn first_usable_fb_region(&self) -> Option<(u64, u64)> {
}
None
}
+
+ /// Compute the end of physical VRAM from all FB regions.
+ pub(crate) fn total_fb_end(&self) -> Option<u64> {
+ let fb_info = &self.0.fbRegionInfoParams;
+ let mut max_end: Option<u64> = None;
+ for i in 0..fb_info.numFBRegions.into_safe_cast() {
+ if let Some(reg) = fb_info.fbRegion.get(i) {
+ if reg.limit < reg.base {
+ continue;
+ }
+ let end = reg.limit.saturating_add(1);
+ max_end = Some(match max_end {
+ None => end,
+ Some(prev) => prev.max(end),
+ });
+ }
+ }
+ max_end
+ }
}

// SAFETY: Padding is explicit and will not contain uninitialized data.
--
2.34.1