From: Alok Kumar <alkumar@nvidia.com>
To: <dakr@kernel.org>, <acourbot@nvidia.com>, <kvm@vger.kernel.org>,
<rust-for-linux@vger.kernel.org>, <nova-gpu@lists.linux.dev>,
<linux-pci@vger.kernel.org>
Cc: <alex@shazbot.org>, <jgg@nvidia.com>, <yishaih@nvidia.com>,
<skolothumtho@nvidia.com>, <kevin.tian@intel.com>,
<airlied@gmail.com>, <simona@ffwll.ch>, <ojeda@kernel.org>,
<alex.gaynor@gmail.com>, <boqun.feng@gmail.com>,
<gary@garyguo.net>, <bjorn3_gh@protonmail.com>,
<lossin@kernel.org>, <a.hindborg@kernel.org>,
<aliceryhl@google.com>, <tmgross@umich.edu>,
<markus.probst@posteo.de>, <jhubbard@nvidia.com>,
<apopple@nvidia.com>, <joelagnelf@nvidia.com>,
<ecourtney@nvidia.com>, <cjia@nvidia.com>, <smitra@nvidia.com>,
<kjaju@nvidia.com>, <alkumar@nvidia.com>, <ankita@nvidia.com>,
<aniketa@nvidia.com>, <kwankhede@nvidia.com>,
<targupta@nvidia.com>, <linux-kernel@vger.kernel.org>,
<zhiwang@kernel.org>, <zhiw@nvidia.com>, <boqun@kernel.org>,
<daniel.almeida@collabora.com>, <tamird@kernel.org>,
<work@onurozkan.dev>, <jgg@ziepe.ca>, <bhelgaas@google.com>,
<kwilczynski@kernel.org>, <dri-devel@lists.freedesktop.org>,
<peter@colberg.org>, <xinmengs@nvidia.com>
Subject: [PATCH v4 20/32] gpu: nova-core: vgpu: encode vGPU boot requests
Date: Fri, 6 Nov 2026 11:09:53 +0530 [thread overview]
Message-ID: <ee73ba913c15d9cdeca02da9258088333d6a2217.1793906667.git.alkumar@nvidia.com> (raw)
In-Reply-To: <cover.1793906667.git.alkumar@nvidia.com>
From: Zhi Wang <zhiw@nvidia.com>
The boot request describes a vGPU's identity, channel map, VRAM,
plugin heap and log buffers to GSP-RM.
Add the NVKV schema and encode it from a named boot description. Pass
VRAM region views so each physical address stays paired with its length
until encoding, and retain the control offset relative to the plugin
heap. Represent channel-map engine and index fields in their 16-bit wire
domains.
Describe one guest VRAM segment and the current whole-GPU,
non-SMIG resource layout. Keep separate MIG-RM heap fields zero for that
supported firmware path.
Co-developed-by: Eliot Courtney <ecourtney@nvidia.com>
Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
Signed-off-by: Zhi Wang <zhiw@nvidia.com>
Signed-off-by: Alok Kumar <alkumar@nvidia.com>
---
drivers/gpu/nova-core/gsp/nvkv.rs | 11 ++
drivers/gpu/nova-core/gsp/nvkv/encode.rs | 12 ++
drivers/gpu/nova-core/vgpu/fw/commands.rs | 168 +++++++++++++++++++++-
3 files changed, 188 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/nova-core/gsp/nvkv.rs b/drivers/gpu/nova-core/gsp/nvkv.rs
index 5887a61af02a..0e8e14f98059 100644
--- a/drivers/gpu/nova-core/gsp/nvkv.rs
+++ b/drivers/gpu/nova-core/gsp/nvkv.rs
@@ -131,6 +131,17 @@ pub(crate) struct Array<T, const N: usize, const KEY_ID: KeyId> {
vec: ArrayVec<T, N>,
}
+impl<T: Default + Copy, const N: usize, const KEY_ID: KeyId> Array<T, N, KEY_ID> {
+ /// Creates an array filled from `values`.
+ ///
+ /// Fails with `EINVAL` if `values` is longer than `N`.
+ pub(crate) fn new(values: &[T]) -> Result<Self> {
+ let mut vec = ArrayVec::default();
+ vec.extend_from_slice(values)?;
+ Ok(Self { vec })
+ }
+}
+
bitfield! {
/// The op word that starts each NVKV operation.
struct Op(u64) {
diff --git a/drivers/gpu/nova-core/gsp/nvkv/encode.rs b/drivers/gpu/nova-core/gsp/nvkv/encode.rs
index c6891c0441ff..c4578e3ecef9 100644
--- a/drivers/gpu/nova-core/gsp/nvkv/encode.rs
+++ b/drivers/gpu/nova-core/gsp/nvkv/encode.rs
@@ -7,6 +7,7 @@
use zerocopy::Immutable;
use super::{
+ Array,
Index,
IndexedKey,
Key,
@@ -130,6 +131,17 @@ fn encode(&self, encoder: &mut Encoder) -> Result {
}
}
+impl<T, const N: usize, const KEY_ID: KeyId> Encodable for Array<T, N, KEY_ID>
+where
+ T: Default + Copy,
+ for<'a> IndexedKey<&'a [T], KEY_ID>: Encodable,
+{
+ #[inline(always)]
+ fn encode(&self, encoder: &mut Encoder) -> Result {
+ IndexedKey::<&[T], KEY_ID>::new(Index::new::<0>(), self.vec.as_slice()).encode(encoder)
+ }
+}
+
impl<T: Encodable> Encodable for Option<T> {
fn encode(&self, encoder: &mut Encoder) -> Result {
if let Some(value) = self {
diff --git a/drivers/gpu/nova-core/vgpu/fw/commands.rs b/drivers/gpu/nova-core/vgpu/fw/commands.rs
index efab30287f05..b8007c3e4a71 100644
--- a/drivers/gpu/nova-core/vgpu/fw/commands.rs
+++ b/drivers/gpu/nova-core/vgpu/fw/commands.rs
@@ -8,17 +8,23 @@
use kernel::{
alloc::ArrayVec,
- bitfield, //
+ bitfield,
+ prelude::*, //
};
use crate::{
gsp::nvkv::{
nvkv_decode,
+ nvkv_encode,
Array,
+ Encodable,
+ Encoder,
+ Index, //
Key,
KeyId,
- Required, //
- }, //
+ Required,
+ },
+ mm::vram::VramRegion, //
};
bitfield! {
@@ -30,6 +36,162 @@ pub(crate) struct Dbdf(u32) {
}
}
+#[derive(Clone, Copy)]
+struct SwizzId(u32);
+
+impl SwizzId {
+ const WHOLE_GPU: Self = Self(0xFFFF_FFFF);
+}
+
+impl From<SwizzId> for u32 {
+ fn from(value: SwizzId) -> Self {
+ value.0
+ }
+}
+
+bitfield! {
+ pub(crate) struct ChannelMapEntry(u64) {
+ 15:0 engine_type;
+ 31:16 index;
+ 63:32 chid_offset;
+ }
+}
+
+impl ChannelMapEntry {
+ const KEY: KeyId = 0x1001;
+
+ #[expect(dead_code)]
+ pub(crate) fn new(engine_type: u16, index: u16, chid_offset: u32) -> Self {
+ Self::zeroed()
+ .with_engine_type(engine_type)
+ .with_index(index)
+ .with_chid_offset(chid_offset)
+ }
+}
+
+impl Encodable for KVVec<ChannelMapEntry> {
+ fn encode(&self, encoder: &mut Encoder) -> Result {
+ // SAFETY: `ChannelMapEntry` is a `bitfield!` over `u64`, i.e.
+ // `#[repr(transparent)]` around a `u64`, so the entries are
+ // layout-compatible with `u64` and can be viewed as a `u64` slice.
+ let slice = unsafe { core::slice::from_raw_parts(self.as_ptr().cast::<u64>(), self.len()) };
+ encoder.encode_array64(ChannelMapEntry::KEY, Index::new::<0>(), slice)
+ }
+}
+
+bitfield! {
+ struct VgpuBootloadOptions(u64) {
+ }
+}
+
+nvkv_encode! {
+ struct VgpuBootloadRequest {
+ dbdf: Key<Dbdf, { Self::DBDF_KEY }, u32>,
+ gfid: Key<u32, { Self::GFID_KEY }>,
+ vgpu_type: Key<u32, { Self::VGPU_TYPE_KEY }>,
+ vm_pid: Key<u32, { Self::VM_PID_KEY }>,
+ swizz_id: Key<SwizzId, { Self::SWIZZ_ID_KEY }, u32>,
+ num_channels: Key<u32, { Self::NUM_CHANNELS_KEY }>,
+ num_plugin_channels: Key<u32, { Self::NUM_PLUGIN_CHANNELS_KEY }>,
+ guest_fb_segment_count: Key<u32, { Self::GUEST_FB_SEGMENT_COUNT_KEY }>,
+ options: Key<VgpuBootloadOptions, { Self::OPTIONS_KEY }, u64>,
+ channel_mapping: KVVec<ChannelMapEntry>,
+ guest_fb_segment_phys_addr: Array<u64, 8, { Self::GUEST_FB_SEGMENT_PHYS_ADDR_KEY }>,
+ guest_fb_segment_length: Array<u64, 8, { Self::GUEST_FB_SEGMENT_LENGTH_KEY }>,
+ plugin_heap_phys_addr: Key<u64, { Self::PLUGIN_HEAP_PHYS_ADDR_KEY }>,
+ plugin_heap_length: Key<u64, { Self::PLUGIN_HEAP_LENGTH_KEY }>,
+ ctrl_buff_offset: Key<u64, { Self::CTRL_BUFF_OFFSET_KEY }>,
+ init_task_log_offset: Key<u64, { Self::INIT_TASK_LOG_OFFSET_KEY }>,
+ init_task_log_size: Key<u64, { Self::INIT_TASK_LOG_SIZE_KEY }>,
+ vgpu_task_log_offset: Key<u64, { Self::VGPU_TASK_LOG_OFFSET_KEY }>,
+ vgpu_task_log_size: Key<u64, { Self::VGPU_TASK_LOG_SIZE_KEY }>,
+ kernel_log_offset: Key<u64, { Self::KERNEL_LOG_OFFSET_KEY }>,
+ kernel_log_size: Key<u64, { Self::KERNEL_LOG_SIZE_KEY }>,
+ mig_rm_heap_phys_addr: Key<u64, { Self::MIG_RM_HEAP_PHYS_ADDR_KEY }>,
+ mig_rm_heap_length: Key<u64, { Self::MIG_RM_HEAP_LENGTH_KEY }>,
+ }
+}
+
+impl VgpuBootloadRequest {
+ const DBDF_KEY: KeyId = 0x0001;
+ const GFID_KEY: KeyId = 0x0002;
+ const VGPU_TYPE_KEY: KeyId = 0x0003;
+ const VM_PID_KEY: KeyId = 0x0004;
+ const SWIZZ_ID_KEY: KeyId = 0x0005;
+ const NUM_CHANNELS_KEY: KeyId = 0x0006;
+ const NUM_PLUGIN_CHANNELS_KEY: KeyId = 0x0007;
+ const GUEST_FB_SEGMENT_COUNT_KEY: KeyId = 0x0008;
+ const OPTIONS_KEY: KeyId = 0x1000;
+ const GUEST_FB_SEGMENT_PHYS_ADDR_KEY: KeyId = 0x1002;
+ const GUEST_FB_SEGMENT_LENGTH_KEY: KeyId = 0x1003;
+ const PLUGIN_HEAP_PHYS_ADDR_KEY: KeyId = 0x1004;
+ const PLUGIN_HEAP_LENGTH_KEY: KeyId = 0x1005;
+ const CTRL_BUFF_OFFSET_KEY: KeyId = 0x1006;
+ const INIT_TASK_LOG_OFFSET_KEY: KeyId = 0x1007;
+ const INIT_TASK_LOG_SIZE_KEY: KeyId = 0x1008;
+ const VGPU_TASK_LOG_OFFSET_KEY: KeyId = 0x1009;
+ const VGPU_TASK_LOG_SIZE_KEY: KeyId = 0x100A;
+ const KERNEL_LOG_OFFSET_KEY: KeyId = 0x100B;
+ const KERNEL_LOG_SIZE_KEY: KeyId = 0x100C;
+ const MIG_RM_HEAP_PHYS_ADDR_KEY: KeyId = 0x100D;
+ const MIG_RM_HEAP_LENGTH_KEY: KeyId = 0x100E;
+}
+
+/// Identity, channel mapping and VRAM regions passed to a GSP plugin at boot.
+///
+/// Region addresses are physical VRAM addresses, including the log fields whose wire
+/// names contain `offset`. The control-buffer offset is relative to the plugin heap.
+pub(crate) struct BootloadInfo<'a> {
+ pub(crate) dbdf: Dbdf,
+ pub(crate) gfid: u32,
+ pub(crate) vgpu_type: u32,
+ pub(crate) vm_pid: u32,
+ pub(crate) num_channels: u32,
+ pub(crate) num_plugin_channels: u32,
+ pub(crate) channel_mapping: KVVec<ChannelMapEntry>,
+ pub(crate) guest_fb: &'a VramRegion,
+ pub(crate) plugin_heap: &'a VramRegion,
+ pub(crate) ctrl_buffer_offset: u64,
+ pub(crate) init_log: &'a VramRegion,
+ pub(crate) vgpu_log: &'a VramRegion,
+ pub(crate) kernel_log: &'a VramRegion,
+}
+
+/// Encodes a `VGPU_BOOTLOAD` request using the typed NVKV schema.
+#[expect(dead_code)]
+pub(crate) fn encode_vgpu_bootload(info: BootloadInfo<'_>) -> Result<KVVec<u64>> {
+ let request = VgpuBootloadRequest {
+ dbdf: info.dbdf.into(),
+ gfid: info.gfid.into(),
+ vgpu_type: info.vgpu_type.into(),
+ vm_pid: info.vm_pid.into(),
+ swizz_id: SwizzId::WHOLE_GPU.into(),
+ num_channels: info.num_channels.into(),
+ num_plugin_channels: info.num_plugin_channels.into(),
+ guest_fb_segment_count: 1.into(),
+ options: VgpuBootloadOptions::zeroed().into(),
+ channel_mapping: info.channel_mapping,
+ guest_fb_segment_phys_addr: Array::new(&[info.guest_fb.address()])?,
+ guest_fb_segment_length: Array::new(&[info.guest_fb.size()])?,
+ plugin_heap_phys_addr: info.plugin_heap.address().into(),
+ plugin_heap_length: info.plugin_heap.size().into(),
+ ctrl_buff_offset: info.ctrl_buffer_offset.into(),
+ init_task_log_offset: info.init_log.address().into(),
+ init_task_log_size: info.init_log.size().into(),
+ vgpu_task_log_offset: info.vgpu_log.address().into(),
+ vgpu_task_log_size: info.vgpu_log.size().into(),
+ kernel_log_offset: info.kernel_log.address().into(),
+ kernel_log_size: info.kernel_log.size().into(),
+ // The current non-SMIG firmware path does not map a separate MIG-RM heap.
+ mig_rm_heap_phys_addr: 0.into(),
+ mig_rm_heap_length: 0.into(),
+ };
+
+ let mut encoder = Encoder::new();
+ request.encode(&mut encoder)?;
+ Ok(encoder.finish())
+}
+
nvkv_decode! {
pub(crate) struct VgpuPropertiesSchema => VgpuProperties {
// TODO: `name`/`class` required?
--
2.53.0
next prev parent reply other threads:[~2026-11-06 5:45 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-06 5:39 [PATCH v4 00/32] Introduce NVIDIA vGPU manager Alok Kumar
2026-11-06 5:39 ` [PATCH v4 01/32] gpu: nova-core: mm: retain BAR1 reservations after unmap failure Alok Kumar
2026-11-06 5:39 ` [PATCH v4 02/32] gpu: nova-core: gsp: pass boot context through setup helpers Alok Kumar
2026-11-06 5:39 ` [PATCH v4 03/32] gpu: nova-core: gsp: decouple boot context from VgpuManager Alok Kumar
2026-11-06 5:39 ` [PATCH v4 04/32] gpu: nova-core: vgpu: detect boot state independently Alok Kumar
2026-11-06 5:39 ` [PATCH v4 05/32] gpu: nova-core: gpu: add a channel ID pool for vGPU Alok Kumar
2026-11-06 5:39 ` [PATCH v4 06/32] gpu: nova-core: gsp: decode the FIFO engine table Alok Kumar
2026-11-06 5:39 ` [PATCH v4 07/32] gpu: nova-core: vgpu: initialize runtime parameters after GSP boot Alok Kumar
2026-11-06 5:39 ` [PATCH v4 08/32] gpu: nova-core: vgpu: reserve the 48-VM WPR2 heap Alok Kumar
2026-11-06 5:39 ` [PATCH v4 09/32] gpu: nova-core: mm: borrow BarUser for temporary BAR1 access Alok Kumar
2026-11-06 5:39 ` [PATCH v4 10/32] gpu: nova-core: mm: add VramBlock Alok Kumar
2026-11-06 5:39 ` [PATCH v4 11/32] gpu: nova-core: mm: add VramRegion Alok Kumar
2026-11-06 5:39 ` [PATCH v4 12/32] gpu: nova-core: mm: add BarMapping Alok Kumar
2026-11-06 5:39 ` [PATCH v4 13/32] gpu: nova-core: gsp: add synchronous GMC transactions Alok Kumar
2026-11-06 5:39 ` [PATCH v4 14/32] gpu: nova-core: gsp: wait for GMC completion events Alok Kumar
2026-11-06 5:39 ` [PATCH v4 15/32] gpu: nova-core: vgpu: add r000 plugin bindings Alok Kumar
2026-11-06 5:39 ` [PATCH v4 16/32] gpu: nova-core: vgpu: add VRAM slot allocator Alok Kumar
2026-11-06 5:39 ` [PATCH v4 17/32] gpu: nova-core: gsp: factor out NVKV payload conversion Alok Kumar
2026-11-06 5:39 ` [PATCH v4 18/32] gpu: nova-core: vgpu: query VF assignments and properties Alok Kumar
2026-11-06 5:39 ` [PATCH v4 19/32] gpu: nova-core: vgpu: add instance create/destroy Alok Kumar
2026-11-06 5:39 ` Alok Kumar [this message]
2026-11-06 5:39 ` [PATCH v4 21/32] gpu: nova-core: vgpu: add GSP plugin communication buffers Alok Kumar
2026-11-06 5:39 ` [PATCH v4 22/32] gpu: nova-core: vgpu: add instance boot Alok Kumar
2026-11-06 5:39 ` [PATCH v4 23/32] gpu: nova-core: vgpu: add instance shutdown Alok Kumar
2026-11-06 5:39 ` [PATCH v4 24/32] gpu: nova-core: vgpu: initialize GSP plugin RPC buffers Alok Kumar
2026-11-06 5:39 ` [PATCH v4 25/32] gpu: nova-core: vgpu: add GSP plugin RPC transactions Alok Kumar
2026-11-06 5:39 ` [PATCH v4 26/32] gpu: nova-core: vgpu: negotiate the GSP plugin RPC version Alok Kumar
2026-11-06 5:40 ` [PATCH v4 27/32] gpu: nova-core: vgpu: send GSP plugin configuration parameters Alok Kumar
2026-11-06 5:40 ` [PATCH v4 28/32] gpu: nova-core: vgpu: update the GSP plugin BME state Alok Kumar
2026-11-06 5:40 ` [PATCH v4 29/32] gpu: nova-core: vgpu: add CeUtils commands Alok Kumar
2026-11-06 5:40 ` [PATCH v4 30/32] gpu: nova-core: vgpu: scrub guest VRAM with CeUtils Alok Kumar
2026-11-06 5:40 ` [PATCH v4 31/32] gpu: nova-core: vgpu: export plugin log buffers via debugfs Alok Kumar
2026-11-06 5:40 ` [PATCH v4 32/32] gpu: nova-core: vgpu: introduce SR-IOV PF APIs Alok Kumar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ee73ba913c15d9cdeca02da9258088333d6a2217.1793906667.git.alkumar@nvidia.com \
--to=alkumar@nvidia.com \
--cc=a.hindborg@kernel.org \
--cc=acourbot@nvidia.com \
--cc=airlied@gmail.com \
--cc=alex.gaynor@gmail.com \
--cc=alex@shazbot.org \
--cc=aliceryhl@google.com \
--cc=aniketa@nvidia.com \
--cc=ankita@nvidia.com \
--cc=apopple@nvidia.com \
--cc=bhelgaas@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=boqun@kernel.org \
--cc=cjia@nvidia.com \
--cc=dakr@kernel.org \
--cc=daniel.almeida@collabora.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=ecourtney@nvidia.com \
--cc=gary@garyguo.net \
--cc=jgg@nvidia.com \
--cc=jgg@ziepe.ca \
--cc=jhubbard@nvidia.com \
--cc=joelagnelf@nvidia.com \
--cc=kevin.tian@intel.com \
--cc=kjaju@nvidia.com \
--cc=kvm@vger.kernel.org \
--cc=kwankhede@nvidia.com \
--cc=kwilczynski@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=markus.probst@posteo.de \
--cc=nova-gpu@lists.linux.dev \
--cc=ojeda@kernel.org \
--cc=peter@colberg.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=simona@ffwll.ch \
--cc=skolothumtho@nvidia.com \
--cc=smitra@nvidia.com \
--cc=tamird@kernel.org \
--cc=targupta@nvidia.com \
--cc=tmgross@umich.edu \
--cc=work@onurozkan.dev \
--cc=xinmengs@nvidia.com \
--cc=yishaih@nvidia.com \
--cc=zhiw@nvidia.com \
--cc=zhiwang@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®