* [PATCH v4 1/6] PCI/IOV: Return unsigned int from pci_sriov_get_totalvfs()
2026-07-09 15:02 [PATCH v4 0/6] gpu: nova-core: boot GSP with vGPU enabled Zhi Wang
@ 2026-07-09 15:02 ` Zhi Wang
2026-07-09 22:46 ` Bjorn Helgaas
2026-07-09 15:02 ` [PATCH v4 2/6] rust: pci: add sriov_get_totalvfs() helper Zhi Wang
` (4 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: Zhi Wang @ 2026-07-09 15:02 UTC (permalink / raw)
To: dakr, acourbot
Cc: airlied, simona, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
lossin, a.hindborg, aliceryhl, tmgross, jhubbard, ecourtney,
joelagnelf, apopple, cjia, smitra, kjaju, alkumar, ankita,
aniketa, kwankhede, targupta, nova-gpu, linux-kernel, zhiwang,
Zhi Wang, Bjorn Helgaas, David Laight, linux-pci
pci_sriov_get_totalvfs() reports a VF count, not an errno-style
status. It returns 0 when SR-IOV is unavailable or the device is not a
PF, and otherwise returns the PF's driver_max_VFs value.
driver_max_VFs is stored as a u16 in struct pci_sriov. It is derived
from the SR-IOV TotalVFs field or from a driver-provided limit, so the
implementation cannot return a negative value.
Change the declaration, CONFIG_PCI_IOV stub, and implementation to
return unsigned int.
Suggested-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: David Laight <david.laight.linux@gmail.com>
Cc: Gary Guo <gary@garyguo.net>
Cc: linux-pci@vger.kernel.org
Link: https://lore.kernel.org/all/DJHPRE4TGGT8.BUTMYOF5YE05@nvidia.com/
Signed-off-by: Zhi Wang <zhiw@nvidia.com>
---
drivers/pci/iov.c | 2 +-
include/linux/pci.h | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index b0d24839c084..9d408fb8ac25 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -1283,7 +1283,7 @@ EXPORT_SYMBOL_GPL(pci_sriov_set_totalvfs);
* SRIOV capability value of TotalVFs or the value of driver_max_VFs
* if the driver reduced it. Otherwise 0.
*/
-int pci_sriov_get_totalvfs(struct pci_dev *dev)
+unsigned int pci_sriov_get_totalvfs(struct pci_dev *dev)
{
if (!dev->is_physfn)
return 0;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index ebb5b9d76360..2b9c61de5f67 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -2569,7 +2569,7 @@ void pci_iov_remove_virtfn(struct pci_dev *dev, int id);
int pci_num_vf(struct pci_dev *dev);
int pci_vfs_assigned(struct pci_dev *dev);
int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs);
-int pci_sriov_get_totalvfs(struct pci_dev *dev);
+unsigned int pci_sriov_get_totalvfs(struct pci_dev *dev);
int pci_sriov_configure_simple(struct pci_dev *dev, int nr_virtfn);
resource_size_t pci_iov_resource_size(const struct pci_dev *dev, int resno);
int pci_iov_vf_bar_set_size(struct pci_dev *dev, int resno, int size);
@@ -2622,7 +2622,7 @@ static inline int pci_vfs_assigned(struct pci_dev *dev)
{ return 0; }
static inline int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs)
{ return 0; }
-static inline int pci_sriov_get_totalvfs(struct pci_dev *dev)
+static inline unsigned int pci_sriov_get_totalvfs(struct pci_dev *dev)
{ return 0; }
#define pci_sriov_configure_simple NULL
static inline resource_size_t pci_iov_resource_size(const struct pci_dev *dev,
--
2.51.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH v4 1/6] PCI/IOV: Return unsigned int from pci_sriov_get_totalvfs()
2026-07-09 15:02 ` [PATCH v4 1/6] PCI/IOV: Return unsigned int from pci_sriov_get_totalvfs() Zhi Wang
@ 2026-07-09 22:46 ` Bjorn Helgaas
2026-07-09 22:58 ` Danilo Krummrich
0 siblings, 1 reply; 10+ messages in thread
From: Bjorn Helgaas @ 2026-07-09 22:46 UTC (permalink / raw)
To: Zhi Wang
Cc: dakr, acourbot, airlied, simona, ojeda, alex.gaynor, boqun.feng,
gary, bjorn3_gh, lossin, a.hindborg, aliceryhl, tmgross, jhubbard,
ecourtney, joelagnelf, apopple, cjia, smitra, kjaju, alkumar,
ankita, aniketa, kwankhede, targupta, nova-gpu, linux-kernel,
zhiwang, Bjorn Helgaas, David Laight, linux-pci
On Thu, Jul 09, 2026 at 06:02:01PM +0300, Zhi Wang wrote:
> pci_sriov_get_totalvfs() reports a VF count, not an errno-style
> status. It returns 0 when SR-IOV is unavailable or the device is not a
> PF, and otherwise returns the PF's driver_max_VFs value.
>
> driver_max_VFs is stored as a u16 in struct pci_sriov. It is derived
> from the SR-IOV TotalVFs field or from a driver-provided limit, so the
> implementation cannot return a negative value.
>
> Change the declaration, CONFIG_PCI_IOV stub, and implementation to
> return unsigned int.
>
> Suggested-by: Alexandre Courbot <acourbot@nvidia.com>
> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: David Laight <david.laight.linux@gmail.com>
> Cc: Gary Guo <gary@garyguo.net>
> Cc: linux-pci@vger.kernel.org
> Link: https://lore.kernel.org/all/DJHPRE4TGGT8.BUTMYOF5YE05@nvidia.com/
> Signed-off-by: Zhi Wang <zhiw@nvidia.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Feel free to merge via another tree, or let me know if you want me to
take just this patch via PCI.
> ---
> drivers/pci/iov.c | 2 +-
> include/linux/pci.h | 4 ++--
> 2 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
> index b0d24839c084..9d408fb8ac25 100644
> --- a/drivers/pci/iov.c
> +++ b/drivers/pci/iov.c
> @@ -1283,7 +1283,7 @@ EXPORT_SYMBOL_GPL(pci_sriov_set_totalvfs);
> * SRIOV capability value of TotalVFs or the value of driver_max_VFs
> * if the driver reduced it. Otherwise 0.
> */
> -int pci_sriov_get_totalvfs(struct pci_dev *dev)
> +unsigned int pci_sriov_get_totalvfs(struct pci_dev *dev)
> {
> if (!dev->is_physfn)
> return 0;
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index ebb5b9d76360..2b9c61de5f67 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -2569,7 +2569,7 @@ void pci_iov_remove_virtfn(struct pci_dev *dev, int id);
> int pci_num_vf(struct pci_dev *dev);
> int pci_vfs_assigned(struct pci_dev *dev);
> int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs);
> -int pci_sriov_get_totalvfs(struct pci_dev *dev);
> +unsigned int pci_sriov_get_totalvfs(struct pci_dev *dev);
> int pci_sriov_configure_simple(struct pci_dev *dev, int nr_virtfn);
> resource_size_t pci_iov_resource_size(const struct pci_dev *dev, int resno);
> int pci_iov_vf_bar_set_size(struct pci_dev *dev, int resno, int size);
> @@ -2622,7 +2622,7 @@ static inline int pci_vfs_assigned(struct pci_dev *dev)
> { return 0; }
> static inline int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs)
> { return 0; }
> -static inline int pci_sriov_get_totalvfs(struct pci_dev *dev)
> +static inline unsigned int pci_sriov_get_totalvfs(struct pci_dev *dev)
> { return 0; }
> #define pci_sriov_configure_simple NULL
> static inline resource_size_t pci_iov_resource_size(const struct pci_dev *dev,
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH v4 1/6] PCI/IOV: Return unsigned int from pci_sriov_get_totalvfs()
2026-07-09 22:46 ` Bjorn Helgaas
@ 2026-07-09 22:58 ` Danilo Krummrich
0 siblings, 0 replies; 10+ messages in thread
From: Danilo Krummrich @ 2026-07-09 22:58 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Zhi Wang, acourbot, airlied, simona, ojeda, alex.gaynor,
boqun.feng, gary, bjorn3_gh, lossin, a.hindborg, aliceryhl,
tmgross, jhubbard, ecourtney, joelagnelf, apopple, cjia, smitra,
kjaju, alkumar, ankita, aniketa, kwankhede, targupta, nova-gpu,
linux-kernel, zhiwang, Bjorn Helgaas, David Laight, linux-pci
On Fri Jul 10, 2026 at 12:46 AM CEST, Bjorn Helgaas wrote:
> Feel free to merge via another tree, or let me know if you want me to
> take just this patch via PCI.
Thanks, will take it through the drm-rust tree then.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 2/6] rust: pci: add sriov_get_totalvfs() helper
2026-07-09 15:02 [PATCH v4 0/6] gpu: nova-core: boot GSP with vGPU enabled Zhi Wang
2026-07-09 15:02 ` [PATCH v4 1/6] PCI/IOV: Return unsigned int from pci_sriov_get_totalvfs() Zhi Wang
@ 2026-07-09 15:02 ` Zhi Wang
2026-07-09 23:00 ` Danilo Krummrich
2026-07-09 15:02 ` [PATCH v4 3/6] gpu: nova-core: read vGPU mode from FSP via PRC protocol Zhi Wang
` (3 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: Zhi Wang @ 2026-07-09 15:02 UTC (permalink / raw)
To: dakr, acourbot
Cc: airlied, simona, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
lossin, a.hindborg, aliceryhl, tmgross, jhubbard, ecourtney,
joelagnelf, apopple, cjia, smitra, kjaju, alkumar, ankita,
aniketa, kwankhede, targupta, nova-gpu, linux-kernel, zhiwang,
Zhi Wang, Bjorn Helgaas, David Laight, linux-pci
Expose pci_sriov_get_totalvfs() to Rust PCI drivers so they can query
how many SR-IOV VFs a device supports.
Use a conditional C helper because the !CONFIG_PCI_IOV version of
pci_sriov_get_totalvfs() is a static inline function and is therefore
not emitted into the Rust bindings. Return Option<NonZero<u16>> so Rust
callers must handle the zero value that represents unavailable SR-IOV.
Cc: Alexandre Courbot <acourbot@nvidia.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: David Laight <david.laight.linux@gmail.com>
Cc: Gary Guo <gary@garyguo.net>
Cc: linux-pci@vger.kernel.org
Link: https://lore.kernel.org/all/DJHPRE4TGGT8.BUTMYOF5YE05@nvidia.com/
Signed-off-by: Zhi Wang <zhiw@nvidia.com>
---
rust/helpers/pci.c | 8 ++++++++
rust/kernel/pci.rs | 13 +++++++++++++
2 files changed, 21 insertions(+)
diff --git a/rust/helpers/pci.c b/rust/helpers/pci.c
index e44905317d75..4ebf256dff23 100644
--- a/rust/helpers/pci.c
+++ b/rust/helpers/pci.c
@@ -24,6 +24,14 @@ __rust_helper bool rust_helper_dev_is_pci(const struct device *dev)
return dev_is_pci(dev);
}
+#ifndef CONFIG_PCI_IOV
+__rust_helper unsigned int
+rust_helper_pci_sriov_get_totalvfs(struct pci_dev *pdev)
+{
+ return pci_sriov_get_totalvfs(pdev);
+}
+#endif
+
#ifndef CONFIG_PCI_MSI
__rust_helper int rust_helper_pci_alloc_irq_vectors(struct pci_dev *dev,
unsigned int min_vecs,
diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs
index 5071cae6543f..280e84201d9a 100644
--- a/rust/kernel/pci.rs
+++ b/rust/kernel/pci.rs
@@ -25,6 +25,7 @@
use core::{
marker::PhantomData,
mem::offset_of,
+ num::NonZero,
ptr::{
addr_of_mut,
NonNull, //
@@ -450,6 +451,18 @@ pub fn pci_class(&self) -> Class {
// SAFETY: `self.as_raw` is a valid pointer to a `struct pci_dev`.
Class::from_raw(unsafe { (*self.as_raw()).class })
}
+
+ /// Returns the total number of VFs, or [`None`] if SR-IOV is not available.
+ #[inline]
+ pub fn sriov_get_totalvfs(&self) -> Option<NonZero<u16>> {
+ // SAFETY: `self.as_raw()` is a valid pointer to a `struct pci_dev`.
+ let total_vfs = unsafe { bindings::pci_sriov_get_totalvfs(self.as_raw()) };
+
+ // CAST: The C function returns `unsigned int`, but the value originates
+ // from TotalVFs/driver_max_VFs (which are defined as `u16`), so this cast
+ // cannot truncate.
+ NonZero::new(total_vfs as u16)
+ }
}
impl<'a> Device<device::Core<'a>> {
--
2.51.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH v4 2/6] rust: pci: add sriov_get_totalvfs() helper
2026-07-09 15:02 ` [PATCH v4 2/6] rust: pci: add sriov_get_totalvfs() helper Zhi Wang
@ 2026-07-09 23:00 ` Danilo Krummrich
0 siblings, 0 replies; 10+ messages in thread
From: Danilo Krummrich @ 2026-07-09 23:00 UTC (permalink / raw)
To: Zhi Wang
Cc: acourbot, airlied, simona, ojeda, alex.gaynor, boqun.feng, gary,
bjorn3_gh, lossin, a.hindborg, aliceryhl, tmgross, jhubbard,
ecourtney, joelagnelf, apopple, cjia, smitra, kjaju, alkumar,
ankita, aniketa, kwankhede, targupta, nova-gpu, linux-kernel,
zhiwang, Bjorn Helgaas, David Laight, linux-pci
On Thu Jul 9, 2026 at 5:02 PM CEST, Zhi Wang wrote:
> + /// Returns the total number of VFs, or [`None`] if SR-IOV is not available.
> + #[inline]
> + pub fn sriov_get_totalvfs(&self) -> Option<NonZero<u16>> {
> + // SAFETY: `self.as_raw()` is a valid pointer to a `struct pci_dev`.
> + let total_vfs = unsafe { bindings::pci_sriov_get_totalvfs(self.as_raw()) };
> +
> + // CAST: The C function returns `unsigned int`, but the value originates
> + // from TotalVFs/driver_max_VFs (which are defined as `u16`), so this cast
> + // cannot truncate.
> + NonZero::new(total_vfs as u16)
> + }
> }
>
> impl<'a> Device<device::Core<'a>> {
It is not a problem yet, but sriov_get_totalvfs() should go into the
Device<Core> impl above.
Once we also have sriov_set_totalvfs() this would otherwise be a potential data
race.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 3/6] gpu: nova-core: read vGPU mode from FSP via PRC protocol
2026-07-09 15:02 [PATCH v4 0/6] gpu: nova-core: boot GSP with vGPU enabled Zhi Wang
2026-07-09 15:02 ` [PATCH v4 1/6] PCI/IOV: Return unsigned int from pci_sriov_get_totalvfs() Zhi Wang
2026-07-09 15:02 ` [PATCH v4 2/6] rust: pci: add sriov_get_totalvfs() helper Zhi Wang
@ 2026-07-09 15:02 ` Zhi Wang
2026-07-09 15:02 ` [PATCH v4 4/6] gpu: nova-core: add vGPU preludes Zhi Wang
` (2 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Zhi Wang @ 2026-07-09 15:02 UTC (permalink / raw)
To: dakr, acourbot
Cc: airlied, simona, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
lossin, a.hindborg, aliceryhl, tmgross, jhubbard, ecourtney,
joelagnelf, apopple, cjia, smitra, kjaju, alkumar, ankita,
aniketa, kwankhede, targupta, nova-gpu, linux-kernel, zhiwang,
Zhi Wang
vGPU boot needs to know whether firmware reports vGPU mode as active.
FSP's Management Partition exposes PRC (Product Reconfiguration Control)
as an API for reading device configuration knobs without firmware
updates. The vGPU mode knob is one such configuration value.
Add typed PRC request and response payloads for the vGPU mode object,
add the PRC NVDM type, and parse the returned knob value into VgpuMode.
Signed-off-by: Zhi Wang <zhiw@nvidia.com>
---
drivers/gpu/nova-core/fsp.rs | 173 ++++++++++++++++++++++++++++++++++
drivers/gpu/nova-core/mctp.rs | 2 +
2 files changed, 175 insertions(+)
diff --git a/drivers/gpu/nova-core/fsp.rs b/drivers/gpu/nova-core/fsp.rs
index afbd75879d16..3a6b02f0dc11 100644
--- a/drivers/gpu/nova-core/fsp.rs
+++ b/drivers/gpu/nova-core/fsp.rs
@@ -52,6 +52,56 @@
mod hal;
+/// PRC message sub-command.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+#[repr(u8)]
+enum PrcMessageSubcmd {
+ /// Read a PRC knob value.
+ Read = 0x0c,
+}
+
+impl From<PrcMessageSubcmd> for u8 {
+ fn from(value: PrcMessageSubcmd) -> Self {
+ value as u8
+ }
+}
+
+/// PRC object identifier.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+#[repr(u8)]
+enum PrcObjectId {
+ /// vGPU mode configuration knob.
+ VgpuMode = 0x29,
+}
+
+impl From<PrcObjectId> for u8 {
+ fn from(value: PrcObjectId) -> Self {
+ value as u8
+ }
+}
+
+kernel::impl_flags!(
+ /// PRC request flags.
+ #[derive(Clone, Copy, Default, PartialEq, Eq)]
+ struct PrcFlags(u8);
+
+ /// Individual PRC request flag.
+ #[derive(Clone, Copy, PartialEq, Eq)]
+ enum PrcFlag {
+ /// Request the active knob value for the current boot.
+ Active = 1 << 1,
+ }
+);
+
+/// vGPU operating mode as reported by FSP via the PRC protocol.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub(crate) enum VgpuMode {
+ /// vGPU support is disabled on this GPU.
+ Disabled,
+ /// vGPU support is enabled on this GPU.
+ Enabled,
+}
+
/// FSP command response payload (`NVDM_PAYLOAD_COMMAND_RESPONSE`).
#[repr(C, packed)]
#[derive(Clone, Copy)]
@@ -61,6 +111,62 @@ struct NvdmPayloadCommandResponse {
error_code: u32,
}
+/// PRC message payload.
+///
+/// Sent to FSP to query or modify a device configuration knob.
+#[repr(C, packed)]
+#[derive(Clone, Copy)]
+struct NvdmPayloadPrc {
+ sub_message_id: u8,
+ flags: u8,
+ object_id: u8,
+ reserved: u8,
+}
+
+impl NvdmPayloadPrc {
+ /// Constructs a PRC payload from typed protocol fields.
+ fn new(subcmd: PrcMessageSubcmd, object_id: PrcObjectId, flags: PrcFlags) -> Self {
+ Self {
+ sub_message_id: subcmd.into(),
+ flags: flags.into(),
+ object_id: object_id.into(),
+ reserved: 0,
+ }
+ }
+}
+
+// SAFETY: NvdmPayloadPrc is a packed C struct with only integral fields.
+unsafe impl AsBytes for NvdmPayloadPrc {}
+
+/// PRC response payload containing the knob state value.
+#[repr(C, packed)]
+#[derive(Clone, Copy)]
+struct NvdmPayloadPrcResponse {
+ value_low: u8,
+ value_high: u8,
+ reserved1: u8,
+ reserved2: u8,
+}
+
+impl NvdmPayloadPrcResponse {
+ /// Returns the PRC knob value as a little-endian 16-bit integer.
+ fn value(self) -> u16 {
+ u16::from(self.value_low) | (u16::from(self.value_high) << 8)
+ }
+}
+
+impl TryFrom<NvdmPayloadPrcResponse> for VgpuMode {
+ type Error = kernel::error::Error;
+
+ fn try_from(value: NvdmPayloadPrcResponse) -> Result<Self> {
+ match value.value() {
+ 0 => Ok(VgpuMode::Disabled),
+ 1 => Ok(VgpuMode::Enabled),
+ _ => Err(EINVAL),
+ }
+ }
+}
+
/// Common MCTP and NVDM headers shared by all FSP messages.
#[repr(C, packed)]
#[derive(Clone, Copy)]
@@ -96,6 +202,17 @@ struct FspResponseHeader {
// SAFETY: FspResponseHeader is a packed C struct with only integral fields.
unsafe impl FromBytes for FspResponseHeader {}
+/// Complete FSP PRC response including the knob state payload.
+#[repr(C, packed)]
+#[derive(Clone, Copy)]
+struct FspPrcResponse {
+ header: FspResponseHeader,
+ prc_data: NvdmPayloadPrcResponse,
+}
+
+// SAFETY: FspPrcResponse is a packed C struct with only integral fields.
+unsafe impl FromBytes for FspPrcResponse {}
+
/// Trait implemented by types representing a message to send to FSP.
///
/// This provides [`Fsp::send_sync_fsp`] with the information it needs to send
@@ -183,10 +300,35 @@ fn new<'a>(
// bytes are initialized.
unsafe impl AsBytes for FspCotMessage {}
+/// Complete FSP PRC message.
+#[repr(C, packed)]
+#[derive(Clone, Copy)]
+struct FspPrcMessage {
+ header: FspMessageHeader,
+ prc: NvdmPayloadPrc,
+}
+
+impl FspPrcMessage {
+ /// Constructs a PRC message.
+ fn new(subcmd: PrcMessageSubcmd, object_id: PrcObjectId, flags: PrcFlags) -> Self {
+ Self {
+ header: FspMessageHeader::new(NvdmType::Prc),
+ prc: NvdmPayloadPrc::new(subcmd, object_id, flags),
+ }
+ }
+}
+
+// SAFETY: FspPrcMessage is a packed C struct with only integral fields.
+unsafe impl AsBytes for FspPrcMessage {}
+
impl MessageToFsp for FspCotMessage {
const NVDM_TYPE: NvdmType = NvdmType::Cot;
}
+impl MessageToFsp for FspPrcMessage {
+ const NVDM_TYPE: NvdmType = NvdmType::Prc;
+}
+
/// Bundled arguments for FMC boot via FSP Chain of Trust.
pub(crate) struct FmcBootArgs {
chipset: Chipset,
@@ -342,6 +484,37 @@ fn send_sync_fsp<M>(&mut self, dev: &device::Device, msg: &M) -> Result<KVec<u8>
Ok(response_buf)
}
+ /// Reads the active vGPU mode from FSP using the PRC protocol.
+ ///
+ /// Queries FSP's Management Partition for the active vGPU mode knob value.
+ #[expect(dead_code)]
+ pub(crate) fn read_vgpu_mode(
+ &mut self,
+ dev: &device::Device<device::Bound>,
+ ) -> Result<VgpuMode> {
+ let msg = KBox::new(
+ FspPrcMessage::new(
+ PrcMessageSubcmd::Read,
+ PrcObjectId::VgpuMode,
+ PrcFlags::from(PrcFlag::Active),
+ ),
+ GFP_KERNEL,
+ )?;
+
+ let response_buf = self.send_sync_fsp(dev, &*msg)?;
+ let (prc_response, _) =
+ FspPrcResponse::from_bytes_prefix(&response_buf[..]).ok_or_else(|| {
+ dev_err!(dev, "PRC response too small: {}\n", response_buf.len());
+ EIO
+ })?;
+
+ let prc_data = prc_response.prc_data;
+
+ VgpuMode::try_from(prc_data).inspect_err(|_| {
+ dev_err!(dev, "Unexpected vGPU mode value: {:#x}\n", prc_data.value());
+ })
+ }
+
/// Boots GSP FMC via FSP Chain of Trust.
///
/// Builds the CoT message from the pre-configured [`FmcBootArgs`], sends it
diff --git a/drivers/gpu/nova-core/mctp.rs b/drivers/gpu/nova-core/mctp.rs
index acc2abbd4b0c..90c642c91a72 100644
--- a/drivers/gpu/nova-core/mctp.rs
+++ b/drivers/gpu/nova-core/mctp.rs
@@ -22,6 +22,8 @@
/// NVDM message type identifiers carried over MCTP.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum NvdmType with TryFrom<Bounded<u32, 8>> {
+ /// PRC (Product Reconfiguration Control) message.
+ Prc = 0x13,
/// Chain of Trust boot message.
Cot = 0x14,
/// FSP command response.
--
2.51.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v4 4/6] gpu: nova-core: add vGPU preludes
2026-07-09 15:02 [PATCH v4 0/6] gpu: nova-core: boot GSP with vGPU enabled Zhi Wang
` (2 preceding siblings ...)
2026-07-09 15:02 ` [PATCH v4 3/6] gpu: nova-core: read vGPU mode from FSP via PRC protocol Zhi Wang
@ 2026-07-09 15:02 ` Zhi Wang
2026-07-09 15:02 ` [PATCH v4 5/6] gpu: nova-core: set RMSetSriovMode for vGPU Zhi Wang
2026-07-09 15:02 ` [PATCH v4 6/6] gpu: nova-core: reserve vGPU WPR2 heap Zhi Wang
5 siblings, 0 replies; 10+ messages in thread
From: Zhi Wang @ 2026-07-09 15:02 UTC (permalink / raw)
To: dakr, acourbot
Cc: airlied, simona, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
lossin, a.hindborg, aliceryhl, tmgross, jhubbard, ecourtney,
joelagnelf, apopple, cjia, smitra, kjaju, alkumar, ankita,
aniketa, kwankhede, targupta, nova-gpu, linux-kernel, zhiwang,
Zhi Wang
GSP boot needs a stable view of vGPU state before it starts building the
boot-time data structures that depend on SR-IOV and firmware policy. That
state must be derived once from the PCI VF count and the FSP PRC vGPU mode
knob before booting GSP.
Add VgpuManager to detect and retain the vGPU state during GPU
construction. Keep the manager separate from the detected state because
later vGPU milestones will add vGPU resources and lifecycle state to it.
Keep the vGPU capability gate local to the vGPU module with per-chip HAL
modules. Treat failures to detect the optional vGPU state as disabled so
they do not prevent a bare-metal probe, and log both the failure and the
detected state where the manager is constructed.
Cc: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Zhi Wang <zhiw@nvidia.com>
---
drivers/gpu/nova-core/fsp.rs | 1 -
drivers/gpu/nova-core/gpu.rs | 7 ++
drivers/gpu/nova-core/gsp.rs | 2 +
drivers/gpu/nova-core/nova_core.rs | 1 +
drivers/gpu/nova-core/vgpu.rs | 90 +++++++++++++++++++++++++
drivers/gpu/nova-core/vgpu/hal.rs | 25 +++++++
drivers/gpu/nova-core/vgpu/hal/gb202.rs | 15 +++++
drivers/gpu/nova-core/vgpu/hal/tu102.rs | 15 +++++
8 files changed, 155 insertions(+), 1 deletion(-)
create mode 100644 drivers/gpu/nova-core/vgpu.rs
create mode 100644 drivers/gpu/nova-core/vgpu/hal.rs
create mode 100644 drivers/gpu/nova-core/vgpu/hal/gb202.rs
create mode 100644 drivers/gpu/nova-core/vgpu/hal/tu102.rs
diff --git a/drivers/gpu/nova-core/fsp.rs b/drivers/gpu/nova-core/fsp.rs
index 3a6b02f0dc11..abc161c4ba96 100644
--- a/drivers/gpu/nova-core/fsp.rs
+++ b/drivers/gpu/nova-core/fsp.rs
@@ -487,7 +487,6 @@ fn send_sync_fsp<M>(&mut self, dev: &device::Device, msg: &M) -> Result<KVec<u8>
/// Reads the active vGPU mode from FSP using the PRC protocol.
///
/// Queries FSP's Management Partition for the active vGPU mode knob value.
- #[expect(dead_code)]
pub(crate) fn read_vgpu_mode(
&mut self,
dev: &device::Device<device::Bound>,
diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
index 442c0979f9c6..42a4cd7971fa 100644
--- a/drivers/gpu/nova-core/gpu.rs
+++ b/drivers/gpu/nova-core/gpu.rs
@@ -30,6 +30,7 @@
GspBootContext, //
},
regs,
+ vgpu::VgpuManager, //
};
mod hal;
@@ -267,6 +268,8 @@ struct GspResources<'gpu> {
// TODO: use different resource types for each boot method, and make the relevant Gsp methods
// generic against them.
fsp: Option<Fsp<'gpu>>,
+ /// vGPU state detected before GSP boot.
+ vgpu: VgpuManager,
/// GSP runtime data.
#[pin]
gsp: Gsp,
@@ -311,6 +314,7 @@ fn drop(self: Pin<&mut Self>) {
gsp_falcon: &*this.gsp_falcon,
sec2_falcon: &*this.sec2_falcon,
fsp: this.fsp.as_mut(),
+ vgpu: &*this.vgpu,
},
bundle,
)
@@ -364,6 +368,8 @@ pub(crate) fn new(
fsp: Fsp::try_new(dev, bar, spec.chipset)?,
+ vgpu: VgpuManager::new(pdev, spec.chipset, fsp.as_mut()),
+
gsp <- Gsp::new(pdev),
// This member must be initialized last, so the `UnloadBundle` can never be dropped
@@ -376,6 +382,7 @@ pub(crate) fn new(
gsp_falcon,
sec2_falcon,
fsp: fsp.as_mut(),
+ vgpu,
})?,
}),
diff --git a/drivers/gpu/nova-core/gsp.rs b/drivers/gpu/nova-core/gsp.rs
index d89cc3ba7c72..164bae8b8524 100644
--- a/drivers/gpu/nova-core/gsp.rs
+++ b/drivers/gpu/nova-core/gsp.rs
@@ -49,6 +49,7 @@
},
},
num,
+ vgpu::VgpuManager, //
};
pub(crate) const GSP_PAGE_SHIFT: usize = 12;
@@ -67,6 +68,7 @@ pub(crate) struct GspBootContext<'ctx, 'gpu> {
pub(crate) gsp_falcon: &'ctx Falcon<'gpu, GspFalcon>,
pub(crate) sec2_falcon: &'ctx Falcon<'gpu, Sec2Falcon>,
pub(crate) fsp: Option<&'ctx mut Fsp<'gpu>>,
+ pub(crate) vgpu: &'ctx VgpuManager,
}
impl<'ctx, 'gpu> GspBootContext<'ctx, 'gpu> {
diff --git a/drivers/gpu/nova-core/nova_core.rs b/drivers/gpu/nova-core/nova_core.rs
index a61406ba5c0b..35a8b1214b0e 100644
--- a/drivers/gpu/nova-core/nova_core.rs
+++ b/drivers/gpu/nova-core/nova_core.rs
@@ -23,6 +23,7 @@
mod regs;
mod sbuffer;
mod vbios;
+mod vgpu;
pub(crate) const MODULE_NAME: &core::ffi::CStr = <LocalModule as kernel::ModuleMetadata>::NAME;
diff --git a/drivers/gpu/nova-core/vgpu.rs b/drivers/gpu/nova-core/vgpu.rs
new file mode 100644
index 000000000000..fcc15bddd53e
--- /dev/null
+++ b/drivers/gpu/nova-core/vgpu.rs
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0
+
+use kernel::{
+ device,
+ pci,
+ prelude::*, //
+};
+
+use crate::{
+ fsp::{
+ Fsp,
+ VgpuMode, //
+ },
+ gpu::Chipset, //
+};
+
+mod hal;
+
+/// vGPU state detected during GPU construction.
+#[derive(Debug, Clone, Copy)]
+pub(crate) enum VgpuState {
+ /// vGPU mode is not enabled for this boot.
+ Disabled,
+ /// vGPU mode is enabled for this boot.
+ Enabled {
+ /// Total number of SR-IOV VFs supported by this device.
+ total_vfs: u16,
+ },
+}
+
+/// vGPU state manager.
+pub(crate) struct VgpuManager {
+ state: VgpuState,
+}
+
+impl VgpuManager {
+ /// Creates a vGPU manager by querying SR-IOV and the FSP PRC vGPU knob.
+ pub(crate) fn new(
+ pdev: &pci::Device<device::Bound>,
+ chipset: Chipset,
+ fsp: Option<&mut Fsp<'_>>,
+ ) -> Self {
+ let state = Self::detect_state(pdev, chipset, fsp).unwrap_or_else(|e| {
+ dev_warn!(
+ pdev.as_ref(),
+ "vGPU state detection failed: {:?}; disabling vGPU\n",
+ e
+ );
+ VgpuState::Disabled
+ });
+ dev_dbg!(pdev.as_ref(), "vGPU state: {:?}\n", state);
+
+ Self { state }
+ }
+
+ /// Detects the vGPU state from the chipset, SR-IOV capability and FSP PRC knob.
+ fn detect_state(
+ pdev: &pci::Device<device::Bound>,
+ chipset: Chipset,
+ fsp: Option<&mut Fsp<'_>>,
+ ) -> Result<VgpuState> {
+ if !hal::vgpu_hal(chipset).supports_vgpu() {
+ return Ok(VgpuState::Disabled);
+ }
+
+ let Some(total_vfs) = pdev.sriov_get_totalvfs() else {
+ return Ok(VgpuState::Disabled);
+ };
+ let total_vfs = total_vfs.get();
+
+ if total_vfs < 2 {
+ // The current vGPU path does not support single-VF SR-IOV devices yet.
+ // Treat one total VF as vGPU-disabled for now; single-VF support can relax
+ // this gate once the manager handles that topology.
+ return Ok(VgpuState::Disabled);
+ }
+
+ let fsp = fsp.ok_or(ENODEV)?;
+
+ match fsp.read_vgpu_mode(pdev.as_ref())? {
+ VgpuMode::Enabled => Ok(VgpuState::Enabled { total_vfs }),
+ VgpuMode::Disabled => Ok(VgpuState::Disabled),
+ }
+ }
+
+ /// Returns the detected vGPU state for this boot.
+ pub(crate) fn state(&self) -> VgpuState {
+ self.state
+ }
+}
diff --git a/drivers/gpu/nova-core/vgpu/hal.rs b/drivers/gpu/nova-core/vgpu/hal.rs
new file mode 100644
index 000000000000..456f8fe27582
--- /dev/null
+++ b/drivers/gpu/nova-core/vgpu/hal.rs
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0
+
+use crate::gpu::{
+ Architecture,
+ Chipset, //
+};
+
+mod gb202;
+mod tu102;
+
+pub(super) trait VgpuHal {
+ /// Returns whether this chipset can support vGPU.
+ fn supports_vgpu(&self) -> bool;
+}
+
+pub(super) fn vgpu_hal(chipset: Chipset) -> &'static dyn VgpuHal {
+ match chipset.arch() {
+ Architecture::BlackwellGB20x => gb202::GB202_HAL,
+ Architecture::Turing
+ | Architecture::Ampere
+ | Architecture::Hopper
+ | Architecture::Ada
+ | Architecture::BlackwellGB10x => tu102::TU102_HAL,
+ }
+}
diff --git a/drivers/gpu/nova-core/vgpu/hal/gb202.rs b/drivers/gpu/nova-core/vgpu/hal/gb202.rs
new file mode 100644
index 000000000000..3add8af26616
--- /dev/null
+++ b/drivers/gpu/nova-core/vgpu/hal/gb202.rs
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0
+// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+
+use crate::vgpu::hal::VgpuHal;
+
+struct Gb202;
+
+impl VgpuHal for Gb202 {
+ fn supports_vgpu(&self) -> bool {
+ true
+ }
+}
+
+const GB202: Gb202 = Gb202;
+pub(super) const GB202_HAL: &dyn VgpuHal = &GB202;
diff --git a/drivers/gpu/nova-core/vgpu/hal/tu102.rs b/drivers/gpu/nova-core/vgpu/hal/tu102.rs
new file mode 100644
index 000000000000..baeea3ac5754
--- /dev/null
+++ b/drivers/gpu/nova-core/vgpu/hal/tu102.rs
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0
+// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+
+use crate::vgpu::hal::VgpuHal;
+
+struct Tu102;
+
+impl VgpuHal for Tu102 {
+ fn supports_vgpu(&self) -> bool {
+ false
+ }
+}
+
+const TU102: Tu102 = Tu102;
+pub(super) const TU102_HAL: &dyn VgpuHal = &TU102;
--
2.51.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v4 5/6] gpu: nova-core: set RMSetSriovMode for vGPU
2026-07-09 15:02 [PATCH v4 0/6] gpu: nova-core: boot GSP with vGPU enabled Zhi Wang
` (3 preceding siblings ...)
2026-07-09 15:02 ` [PATCH v4 4/6] gpu: nova-core: add vGPU preludes Zhi Wang
@ 2026-07-09 15:02 ` Zhi Wang
2026-07-09 15:02 ` [PATCH v4 6/6] gpu: nova-core: reserve vGPU WPR2 heap Zhi Wang
5 siblings, 0 replies; 10+ messages in thread
From: Zhi Wang @ 2026-07-09 15:02 UTC (permalink / raw)
To: dakr, acourbot
Cc: airlied, simona, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
lossin, a.hindborg, aliceryhl, tmgross, jhubbard, ecourtney,
joelagnelf, apopple, cjia, smitra, kjaju, alkumar, ankita,
aniketa, kwankhede, targupta, nova-gpu, linux-kernel, zhiwang,
Zhi Wang
The GSP registry setup needs to advertise SR-IOV mode when nova-core boots
GSP for an enabled vGPU configuration. Without the registry entry, GSP-RM
is not told to initialize in the mode required by NVIDIA vGPU.
Append RMSetSriovMode to the SetRegistry command when the vGPU state
detected before GSP boot is enabled. Keep the existing registry entries
unchanged for non-vGPU boots.
Cc: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Zhi Wang <zhiw@nvidia.com>
---
drivers/gpu/nova-core/gsp/boot.rs | 2 +-
drivers/gpu/nova-core/gsp/commands.rs | 14 +++++++++++++-
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/nova-core/gsp/boot.rs b/drivers/gpu/nova-core/gsp/boot.rs
index 6b7d00205000..a2e8342e7760 100644
--- a/drivers/gpu/nova-core/gsp/boot.rs
+++ b/drivers/gpu/nova-core/gsp/boot.rs
@@ -89,7 +89,7 @@ pub(crate) fn boot(
self.cmdq
.send_command_no_wait(bar, commands::SetSystemInfo::new(pdev, chipset))?;
self.cmdq
- .send_command_no_wait(bar, commands::SetRegistry::new()?)?;
+ .send_command_no_wait(bar, commands::SetRegistry::new(ctx.vgpu.state())?)?;
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 08380de39048..134f34b19174 100644
--- a/drivers/gpu/nova-core/gsp/commands.rs
+++ b/drivers/gpu/nova-core/gsp/commands.rs
@@ -34,6 +34,7 @@
},
},
sbuffer::SBufferIter,
+ vgpu::VgpuState, //
};
/// The `GspSetSystemInfo` command.
@@ -72,7 +73,7 @@ pub(crate) struct SetRegistry {
impl SetRegistry {
/// Creates a new `SetRegistry` command, using a set of hardcoded entries.
- pub(crate) fn new() -> Result<Self> {
+ pub(crate) fn new(vgpu_state: VgpuState) -> Result<Self> {
let mut entries = KVec::new();
// RMSecBusResetEnable - enables PCI secondary bus reset
@@ -104,6 +105,17 @@ pub(crate) fn new() -> Result<Self> {
GFP_KERNEL,
)?;
+ if matches!(vgpu_state, VgpuState::Enabled { .. }) {
+ // RMSetSriovMode - required when vGPU is enabled.
+ entries.push(
+ RegistryEntry {
+ key: "RMSetSriovMode",
+ value: 1,
+ },
+ GFP_KERNEL,
+ )?;
+ }
+
Ok(Self { entries })
}
}
--
2.51.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v4 6/6] gpu: nova-core: reserve vGPU WPR2 heap
2026-07-09 15:02 [PATCH v4 0/6] gpu: nova-core: boot GSP with vGPU enabled Zhi Wang
` (4 preceding siblings ...)
2026-07-09 15:02 ` [PATCH v4 5/6] gpu: nova-core: set RMSetSriovMode for vGPU Zhi Wang
@ 2026-07-09 15:02 ` Zhi Wang
5 siblings, 0 replies; 10+ messages in thread
From: Zhi Wang @ 2026-07-09 15:02 UTC (permalink / raw)
To: dakr, acourbot
Cc: airlied, simona, ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh,
lossin, a.hindborg, aliceryhl, tmgross, jhubbard, ecourtney,
joelagnelf, apopple, cjia, smitra, kjaju, alkumar, ankita,
aniketa, kwankhede, targupta, nova-gpu, linux-kernel, zhiwang,
Zhi Wang
GSP-RM needs a larger WPR2 heap when booting in vGPU mode. The heap size
is firmware-dependent, so it should come from the generated firmware
bindings instead of being open-coded in nova-core.
Pass the detected vGPU state into the framebuffer layout calculation. Keep
baremetal boots on the existing heap sizing path, and use the 570.144
vGPU default heap binding only when vGPU is enabled. The same state match
also sets the VF partition count, so disabled and invalid 0/1-VF states do
not enter the vGPU heap path.
Cc: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Zhi Wang <zhiw@nvidia.com>
---
drivers/gpu/nova-core/fb.rs | 25 +++++++++++++++----
drivers/gpu/nova-core/gsp/boot.rs | 2 +-
drivers/gpu/nova-core/gsp/fw.rs | 5 ++++
.../gpu/nova-core/gsp/fw/r570_144/bindings.rs | 1 +
4 files changed, 27 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/nova-core/fb.rs b/drivers/gpu/nova-core/fb.rs
index 273cff752fae..e93ec46a6602 100644
--- a/drivers/gpu/nova-core/fb.rs
+++ b/drivers/gpu/nova-core/fb.rs
@@ -23,7 +23,8 @@
firmware::gsp::GspFirmware,
gpu::Chipset,
gsp,
- num::FromSafeCast, //
+ num::FromSafeCast,
+ vgpu::VgpuState, //
};
mod hal;
@@ -171,7 +172,12 @@ pub(crate) struct FbLayout {
impl FbLayout {
/// Computes the FB layout for `chipset` required to run the `gsp_fw` GSP firmware.
- pub(crate) fn new(chipset: Chipset, bar: Bar0<'_>, gsp_fw: &GspFirmware) -> Result<Self> {
+ pub(crate) fn new(
+ chipset: Chipset,
+ bar: Bar0<'_>,
+ gsp_fw: &GspFirmware,
+ vgpu_state: VgpuState,
+ ) -> Result<Self> {
let hal = hal::fb_hal(chipset);
let fb = {
@@ -234,10 +240,19 @@ pub(crate) fn new(chipset: Chipset, bar: Bar0<'_>, gsp_fw: &GspFirmware) -> Resu
FbRange(elf_addr..elf_addr + elf_size)
};
+ let (vf_partition_count, wpr2_heap_size) = match vgpu_state {
+ VgpuState::Disabled => (
+ 0,
+ gsp::LibosParams::from_chipset(chipset).wpr_heap_size(chipset, fb.end)?,
+ ),
+ VgpuState::Enabled { total_vfs } => (
+ u8::try_from(total_vfs).map_err(|_| EINVAL)?,
+ gsp::LibosParams::vgpu_wpr_heap_size(),
+ ),
+ };
+
let wpr2_heap = {
const WPR2_HEAP_DOWN_ALIGN: Alignment = Alignment::new::<SZ_1M>();
- let wpr2_heap_size =
- gsp::LibosParams::from_chipset(chipset).wpr_heap_size(chipset, fb.end)?;
let wpr2_heap_addr = (elf.start - wpr2_heap_size).align_down(WPR2_HEAP_DOWN_ALIGN);
FbRange(wpr2_heap_addr..(elf.start).align_down(WPR2_HEAP_DOWN_ALIGN))
@@ -265,7 +280,7 @@ pub(crate) fn new(chipset: Chipset, bar: Bar0<'_>, gsp_fw: &GspFirmware) -> Resu
wpr2_heap,
wpr2,
heap,
- vf_partition_count: 0,
+ vf_partition_count,
pmu_reserved_size: hal.pmu_reserved_size(),
})
}
diff --git a/drivers/gpu/nova-core/gsp/boot.rs b/drivers/gpu/nova-core/gsp/boot.rs
index a2e8342e7760..727b8ae4bcb7 100644
--- a/drivers/gpu/nova-core/gsp/boot.rs
+++ b/drivers/gpu/nova-core/gsp/boot.rs
@@ -50,7 +50,7 @@ pub(crate) fn boot(
let gsp_fw = KBox::pin_init(GspFirmware::new(dev, chipset, FIRMWARE_VERSION), GFP_KERNEL)?;
- let fb_layout = FbLayout::new(chipset, bar, &gsp_fw)?;
+ let fb_layout = FbLayout::new(chipset, bar, &gsp_fw, ctx.vgpu.state())?;
dev_dbg!(dev, "{:#x?}\n", fb_layout);
let wpr_meta = Coherent::init(dev, GFP_KERNEL, GspFwWprMeta::new(&gsp_fw, &fb_layout))?;
diff --git a/drivers/gpu/nova-core/gsp/fw.rs b/drivers/gpu/nova-core/gsp/fw.rs
index 2590931262af..3088ad162706 100644
--- a/drivers/gpu/nova-core/gsp/fw.rs
+++ b/drivers/gpu/nova-core/gsp/fw.rs
@@ -178,6 +178,11 @@ pub(crate) fn from_chipset(chipset: Chipset) -> &'static LibosParams {
}
}
+ /// Returns the WPR heap size to reserve when vGPU is enabled.
+ pub(crate) fn vgpu_wpr_heap_size() -> u64 {
+ u64::from(bindings::GSP_FW_HEAP_SIZE_VGPU_DEFAULT)
+ }
+
/// Returns the amount of memory (in bytes) to allocate for the WPR heap for a framebuffer size
/// of `fb_size` (in bytes) for `chipset`.
pub(crate) fn wpr_heap_size(&self, chipset: Chipset, fb_size: u64) -> Result<u64> {
diff --git a/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs b/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
index ea350f9b2cc4..afe3e007f088 100644
--- a/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
+++ b/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
@@ -40,6 +40,7 @@ fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
pub const GSP_FW_HEAP_PARAM_BASE_RM_SIZE_GH100: u32 = 14680064;
pub const GSP_FW_HEAP_PARAM_SIZE_PER_GB_FB: u32 = 98304;
pub const GSP_FW_HEAP_PARAM_CLIENT_ALLOC_SIZE: u32 = 100663296;
+pub const GSP_FW_HEAP_SIZE_VGPU_DEFAULT: u32 = 609222656;
pub const GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS2_MIN_MB: u32 = 64;
pub const GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS2_MAX_MB: u32 = 256;
pub const GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS3_BAREMETAL_MIN_MB: u32 = 88;
--
2.51.0
^ permalink raw reply related [flat|nested] 10+ messages in thread