[PATCH v3 06/31] gpu: nova-core: vgpu: initialize runtime parameters after GSP boot
From: Zhi Wang
Date: Mon Sep 28 2026 - 06:30:54 EST
The vGPU manager needs the VMMU segment size and FIFO engine topology
returned by a successful GSP boot to divide instance resources.
Construct VgpuManager only for a vGPU-enabled boot. Retain the GPU-owned
channel pool, the ordered host-driven engine
list and the VMMU segment size. Expose the existing decoded VMMU value
from GspStaticInfo at its first consumer, preserving zero when firmware
omits the key.
Keep the runtime values in the manager for its instance module, and drop
the manager before the pool and memory resources it borrows.
Cc: Alexandre Courbot <acourbot@xxxxxxxxxx>
Signed-off-by: Zhi Wang <zhiw@xxxxxxxxxx>
---
drivers/gpu/nova-core/gpu.rs | 24 +++++++++++++++-
drivers/gpu/nova-core/gsp/commands.rs | 5 +++-
drivers/gpu/nova-core/gsp/fw/commands.rs | 4 +--
drivers/gpu/nova-core/vgpu.rs | 36 +++++++++++++++++++++++-
4 files changed, 63 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
index c239b6614d44..11d9986c4b19 100644
--- a/drivers/gpu/nova-core/gpu.rs
+++ b/drivers/gpu/nova-core/gpu.rs
@@ -49,7 +49,10 @@
VramAddress, //
},
num,
- vgpu::VgpuState, //
+ vgpu::{
+ VgpuManager,
+ VgpuState, //
+ },
};
#[cfg_attr(not(CONFIG_KUNIT = "y"), expect(dead_code))]
@@ -323,6 +326,7 @@ fn static_info(&self) -> &gsp::commands::GspStaticInfo {
#[pin_data]
pub(crate) struct Gpu<'gpu> {
spec: Spec,
+ vgpu: Option<VgpuManager<'gpu>>,
/// GSP event interrupt registration.
///
/// Must be kept declared *before* `gsp_resources`, so that the handler is unregistered, and
@@ -457,6 +461,24 @@ pub(crate) fn new<'a>(
})?,
}),
+ vgpu: {
+ let info = &gsp_resources.boot_result.static_info;
+ match gsp_resources.vgpu_state {
+ VgpuState::Disabled => None,
+ VgpuState::Enabled { .. } => Some(VgpuManager::new(
+ // SAFETY: `chid_pool` is initialized above at its final pinned address.
+ // The private manager and its pool borrow cannot escape this `Gpu`.
+ // Completed field drop order drops the manager before the pool; on failure,
+ // pin-init drops it before the earlier-initialized pool.
+ unsafe { &*core::ptr::from_ref(chid_pool.as_ref().get_ref()) },
+ &info.fifo_engine_list(),
+ info.vmmu_segment_size,
+ TOTAL_CHANNELS,
+ )),
+ }
+ },
+
+ // GSP boot left the SWGEN0 latch set and pending bits in the tree.
_: {
irq::gsp::quiesce(bar, gsp_resources.spec.chipset, vectors_ref)?;
},
diff --git a/drivers/gpu/nova-core/gsp/commands.rs b/drivers/gpu/nova-core/gsp/commands.rs
index 436ea52689b9..97e32f81a39b 100644
--- a/drivers/gpu/nova-core/gsp/commands.rs
+++ b/drivers/gpu/nova-core/gsp/commands.rs
@@ -34,7 +34,10 @@
vgpu::VgpuState, //
};
-pub(crate) use fw::commands::GspStaticInfo;
+pub(crate) use fw::commands::{
+ FifoEngineList,
+ GspStaticInfo, //
+};
/// Builds the NVKV-encoded payload of a `GSP_INIT` request for `pdev`.
///
diff --git a/drivers/gpu/nova-core/gsp/fw/commands.rs b/drivers/gpu/nova-core/gsp/fw/commands.rs
index 17ae4224e214..7381b30f3680 100644
--- a/drivers/gpu/nova-core/gsp/fw/commands.rs
+++ b/drivers/gpu/nova-core/gsp/fw/commands.rs
@@ -394,8 +394,7 @@ pub(crate) struct GspStaticInfo {
gpu_name: ArrayVec<u8, { Self::MAX_GPU_NAME_LEN }>,
fb_regions: KVVec<FbRegion>,
bar1_pde_base: u64,
- #[cfg_attr(not(CONFIG_KUNIT = "y"), expect(dead_code))]
- vmmu_segment_size: u64,
+ pub(crate) vmmu_segment_size: u64,
fifo_engine_count: FifoEngineCount,
fifo_engine_gmc_ids: [u32; MAX_FIFO_ENGINES],
fifo_engine_flags: [u32; MAX_FIFO_ENGINES],
@@ -464,7 +463,6 @@ pub(crate) fn total_fb_end(&self) -> Option<u64> {
}
/// Returns the host-driven engines in their firmware FIFO order.
- #[expect(dead_code)]
pub(crate) fn fifo_engine_list(&self) -> FifoEngineList {
// INVARIANT: The list starts empty and appends at most one ID per supported input slot.
let mut fifo_engine_list = FifoEngineList {
diff --git a/drivers/gpu/nova-core/vgpu.rs b/drivers/gpu/nova-core/vgpu.rs
index b405ba49c490..5cd82adeb0f8 100644
--- a/drivers/gpu/nova-core/vgpu.rs
+++ b/drivers/gpu/nova-core/vgpu.rs
@@ -13,7 +13,11 @@
Fsp,
VgpuMode, //
},
- gpu::Chipset, //
+ gpu::{
+ ChannelIdPool,
+ Chipset, //
+ },
+ gsp::commands::FifoEngineList, //
};
mod hal;
@@ -80,3 +84,33 @@ fn query_state(
}
}
}
+
+/// Runtime resources for an enabled vGPU boot.
+pub(crate) struct VgpuManager<'gpu> {
+ #[expect(dead_code)]
+ chid_pool: &'gpu ChannelIdPool,
+ /// VMMU segment size in bytes, or zero if GSP-RM omitted it.
+ #[expect(dead_code)]
+ vmmu_segment_size: u64,
+ #[expect(dead_code)]
+ total_channels: u32,
+ #[expect(dead_code)]
+ fifo_engine_list: FifoEngineList,
+}
+
+impl<'gpu> VgpuManager<'gpu> {
+ /// Retains runtime parameters from a completed vGPU-enabled GSP boot.
+ pub(crate) fn new(
+ chid_pool: &'gpu ChannelIdPool,
+ fifo_engine_list: &FifoEngineList,
+ vmmu_segment_size: u64,
+ total_channels: u32,
+ ) -> Self {
+ Self {
+ chid_pool,
+ vmmu_segment_size,
+ total_channels,
+ fifo_engine_list: *fifo_engine_list,
+ }
+ }
+}