Re: [PATCH 3/4] gpu: nova-core: gsp: Extract usable FB region from GSP
From: Eliot Courtney
Date: Tue Jun 09 2026 - 23:36:47 EST
On Tue Jun 9, 2026 at 5:04 PM JST, Alexandre Courbot wrote:
> From: Joel Fernandes <joelagnelf@xxxxxxxxxx>
>
> Add usable_fb_regions_iter() to GspStaticConfigInfo to extract the first
> usable FB region from GSP's fbRegionInfoParams. Usable regions are those
> that are not reserved or protected.
>
> The extracted region is stored in GetGspStaticInfoReply and exposed as
> usable_fb_region field for use by the memory subsystem.
>
> Signed-off-by: Joel Fernandes <joelagnelf@xxxxxxxxxx>
> Reviewed-by: John Hubbard <jhubbard@xxxxxxxxxx>
> ---
> drivers/gpu/nova-core/gsp/commands.rs | 9 +++++--
> drivers/gpu/nova-core/gsp/fw/commands.rs | 40 +++++++++++++++++++++++++++++++-
> 2 files changed, 46 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/nova-core/gsp/commands.rs b/drivers/gpu/nova-core/gsp/commands.rs
> index f84de9f4f045..d955f52a93bb 100644
> --- a/drivers/gpu/nova-core/gsp/commands.rs
> +++ b/drivers/gpu/nova-core/gsp/commands.rs
> @@ -5,6 +5,7 @@
> array,
> convert::Infallible,
> ffi::FromBytesUntilNulError,
> + ops::Range,
> str::Utf8Error, //
> };
>
> @@ -191,15 +192,18 @@ fn init(&self) -> impl Init<Self::Command, Self::InitError> {
> }
> }
>
> -/// The reply from the GSP to the [`GetGspInfo`] command.
> +/// The reply from the GSP to the [`GetGspStaticInfo`] command.
> pub(crate) struct GetGspStaticInfoReply {
> gpu_name: [u8; 64],
> + /// Usable FB (VRAM) region for driver memory allocation.
> + #[expect(dead_code)]
> + pub(crate) usable_fb_region: Range<u64>,
> }
>
> impl MessageFromGsp for GetGspStaticInfoReply {
> const FUNCTION: MsgFunction = MsgFunction::GetGspStaticInfo;
> type Message = fw::commands::GspStaticConfigInfo;
> - type InitError = Infallible;
> + type InitError = Error;
>
> fn read(
> msg: &Self::Message,
> @@ -207,6 +211,7 @@ fn read(
> ) -> Result<Self, Self::InitError> {
> Ok(GetGspStaticInfoReply {
> gpu_name: msg.gpu_name_str(),
> + usable_fb_region: msg.usable_fb_regions_iter().next().ok_or(ENODEV)?,
> })
> }
> }
> diff --git a/drivers/gpu/nova-core/gsp/fw/commands.rs b/drivers/gpu/nova-core/gsp/fw/commands.rs
> index 7bcc41fc7fa0..d025167927df 100644
> --- a/drivers/gpu/nova-core/gsp/fw/commands.rs
> +++ b/drivers/gpu/nova-core/gsp/fw/commands.rs
> @@ -1,6 +1,8 @@
> // SPDX-License-Identifier: GPL-2.0
> // SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
>
> +use core::ops::Range;
> +
> use kernel::{
> device,
> pci,
> @@ -13,7 +15,8 @@
>
> use crate::{
> gpu::Chipset,
> - gsp::GSP_PAGE_SIZE, //
> + gsp::GSP_PAGE_SIZE,
> + num::IntoSafeCast, //
> };
>
> use super::bindings;
> @@ -129,6 +132,41 @@ impl GspStaticConfigInfo {
> pub(crate) fn gpu_name_str(&self) -> [u8; 64] {
> self.0.gpuNameString
> }
> +
> + /// Returns an iterator over valid FB regions from GSP firmware data.
> + fn fb_regions(
> + &self,
> + ) -> impl Iterator<Item = &bindings::NV2080_CTRL_CMD_FB_GET_FB_REGION_FB_REGION_INFO> {
> + let fb_info = &self.0.fbRegionInfoParams;
> + fb_info
> + .fbRegion
> + .iter()
> + .take(fb_info.numFBRegions.into_safe_cast())
> + .filter(|reg| reg.limit >= reg.base)
Do you know if we actually get broken values like this (limit < base)?
Also we could print out the `usable_fb_region` as well, if you like?
Reviewed-by: Eliot Courtney <ecourtney@xxxxxxxxxx>
> + }
> +
> + /// Iterates over usable FB regions from GSP firmware data.
> + ///
> + /// Each yielded region is a [`Range<u64>`] suitable for driver memory allocation.
> + /// Usable regions are those that satisfy all the following properties:
> + /// - Are not reserved for firmware internal use.
> + /// - Are not protected (hardware-enforced access restrictions).
> + /// - Support compression (can use GPU memory compression for bandwidth).
> + /// - Support ISO (isochronous memory for display requiring guaranteed bandwidth).
> + pub(crate) fn usable_fb_regions_iter(&self) -> impl Iterator<Item = Range<u64>> + '_ {
> + self.fb_regions().filter_map(|reg| {
> + // Filter: not reserved, not protected, supports compression and ISO.
> + if reg.reserved == 0
> + && reg.bProtected == 0
> + && reg.supportCompressed != 0
> + && reg.supportISO != 0
> + {
> + reg.limit.checked_add(1).map(|end| reg.base..end)
> + } else {
> + None
> + }
> + })
> + }
> }
>
> // SAFETY: Padding is explicit and will not contain uninitialized data.