[PATCH v3 27/31] gpu: nova-core: vgpu: update the GSP plugin BME state

From: Zhi Wang

Date: Mon Sep 28 2026 - 06:40:30 EST


The vGPU manager reports the enabled bus-mastering state to the GSP plugin
after its initial configuration. The guest can then use the vGPU from now
on.

Add the BME state request and NVKV encoder, and send the enabled state
after configuration succeeds.

Co-developed-by: Eliot Courtney <ecourtney@xxxxxxxxxx>
Signed-off-by: Eliot Courtney <ecourtney@xxxxxxxxxx>
Signed-off-by: Zhi Wang <zhiw@xxxxxxxxxx>
---
drivers/gpu/nova-core/vgpu/commands.rs | 11 +++++++++++
drivers/gpu/nova-core/vgpu/fw/commands.rs | 22 ++++++++++++++++++++++
drivers/gpu/nova-core/vgpu/instance.rs | 2 ++
3 files changed, 35 insertions(+)

diff --git a/drivers/gpu/nova-core/vgpu/commands.rs b/drivers/gpu/nova-core/vgpu/commands.rs
index ec40a960069b..bfb033e5eb37 100644
--- a/drivers/gpu/nova-core/vgpu/commands.rs
+++ b/drivers/gpu/nova-core/vgpu/commands.rs
@@ -25,6 +25,7 @@
use super::{
fw::{
commands::{
+ encode_plugin_set_bme,
VgpuPropertiesSchema, //
},
RpcMessage, //
@@ -178,3 +179,13 @@ pub(super) fn send_plugin_config(
) -> Result {
rpc.rpc_call_nvkv(dev, RpcMessage::SetupConfigParamsAndInit, config)
}
+
+/// Update the bus-mastering state reported to the GSP plugin.
+pub(super) fn set_plugin_bme(
+ dev: &device::Device<device::Bound>,
+ rpc: &mut PluginRpc<'_, '_>,
+ enable: bool,
+) -> Result {
+ let bme = encode_plugin_set_bme(enable)?;
+ rpc.rpc_call_nvkv(dev, RpcMessage::UpdateBmeState, &bme)
+}
diff --git a/drivers/gpu/nova-core/vgpu/fw/commands.rs b/drivers/gpu/nova-core/vgpu/fw/commands.rs
index e3b5198e9c80..cc2298c3679c 100644
--- a/drivers/gpu/nova-core/vgpu/fw/commands.rs
+++ b/drivers/gpu/nova-core/vgpu/fw/commands.rs
@@ -37,6 +37,7 @@
pub(crate) enum RpcMessage {
VersionNegotiation = bindings::MESSAGE_NV_VGPU_CPU_RPC_MSG_VERSION_NEGOTIATION,
SetupConfigParamsAndInit = bindings::MESSAGE_NV_VGPU_CPU_RPC_MSG_SETUP_CONFIG_PARAMS_AND_INIT,
+ UpdateBmeState = bindings::MESSAGE_NV_VGPU_CPU_RPC_MSG_UPDATE_BME_STATE,
}

bitfield! {
@@ -398,3 +399,24 @@ pub(crate) fn encode_plugin_config_params(
request.encode(&mut encoder)?;
Ok(encoder.finish())
}
+
+nvkv_encode! {
+ struct PluginSetBmeRequest {
+ bme_enable: Key<bool, { Self::BME_ENABLE_KEY }, u32>,
+ }
+}
+
+impl PluginSetBmeRequest {
+ const BME_ENABLE_KEY: KeyId = 0x0100;
+}
+
+/// Encodes a plugin BME state update using the typed NVKV schema.
+pub(crate) fn encode_plugin_set_bme(enable: bool) -> Result<EncodedStream> {
+ let request = PluginSetBmeRequest {
+ bme_enable: enable.into(),
+ };
+
+ let mut encoder = Encoder::new();
+ request.encode(&mut encoder)?;
+ Ok(encoder.finish())
+}
diff --git a/drivers/gpu/nova-core/vgpu/instance.rs b/drivers/gpu/nova-core/vgpu/instance.rs
index 247e88bdc82f..23c2b791aa25 100644
--- a/drivers/gpu/nova-core/vgpu/instance.rs
+++ b/drivers/gpu/nova-core/vgpu/instance.rs
@@ -36,6 +36,7 @@
send_cleanup,
send_plugin_config,
send_shutdown,
+ set_plugin_bme,
Dbdf, //
},
fw::commands::{
@@ -162,6 +163,7 @@ fn activate(&mut self, vgpu: &VgpuManager<'gpu>) -> Result {
self.plugin_rpc.init_rpc()?;
negotiate_plugin_version(dev, &mut self.plugin_rpc)?;
self.configure_plugin(dev)?;
+ set_plugin_bme(dev, &mut self.plugin_rpc, true)?;

Ok(())
}