mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Zhi Wang <zhiw@nvidia.com>
To: <dakr@kernel.org>, <acourbot@nvidia.com>
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>,
	<jhubbard@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>, <nova-gpu@lists.linux.dev>,
	<linux-kernel@vger.kernel.org>, <zhiwang@kernel.org>,
	Zhi Wang <zhiw@nvidia.com>
Subject: [PATCH v2 32/32] gpu: nova-core: vgpu: export plugin log buffers via debugfs
Date: Mon, 14 Sep 2026 10:49:07 +0300	[thread overview]
Message-ID: <20260914074907.1399629-33-zhiw@nvidia.com> (raw)
In-Reply-To: <20260914074907.1399629-1-zhiw@nvidia.com>

Expose the three per-VM GSP plugin log buffers (init, vgpu, kernel)
through debugfs so that nvlog_decoder can decode them at runtime.

Each log file is backed by VRAM in the management heap and read via
BAR1 MMIO. Prepend the GSP log header when a firmware build ID is
available.

Signed-off-by: Zhi Wang <zhiw@nvidia.com>
---
 drivers/gpu/nova-core/gsp.rs                  |   4 +-
 drivers/gpu/nova-core/mm/bar_user.rs          |   5 +-
 drivers/gpu/nova-core/vgpu.rs                 |   1 +
 drivers/gpu/nova-core/vgpu/gsp_plugin_comm.rs | 120 +++++++++++-
 drivers/gpu/nova-core/vgpu/instance.rs        |  77 +++++++-
 drivers/gpu/nova-core/vgpu/log.rs             | 171 ++++++++++++++++++
 6 files changed, 364 insertions(+), 14 deletions(-)
 create mode 100644 drivers/gpu/nova-core/vgpu/log.rs

diff --git a/drivers/gpu/nova-core/gsp.rs b/drivers/gpu/nova-core/gsp.rs
index 0bf4c8ee96ee..96ee879ce268 100644
--- a/drivers/gpu/nova-core/gsp.rs
+++ b/drivers/gpu/nova-core/gsp.rs
@@ -115,7 +115,7 @@ fn init(view: CoherentView<'_, Self>, start: DmaAddress) -> Result<()> {
 /// This header makes each dump self-describing so that decoding tools can
 /// identify the firmware build, GPU architecture, and metadata format without
 /// out-of-band information.
-const LOG_BUFFER_HEADER_SIZE: usize = 0x48;
+pub(crate) const LOG_BUFFER_HEADER_SIZE: usize = 0x48;
 
 /// Build a log buffer header from GPU and firmware metadata.
 ///
@@ -129,7 +129,7 @@ fn init(view: CoherentView<'_, Self>, start: DmaAddress) -> Result<()> {
 ///   0x20  buildId[32]
 ///   0x40  flags (u32) = 1 (packed metadata)
 ///   0x44  reserved (u32) = 0
-fn build_log_buffer_header(
+pub(crate) fn build_log_buffer_header(
     chipset: Chipset,
     build_id: &BuildId,
     task_prefix: &str,
diff --git a/drivers/gpu/nova-core/mm/bar_user.rs b/drivers/gpu/nova-core/mm/bar_user.rs
index b7b4bf14b56d..2e9482256b16 100644
--- a/drivers/gpu/nova-core/mm/bar_user.rs
+++ b/drivers/gpu/nova-core/mm/bar_user.rs
@@ -188,7 +188,6 @@ pub(crate) struct BarMapping<'map, 'gpu> {
     logical_size: usize,
 }
 
-#[expect(dead_code)]
 impl<'map, 'gpu> BarMapping<'map, 'gpu> {
     /// Maps the containing pages while restricting CPU access to the requested byte range.
     pub(crate) fn new(
@@ -231,6 +230,10 @@ pub(crate) fn new(
         })
     }
 
+    pub(crate) fn bar1(&self) -> &'gpu Bar1<'gpu> {
+        self.access.bar_user.bar1
+    }
+
     pub(crate) fn region(&self) -> &VramRegion {
         &self.region
     }
diff --git a/drivers/gpu/nova-core/vgpu.rs b/drivers/gpu/nova-core/vgpu.rs
index 407accc05139..123f5a20986e 100644
--- a/drivers/gpu/nova-core/vgpu.rs
+++ b/drivers/gpu/nova-core/vgpu.rs
@@ -28,6 +28,7 @@
 mod gsp_plugin_rpc;
 mod hal;
 mod instance;
+mod log;
 mod scrubber;
 mod vram;
 
diff --git a/drivers/gpu/nova-core/vgpu/gsp_plugin_comm.rs b/drivers/gpu/nova-core/vgpu/gsp_plugin_comm.rs
index e385ecff43fa..7aa9e9caaa49 100644
--- a/drivers/gpu/nova-core/vgpu/gsp_plugin_comm.rs
+++ b/drivers/gpu/nova-core/vgpu/gsp_plugin_comm.rs
@@ -3,15 +3,21 @@
 
 //! GSP plugin communication buffer mappings and access.
 
-use kernel::prelude::*;
+use kernel::{
+    io::Io,
+    prelude::*, //
+};
 
-use crate::mm::{
-    bar_user::{
-        BarMapping,
-        BarUser, //
+use crate::{
+    driver::Bar1,
+    mm::{
+        bar_user::{
+            BarMapping,
+            BarUser, //
+        },
+        vram::VramRegion,
+        GpuMm, //
     },
-    vram::VramRegion,
-    GpuMm, //
 };
 
 use super::fw::{
@@ -50,6 +56,97 @@ fn take_region(region: &VramRegion, cursor: &mut u64, size: u32) -> Result<VramR
     Ok(subregion)
 }
 
+/// BAR1 view of one vGPU plugin log buffer.
+pub(super) struct MappedPluginLogBuffer<'gpu> {
+    bar1: &'gpu Bar1<'gpu>,
+    gpu_va_addr: usize,
+    size: usize,
+}
+
+impl<'gpu> MappedPluginLogBuffer<'gpu> {
+    fn new(map: &BarMapping<'_, 'gpu>, region: &VramRegion) -> Result<Self> {
+        let start = region
+            .address()
+            .checked_sub(map.region().address())
+            .ok_or(EINVAL)
+            .and_then(|start| usize::try_from(start).map_err(|_| EOVERFLOW))?;
+        let size = usize::try_from(region.size()).map_err(|_| EOVERFLOW)?;
+        let end = start.checked_add(size).ok_or(EOVERFLOW)?;
+        if end > map.size() || !start.is_multiple_of(4) || !size.is_multiple_of(4) {
+            return Err(EINVAL);
+        }
+
+        let gpu_va_addr = usize::try_from(map.gpu_va_addr()?)
+            .map_err(|_| EOVERFLOW)?
+            .checked_add(start)
+            .ok_or(EOVERFLOW)?;
+        if !gpu_va_addr.is_multiple_of(4) {
+            return Err(EINVAL);
+        }
+
+        let bar1 = map.bar1();
+        if gpu_va_addr.checked_add(size).ok_or(EOVERFLOW)? > bar1.size() {
+            return Err(EINVAL);
+        }
+
+        Ok(Self {
+            bar1,
+            gpu_va_addr,
+            size,
+        })
+    }
+
+    pub(super) const fn size(&self) -> usize {
+        self.size
+    }
+
+    pub(super) fn read(&self, offset: usize, output: &mut [u8]) -> Result {
+        let end = offset.checked_add(output.len()).ok_or(EOVERFLOW)?;
+        if end > self.size {
+            return Err(EINVAL);
+        }
+
+        let mut source = offset;
+        let mut copied = 0usize;
+
+        while copied < output.len() {
+            let aligned_source = source & !3;
+            let within = source & 3;
+            let bar_offset = self
+                .gpu_va_addr
+                .checked_add(aligned_source)
+                .ok_or(EOVERFLOW)?;
+            let bytes = self.bar1.try_read32(bar_offset)?.to_le_bytes();
+            let chunk = (4 - within).min(output.len() - copied);
+
+            output[copied..copied + chunk].copy_from_slice(&bytes[within..within + chunk]);
+            source = source.checked_add(chunk).ok_or(EOVERFLOW)?;
+            copied += chunk;
+        }
+
+        Ok(())
+    }
+}
+
+/// BAR1 views of all vGPU plugin log buffers.
+pub(super) struct MappedPluginLogBuffers<'gpu> {
+    init: MappedPluginLogBuffer<'gpu>,
+    vgpu: MappedPluginLogBuffer<'gpu>,
+    kernel: MappedPluginLogBuffer<'gpu>,
+}
+
+impl<'gpu> MappedPluginLogBuffers<'gpu> {
+    pub(super) fn into_parts(
+        self,
+    ) -> (
+        MappedPluginLogBuffer<'gpu>,
+        MappedPluginLogBuffer<'gpu>,
+        MappedPluginLogBuffer<'gpu>,
+    ) {
+        (self.init, self.vgpu, self.kernel)
+    }
+}
+
 /// BAR1 mapping of the plugin communication region in its management heap.
 ///
 /// r000 layout, with byte offsets from the management heap (not to scale):
@@ -216,6 +313,15 @@ pub(super) fn plugin_logs(&self) -> PluginLogRegions {
         }
     }
 
+    /// Return BAR1 views that must stop being read before this mapping is destroyed.
+    pub(super) fn mapped_plugin_logs(&self) -> Result<MappedPluginLogBuffers<'gpu>> {
+        Ok(MappedPluginLogBuffers {
+            init: MappedPluginLogBuffer::new(&self.map, &self.init_log)?,
+            vgpu: MappedPluginLogBuffer::new(&self.map, &self.vgpu_log)?,
+            kernel: MappedPluginLogBuffer::new(&self.map, &self.kernel_log)?,
+        })
+    }
+
     /// Clear a previous boot marker before starting the plugin.
     pub(super) fn clear_plugin_ready(&self) -> Result {
         let offset = self.io_offset(
diff --git a/drivers/gpu/nova-core/vgpu/instance.rs b/drivers/gpu/nova-core/vgpu/instance.rs
index bb01d4088b5e..7f47c158d407 100644
--- a/drivers/gpu/nova-core/vgpu/instance.rs
+++ b/drivers/gpu/nova-core/vgpu/instance.rs
@@ -4,10 +4,12 @@
 use core::num::NonZeroUsize;
 
 use kernel::{
+    debugfs,
     device,
     prelude::*,
     ptr::Alignment,
-    sizes::SizeConstants, //
+    sizes::SizeConstants,
+    str::CString, //
     time::{
         delay::fsleep,
         Delta,
@@ -23,7 +25,11 @@
 
 use crate::{
     driver::Bar0,
-    gpu::ChannelIdReservation,
+    firmware::BuildId,
+    gpu::{
+        ChannelIdReservation,
+        Chipset, //
+    },
     mm::{
         bar_user::BarUser,
         GpuMm, //
@@ -31,8 +37,12 @@
 };
 
 use super::{
-    gsp_plugin_comm::CommBufferRegion,
+    gsp_plugin_comm::{
+        CommBufferRegion,
+        MappedPluginLogBuffers, //
+    },
     gsp_plugin_rpc::PluginRpc,
+    log::VgpuLogBuffers,
     scrubber::CeUtils,
     vram::{
         VgpuVramLayout,
@@ -143,6 +153,7 @@ pub(super) struct VgpuInstance<'gpu> {
     vm_pid: u32,
     chids: ChannelIdReservation<'gpu>,
     num_plugin_channels: u32,
+    debugfs_logs: Option<Pin<KBox<debugfs::Scope<VgpuLogBuffers<'gpu>>>>>,
     vram_slot: VgpuVramSlot,
     pub(super) plugin_rpc: PluginRpc<'gpu, 'gpu>,
     ceutils: Option<CeUtils>,
@@ -246,6 +257,39 @@ pub(super) const fn new(gfid: Gfid, dbdf: Dbdf, vgpu_type: VgpuType, vm_pid: u32
     }
 }
 
+fn create_debugfs_logs<'gpu>(
+    buffers: MappedPluginLogBuffers<'gpu>,
+    dbdf: Dbdf,
+    chipset: Chipset,
+    build_id: Option<&BuildId>,
+) -> Result<Pin<KBox<debugfs::Scope<VgpuLogBuffers<'gpu>>>>> {
+    let logs = VgpuLogBuffers::new(buffers, chipset, build_id);
+    let raw_dbdf = dbdf.into_raw();
+    let domain = raw_dbdf >> 16;
+    let bus = (raw_dbdf >> 8) & 0xff;
+    let device = (raw_dbdf >> 3) & 0x1f;
+    let function = raw_dbdf & 0x07;
+    let directory = CString::try_from_fmt(fmt!(
+        "{:04x}:{:02x}:{:02x}.{:x}-vgpu",
+        domain,
+        bus,
+        device,
+        function,
+    ))?;
+
+    #[allow(static_mut_refs)]
+    // SAFETY: The root is initialized before driver registration and cleared
+    // only after driver unregistration has drained all users.
+    let root = unsafe { crate::DEBUGFS_ROOT.as_ref() }.ok_or(ENODEV)?;
+
+    KBox::pin_init(
+        root.scope(logs, &directory, |logs, directory| {
+            VgpuLogBuffers::register_debugfs(logs, directory);
+        }),
+        GFP_KERNEL,
+    )
+}
+
 /// Registry of live vGPU instances.
 pub(super) struct VgpuInstances<'gpu> {
     instances: KVec<VgpuInstance<'gpu>>,
@@ -287,10 +331,12 @@ fn release_vram_slot(&mut self, slot: VgpuVramSlot) -> Result {
 
     fn release_instance(&mut self, instance: VgpuInstance<'gpu>, mm: &mut GpuMm<'_>) -> Result {
         let VgpuInstance {
+            debugfs_logs,
             plugin_rpc,
             vram_slot,
             ..
         } = instance;
+        drop(debugfs_logs);
         let result = plugin_rpc.destroy(mm);
         self.release_vram_slot(vram_slot)?;
         result
@@ -369,6 +415,7 @@ pub(super) fn allocate_instance(
             vm_pid,
             chids,
             num_plugin_channels: 3,
+            debugfs_logs: None,
             vram_slot,
             plugin_rpc: PluginRpc::new(comm),
             ceutils: None,
@@ -407,6 +454,7 @@ pub(super) fn allocate_instance(
     }
 
     /// Boot and configure the GSP plugin for a registered instance.
+    #[expect(clippy::too_many_arguments)]
     pub(super) fn activate_instance(
         &mut self,
         dev: &device::Device<device::Bound>,
@@ -414,6 +462,8 @@ pub(super) fn activate_instance(
         bar0: Bar0<'_>,
         gfid: Gfid,
         fifo_engine_list: &FifoEngineList,
+        chipset: Chipset,
+        build_id: Option<&BuildId>,
     ) -> Result {
         let instance = self
             .instances
@@ -428,7 +478,26 @@ pub(super) fn activate_instance(
         instance.plugin_rpc.init_rpc()?;
         negotiate_plugin_version(dev, bar0, gfid, &mut instance.plugin_rpc)?;
         instance.configure_plugin(dev, bar0)?;
-        set_plugin_bme(dev, bar0, gfid, &mut instance.plugin_rpc, true)
+        set_plugin_bme(dev, bar0, gfid, &mut instance.plugin_rpc, true)?;
+
+        if instance.debugfs_logs.is_none() {
+            match instance
+                .plugin_rpc
+                .comm()
+                .mapped_plugin_logs()
+                .and_then(|buffers| create_debugfs_logs(buffers, instance.dbdf, chipset, build_id))
+            {
+                Ok(logs) => instance.debugfs_logs = Some(logs),
+                Err(error) => dev_warn!(
+                    dev,
+                    "debugfs logs unavailable for gfid={}: {:?}\n",
+                    gfid.0,
+                    error,
+                ),
+            }
+        }
+
+        Ok(())
     }
 
     /// Stop the plugin and release the instance's firmware and host resources.
diff --git a/drivers/gpu/nova-core/vgpu/log.rs b/drivers/gpu/nova-core/vgpu/log.rs
new file mode 100644
index 000000000000..6f58f8ae9bf0
--- /dev/null
+++ b/drivers/gpu/nova-core/vgpu/log.rs
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: GPL-2.0
+// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+
+//! GSP plugin logs exposed through debugfs.
+//!
+//! With debugfs mounted at `/sys/kernel/debug`, the directory uses the VF's
+//! PCI domain:bus:device.function address:
+//!
+//! ```text
+//! /sys/kernel/debug/nova-core/<VF-DBDF>-vgpu/
+//! |-- init_log
+//! |-- vgpu_log
+//! `-- kernel_log
+//! ```
+
+use kernel::{
+    debugfs,
+    fs::file,
+    prelude::*,
+    uaccess::UserSliceWriter, //
+};
+
+use crate::{
+    firmware::BuildId,
+    gpu::Chipset,
+    gsp::{
+        build_log_buffer_header,
+        LOG_BUFFER_HEADER_SIZE, //
+    },
+    vgpu::gsp_plugin_comm::{
+        MappedPluginLogBuffer,
+        MappedPluginLogBuffers, //
+    },
+};
+
+const LOG_READ_CHUNK_SIZE: usize = 4096;
+
+/// A vGPU plugin log buffer backed by VRAM, read via BAR1 MMIO.
+///
+/// An optional header lets `nvlog_decoder` identify the GPU architecture and firmware build.
+struct VgpuLogBuffer<'gpu> {
+    buffer: MappedPluginLogBuffer<'gpu>,
+    header: [u8; LOG_BUFFER_HEADER_SIZE],
+    header_len: usize,
+}
+
+impl<'gpu> VgpuLogBuffer<'gpu> {
+    fn new(
+        buffer: MappedPluginLogBuffer<'gpu>,
+        chipset: Chipset,
+        build_id: Option<&BuildId>,
+        task_prefix: &str,
+    ) -> Self {
+        let (header, header_len) = match build_id {
+            Some(bid) => (
+                build_log_buffer_header(chipset, bid, task_prefix),
+                LOG_BUFFER_HEADER_SIZE,
+            ),
+            None => ([0u8; LOG_BUFFER_HEADER_SIZE], 0),
+        };
+
+        Self {
+            buffer,
+            header,
+            header_len,
+        }
+    }
+}
+
+impl debugfs::BinaryWriter for VgpuLogBuffer<'_> {
+    fn write_to_slice(
+        &self,
+        writer: &mut UserSliceWriter,
+        offset: &mut file::Offset,
+    ) -> Result<usize> {
+        if offset.is_negative() {
+            return Err(EINVAL);
+        }
+
+        let offset_val: usize = (*offset).try_into().map_err(|_| EINVAL)?;
+        let total_len = self
+            .header_len
+            .checked_add(self.buffer.size())
+            .ok_or(EOVERFLOW)?;
+
+        if offset_val >= total_len {
+            return Ok(0);
+        }
+
+        let count = (total_len - offset_val).min(writer.len());
+        if count == 0 {
+            return Ok(0);
+        }
+
+        // Keep the staging buffer on the heap to avoid a page-sized kernel stack object.
+        let staging_size = count.min(LOG_READ_CHUNK_SIZE);
+        let mut staging = KVec::new();
+        staging.resize(staging_size, 0, GFP_KERNEL)?;
+
+        let mut written = 0usize;
+        let result: Result = (|| {
+            while written < count {
+                let chunk_len = (count - written).min(staging.len());
+                let chunk = &mut staging[..chunk_len];
+                let chunk_offset = offset_val.checked_add(written).ok_or(EOVERFLOW)?;
+                let mut filled = 0usize;
+
+                if chunk_offset < self.header_len {
+                    let header_len = (self.header_len - chunk_offset).min(chunk_len);
+                    chunk[..header_len]
+                        .copy_from_slice(&self.header[chunk_offset..chunk_offset + header_len]);
+                    filled = header_len;
+                }
+
+                if filled < chunk_len {
+                    let log_offset = chunk_offset
+                        .checked_add(filled)
+                        .ok_or(EOVERFLOW)?
+                        .checked_sub(self.header_len)
+                        .ok_or(EINVAL)?;
+
+                    self.buffer.read(log_offset, &mut chunk[filled..])?;
+                }
+
+                writer.write_slice(chunk)?;
+                written = written.checked_add(chunk_len).ok_or(EOVERFLOW)?;
+            }
+            Ok(())
+        })();
+        if written == 0 {
+            result?;
+        }
+
+        *offset = (*offset)
+            .checked_add(i64::try_from(written).map_err(|_| EOVERFLOW)?)
+            .ok_or(EOVERFLOW)?;
+        Ok(written)
+    }
+}
+
+/// The three plugin log streams for one vGPU instance.
+pub(super) struct VgpuLogBuffers<'gpu> {
+    init_log: VgpuLogBuffer<'gpu>,
+    vgpu_log: VgpuLogBuffer<'gpu>,
+    kernel_log: VgpuLogBuffer<'gpu>,
+}
+
+impl<'gpu> VgpuLogBuffers<'gpu> {
+    pub(super) fn new(
+        buffers: MappedPluginLogBuffers<'gpu>,
+        chipset: Chipset,
+        build_id: Option<&BuildId>,
+    ) -> Self {
+        let (init, vgpu, kernel) = buffers.into_parts();
+
+        Self {
+            init_log: VgpuLogBuffer::new(init, chipset, build_id, "INIT"),
+            vgpu_log: VgpuLogBuffer::new(vgpu, chipset, build_id, "VGPU"),
+            kernel_log: VgpuLogBuffer::new(kernel, chipset, build_id, "KERN"),
+        }
+    }
+
+    pub(super) fn register_debugfs<'data, 'dir>(
+        logs: &'data Self,
+        dir: &'dir debugfs::ScopedDir<'data, 'dir>,
+    ) {
+        dir.read_binary_file(c"init_log", &logs.init_log);
+        dir.read_binary_file(c"vgpu_log", &logs.vgpu_log);
+        dir.read_binary_file(c"kernel_log", &logs.kernel_log);
+    }
+}

      parent reply	other threads:[~2026-09-14  7:54 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-14  7:48 [PATCH v2 00/32] Introduce NVIDIA vGPU manager Zhi Wang
2026-09-14  7:48 ` [PATCH v2 01/32] gpu: nova-core: gsp: pass boot context through setup helpers Zhi Wang
2026-09-14  7:48 ` [PATCH v2 02/32] gpu: nova-core: gsp: decouple boot context from VgpuManager Zhi Wang
2026-09-14  7:48 ` [PATCH v2 03/32] gpu: nova-core: vgpu: detect boot state independently Zhi Wang
2026-09-14  7:48 ` [PATCH v2 04/32] gpu: nova-core: gpu: add a channel ID pool for vGPU Zhi Wang
2026-09-14  7:48 ` [PATCH v2 05/32] gpu: nova-core: gsp: expose the VMMU segment size Zhi Wang
2026-09-14  7:48 ` [PATCH v2 06/32] gpu: nova-core: gsp: decode the FIFO engine table Zhi Wang
2026-09-14  7:48 ` [PATCH v2 07/32] gpu: nova-core: vgpu: initialize runtime parameters after GSP boot Zhi Wang
2026-09-14  7:48 ` [PATCH v2 08/32] gpu: nova-core: vgpu: reserve the 48-VM WPR2 heap Zhi Wang
2026-09-14  7:48 ` [PATCH v2 09/32] gpu: nova-core: mm: borrow BarUser for temporary BAR1 access Zhi Wang
2026-09-14  7:48 ` [PATCH v2 10/32] gpu: nova-core: mm: add VramBlock Zhi Wang
2026-09-14  7:48 ` [PATCH v2 11/32] gpu: nova-core: mm: add VramRegion Zhi Wang
2026-09-14  7:48 ` [PATCH v2 12/32] gpu: nova-core: mm: add BarMapping Zhi Wang
2026-09-14  7:48 ` [PATCH v2 13/32] gpu: nova-core: gsp: dispatch RM RPC messages during GMC receive Zhi Wang
2026-09-14  7:48 ` [PATCH v2 14/32] gpu: nova-core: gsp: add synchronous GMC transactions Zhi Wang
2026-09-14  7:48 ` [PATCH v2 15/32] gpu: nova-core: gsp: add status-only " Zhi Wang
2026-09-14  7:48 ` [PATCH v2 16/32] gpu: nova-core: gsp: wait for GMC completion events Zhi Wang
2026-09-14  7:48 ` [PATCH v2 17/32] gpu: nova-core: vgpu: add r000 plugin bindings Zhi Wang
2026-09-14  7:48 ` [PATCH v2 18/32] gpu: nova-core: vgpu: add VRAM slot allocator Zhi Wang
2026-09-14  7:48 ` [PATCH v2 19/32] gpu: nova-core: gsp: factor out NVKV payload conversion Zhi Wang
2026-09-14  7:48 ` [PATCH v2 20/32] gpu: nova-core: vgpu: query VF assignments and properties Zhi Wang
2026-09-14  7:48 ` [PATCH v2 21/32] gpu: nova-core: vgpu: add instance create/destroy Zhi Wang
2026-09-14  7:48 ` [PATCH v2 22/32] gpu: nova-core: vgpu: encode vGPU boot requests Zhi Wang
2026-09-14  7:48 ` [PATCH v2 23/32] gpu: nova-core: vgpu: add GSP plugin communication buffers Zhi Wang
2026-09-14  7:48 ` [PATCH v2 24/32] gpu: nova-core: vgpu: add instance boot and shutdown Zhi Wang
2026-09-14  7:49 ` [PATCH v2 25/32] gpu: nova-core: vgpu: initialize GSP plugin RPC buffers Zhi Wang
2026-09-14  7:49 ` [PATCH v2 26/32] gpu: nova-core: vgpu: add GSP plugin RPC transactions Zhi Wang
2026-09-14  7:49 ` [PATCH v2 27/32] gpu: nova-core: vgpu: negotiate the GSP plugin RPC version Zhi Wang
2026-09-14  7:49 ` [PATCH v2 28/32] gpu: nova-core: vgpu: send GSP plugin configuration parameters Zhi Wang
2026-09-14  7:49 ` [PATCH v2 29/32] gpu: nova-core: vgpu: update the GSP plugin BME state Zhi Wang
2026-09-14  7:49 ` [PATCH v2 30/32] gpu: nova-core: vgpu: scrub guest VRAM with CeUtils Zhi Wang
2026-09-14  7:49 ` [PATCH v2 31/32] gpu: nova-core: add build ID headers to debugfs log buffer dumps Zhi Wang
2026-09-14  7:49 ` Zhi Wang [this message]

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=20260914074907.1399629-33-zhiw@nvidia.com \
    --to=zhiw@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=alkumar@nvidia.com \
    --cc=aniketa@nvidia.com \
    --cc=ankita@nvidia.com \
    --cc=bjorn3_gh@protonmail.com \
    --cc=boqun.feng@gmail.com \
    --cc=cjia@nvidia.com \
    --cc=dakr@kernel.org \
    --cc=ecourtney@nvidia.com \
    --cc=gary@garyguo.net \
    --cc=jgg@nvidia.com \
    --cc=jhubbard@nvidia.com \
    --cc=kevin.tian@intel.com \
    --cc=kjaju@nvidia.com \
    --cc=kwankhede@nvidia.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lossin@kernel.org \
    --cc=nova-gpu@lists.linux.dev \
    --cc=ojeda@kernel.org \
    --cc=simona@ffwll.ch \
    --cc=skolothumtho@nvidia.com \
    --cc=smitra@nvidia.com \
    --cc=targupta@nvidia.com \
    --cc=tmgross@umich.edu \
    --cc=yishaih@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®