91 lines · 2.3 KB · Rust
RawDownload
// SPDX-License-Identifier: GPL-2.0 use core::num::NonZero; 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: NonZero<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::Core<'_>>,        chipset: Chipset,        fsp: Option<&mut Fsp<'_>>,    ) -> Self {        let state = Self::detect_state(pdev, chipset, fsp).unwrap_or_else(|e| {            dev_warn!(                pdev,                "vGPU state detection failed: {:?}; disabling vGPU\n",                e            );            VgpuState::Disabled        });        dev_dbg!(pdev, "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::Core<'_>>,        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);        };         if total_vfs.get() < 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    }}