[PATCH 8/9] gpu: nova-core: set RMSetSriovMode when NVIDIA vGPU is enabled
From: Zhi Wang
Date: Thu Jun 04 2026 - 07:51:50 EST
The registry object "RMSetSriovMode" is required to be set when vGPU is
enabled.
Convert SetRegistry to use KVec<RegistryEntry> for dynamic construction,
allowing entries to be added conditionally at runtime.
Set "RMSetSriovMode" to 1 when nova-core is loading the GSP firmware and
initialize the GSP registry objects, if vGPU is enabled.
Signed-off-by: Zhi Wang <zhiw@xxxxxxxxxx>
---
drivers/gpu/nova-core/gsp/boot.rs | 2 +-
drivers/gpu/nova-core/gsp/commands.rs | 93 ++++++++++++++++++---------
drivers/gpu/nova-core/gsp/fw.rs | 4 ++
3 files changed, 67 insertions(+), 32 deletions(-)
diff --git a/drivers/gpu/nova-core/gsp/boot.rs b/drivers/gpu/nova-core/gsp/boot.rs
index 6e170401d616..2981d02d15ad 100644
--- a/drivers/gpu/nova-core/gsp/boot.rs
+++ b/drivers/gpu/nova-core/gsp/boot.rs
@@ -139,7 +139,7 @@ pub(crate) fn boot(
self.cmdq
.send_command_no_wait(ctx.bar, commands::SetSystemInfo::new(ctx.pdev, ctx.chipset))?;
self.cmdq
- .send_command_no_wait(ctx.bar, commands::SetRegistry::new())?;
+ .send_command_no_wait(ctx.bar, commands::SetRegistry::new(ctx.vgpu_requested.get())?)?;
hal.post_boot(&self, ctx, &gsp_fw)?;
diff --git a/drivers/gpu/nova-core/gsp/commands.rs b/drivers/gpu/nova-core/gsp/commands.rs
index f84de9f4f045..6171c60f6de0 100644
--- a/drivers/gpu/nova-core/gsp/commands.rs
+++ b/drivers/gpu/nova-core/gsp/commands.rs
@@ -29,6 +29,10 @@
},
fw::{
self,
+ commands::{
+ PackedRegistryEntry,
+ PackedRegistryTable, //
+ },
MsgFunction, //
},
},
@@ -65,38 +69,62 @@ struct RegistryEntry {
}
/// The `SetRegistry` command.
+///
+/// Registry entries are built dynamically at runtime based on the current
+/// configuration (e.g. whether vGPU is enabled).
pub(crate) struct SetRegistry {
- entries: [RegistryEntry; Self::NUM_ENTRIES],
+ entries: KVec<RegistryEntry>,
}
impl SetRegistry {
- // For now we hard-code the registry entries. Future work will allow others to
- // be added as module parameters.
- const NUM_ENTRIES: usize = 3;
-
- /// Creates a new `SetRegistry` command, using a set of hardcoded entries.
- pub(crate) fn new() -> Self {
- Self {
- entries: [
- // RMSecBusResetEnable - enables PCI secondary bus reset
- RegistryEntry {
- key: "RMSecBusResetEnable",
- value: 1,
- },
- // RMForcePcieConfigSave - forces GSP-RM to preserve PCI configuration registers on
- // any PCI reset.
- RegistryEntry {
- key: "RMForcePcieConfigSave",
- value: 1,
- },
- // RMDevidCheckIgnore - allows GSP-RM to boot even if the PCI dev ID is not found
- // in the internal product name database.
+ /// Creates a new `SetRegistry` command.
+ ///
+ /// The base set of registry entries is always included. Additional entries
+ /// are appended dynamically based on runtime conditions (e.g. vGPU).
+ pub(crate) fn new(vgpu_requested: bool) -> Result<Self> {
+ let mut entries = KVec::new();
+
+ // RMSecBusResetEnable - enables PCI secondary bus reset
+ entries.push(
+ RegistryEntry {
+ key: "RMSecBusResetEnable",
+ value: 1,
+ },
+ GFP_KERNEL,
+ )?;
+
+ // RMForcePcieConfigSave - forces GSP-RM to preserve PCI configuration registers on
+ // any PCI reset.
+ entries.push(
+ RegistryEntry {
+ key: "RMForcePcieConfigSave",
+ value: 1,
+ },
+ GFP_KERNEL,
+ )?;
+
+ // RMDevidCheckIgnore - allows GSP-RM to boot even if the PCI dev ID is not found
+ // in the internal product name database.
+ entries.push(
+ RegistryEntry {
+ key: "RMDevidCheckIgnore",
+ value: 1,
+ },
+ GFP_KERNEL,
+ )?;
+
+ // RMSetSriovMode - required when vGPU is enabled.
+ if vgpu_requested {
+ entries.push(
RegistryEntry {
- key: "RMDevidCheckIgnore",
+ key: "RMSetSriovMode",
value: 1,
},
- ],
+ GFP_KERNEL,
+ )?;
}
+
+ Ok(Self { entries })
}
}
@@ -107,28 +135,31 @@ impl CommandToGsp for SetRegistry {
type InitError = Infallible;
fn init(&self) -> impl Init<Self::Command, Self::InitError> {
- Self::Command::init(Self::NUM_ENTRIES as u32, self.variable_payload_len() as u32)
+ PackedRegistryTable::init(
+ self.entries.len() as u32,
+ self.variable_payload_len() as u32,
+ )
}
fn variable_payload_len(&self) -> usize {
let mut key_size = 0;
- for i in 0..Self::NUM_ENTRIES {
- key_size += self.entries[i].key.len() + 1; // +1 for NULL terminator
+ for entry in self.entries.iter() {
+ key_size += entry.key.len() + 1; // +1 for NULL terminator
}
- Self::NUM_ENTRIES * size_of::<fw::commands::PackedRegistryEntry>() + key_size
+ self.entries.len() * size_of::<fw::commands::PackedRegistryEntry>() + key_size
}
fn init_variable_payload(
&self,
dst: &mut SBufferIter<core::array::IntoIter<&mut [u8], 2>>,
) -> Result {
- let string_data_start_offset = size_of::<Self::Command>()
- + Self::NUM_ENTRIES * size_of::<fw::commands::PackedRegistryEntry>();
+ let string_data_start_offset = size_of::<PackedRegistryTable>()
+ + self.entries.len() * size_of::<PackedRegistryEntry>();
// Array for string data.
let mut string_data = KVec::new();
- for entry in self.entries.iter().take(Self::NUM_ENTRIES) {
+ for entry in self.entries.iter() {
dst.write_all(
fw::commands::PackedRegistryEntry::new(
(string_data_start_offset + string_data.len()) as u32,
diff --git a/drivers/gpu/nova-core/gsp/fw.rs b/drivers/gpu/nova-core/gsp/fw.rs
index 4db0cfa4dc4d..14424a2c2d83 100644
--- a/drivers/gpu/nova-core/gsp/fw.rs
+++ b/drivers/gpu/nova-core/gsp/fw.rs
@@ -299,6 +299,7 @@ pub(crate) enum MsgFunction {
OsErrorLog = bindings::NV_VGPU_MSG_EVENT_OS_ERROR_LOG,
PostEvent = bindings::NV_VGPU_MSG_EVENT_POST_EVENT,
RcTriggered = bindings::NV_VGPU_MSG_EVENT_RC_TRIGGERED,
+ GpuacctPerfmonUtilSamples = bindings::NV_VGPU_MSG_EVENT_GPUACCT_PERFMON_UTIL_SAMPLES,
UcodeLibOsPrint = bindings::NV_VGPU_MSG_EVENT_UCODE_LIBOS_PRINT,
}
@@ -348,6 +349,9 @@ fn try_from(value: u32) -> Result<MsgFunction> {
bindings::NV_VGPU_MSG_EVENT_OS_ERROR_LOG => Ok(MsgFunction::OsErrorLog),
bindings::NV_VGPU_MSG_EVENT_POST_EVENT => Ok(MsgFunction::PostEvent),
bindings::NV_VGPU_MSG_EVENT_RC_TRIGGERED => Ok(MsgFunction::RcTriggered),
+ bindings::NV_VGPU_MSG_EVENT_GPUACCT_PERFMON_UTIL_SAMPLES => {
+ Ok(MsgFunction::GpuacctPerfmonUtilSamples)
+ }
bindings::NV_VGPU_MSG_EVENT_UCODE_LIBOS_PRINT => Ok(MsgFunction::UcodeLibOsPrint),
_ => Err(EINVAL),
}
--
2.51.0