All the resources that required by a new vGPU has been set up. It is time
to activate it.

Send the NV2080_CTRL_CMD_VGPU_MGR_INTERNAL_BOOTLOAD_GSP_VGPU_PLUGIN_TASK
GSP RPC to activate the new vGPU.

Signed-off-by: Zhi Wang <z...@nvidia.com>
---
 .../ctrl/ctrl2080/ctrl2080vgpumgrinternal.h   | 90 ++++++++++++++++++
 drivers/vfio/pci/nvidia-vgpu/nvkm.h           |  3 +
 drivers/vfio/pci/nvidia-vgpu/vgpu.c           | 94 +++++++++++++++++++
 3 files changed, 187 insertions(+)

diff --git 
a/drivers/vfio/pci/nvidia-vgpu/include/nvrm/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080vgpumgrinternal.h
 
b/drivers/vfio/pci/nvidia-vgpu/include/nvrm/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080vgpumgrinternal.h
index f44cdc733229..58c6bff72f44 100644
--- 
a/drivers/vfio/pci/nvidia-vgpu/include/nvrm/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080vgpumgrinternal.h
+++ 
b/drivers/vfio/pci/nvidia-vgpu/include/nvrm/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080vgpumgrinternal.h
@@ -59,4 +59,94 @@ typedef struct 
NV2080_CTRL_VGPU_MGR_INTERNAL_PGPU_ADD_VGPU_TYPE_PARAMS {
        NV_DECLARE_ALIGNED(NVA081_CTRL_VGPU_INFO 
vgpuInfo[NVA081_MAX_VGPU_TYPES_PER_PGPU], 8);
 } NV2080_CTRL_VGPU_MGR_INTERNAL_PGPU_ADD_VGPU_TYPE_PARAMS;
 
+/*
+ * NV2080_CTRL_CMD_VGPU_MGR_INTERNAL_BOOTLOAD_GSP_VGPU_PLUGIN_TASK
+ *
+ * This command is used to bootload GSP VGPU plugin task.
+ * Can be called only with SR-IOV and with VGPU_GSP_PLUGIN_OFFLOAD feature.
+ *
+ * dbdf                        - domain (31:16), bus (15:8), device (7:3), 
function (2:0)
+ * gfid                        - Gfid
+ * vgpuType                    - The Type ID for VGPU profile
+ * vmPid                       - Plugin process ID of vGPU guest instance
+ * swizzId                     - SwizzId
+ * numChannels                 - Number of channels
+ * numPluginChannels           - Number of plugin channels
+ * bDisableSmcPartitionRestore - If set to true, SMC default execution 
partition
+ *                               save/restore will not be done in host-RM
+ * guestFbPhysAddrList         - list of VMMU segment aligned physical address 
of guest FB memory
+ * guestFbLengthList           - list of guest FB memory length in bytes
+ * pluginHeapMemoryPhysAddr    - plugin heap memory offset
+ * pluginHeapMemoryLength      - plugin heap memory length in bytes
+ * bDeviceProfilingEnabled     - If set to true, profiling is allowed
+ */
+#define NV2080_CTRL_CMD_VGPU_MGR_INTERNAL_BOOTLOAD_GSP_VGPU_PLUGIN_TASK 
(0x20804001) /* finn: Evaluated from 
"(FINN_NV20_SUBDEVICE_0_VGPU_MGR_INTERNAL_INTERFACE_ID << 8) | 
NV2080_CTRL_VGPU_MGR_INTERNAL_BOOTLOAD_GSP_VGPU_PLUGIN_TASK_PARAMS_MESSAGE_ID" 
*/
+
+#define NV2080_CTRL_MAX_VMMU_SEGMENTS                                   384
+
+/* Must match NV2080_ENGINE_TYPE_LAST from cl2080.h */
+#define NV2080_GPU_MAX_ENGINES                                          0x3e
+
+#define 
NV2080_CTRL_VGPU_MGR_INTERNAL_BOOTLOAD_GSP_VGPU_PLUGIN_TASK_PARAMS_MESSAGE_ID 
(0x1U)
+
+typedef struct 
NV2080_CTRL_VGPU_MGR_INTERNAL_BOOTLOAD_GSP_VGPU_PLUGIN_TASK_PARAMS {
+       NvU32  dbdf;
+       NvU32  gfid;
+       NvU32  vgpuType;
+       NvU32  vmPid;
+       NvU32  swizzId;
+       NvU32  numChannels;
+       NvU32  numPluginChannels;
+       NvU32  chidOffset[NV2080_GPU_MAX_ENGINES];
+       NvBool bDisableDefaultSmcExecPartRestore;
+       NvU32  numGuestFbSegments;
+       NV_DECLARE_ALIGNED(NvU64 
guestFbPhysAddrList[NV2080_CTRL_MAX_VMMU_SEGMENTS], 8);
+       NV_DECLARE_ALIGNED(NvU64 
guestFbLengthList[NV2080_CTRL_MAX_VMMU_SEGMENTS], 8);
+       NV_DECLARE_ALIGNED(NvU64 pluginHeapMemoryPhysAddr, 8);
+       NV_DECLARE_ALIGNED(NvU64 pluginHeapMemoryLength, 8);
+       NV_DECLARE_ALIGNED(NvU64 ctrlBuffOffset, 8);
+       NV_DECLARE_ALIGNED(NvU64 initTaskLogBuffOffset, 8);
+       NV_DECLARE_ALIGNED(NvU64 initTaskLogBuffSize, 8);
+       NV_DECLARE_ALIGNED(NvU64 vgpuTaskLogBuffOffset, 8);
+       NV_DECLARE_ALIGNED(NvU64 vgpuTaskLogBuffSize, 8);
+       NvBool bDeviceProfilingEnabled;
+} NV2080_CTRL_VGPU_MGR_INTERNAL_BOOTLOAD_GSP_VGPU_PLUGIN_TASK_PARAMS;
+
+/*
+ * NV2080_CTRL_CMD_VGPU_MGR_INTERNAL_SHUTDOWN_GSP_VGPU_PLUGIN_TASK
+ *
+ * This command is used to shutdown GSP VGPU plugin task.
+ * Can be called only with SR-IOV and with VGPU_GSP_PLUGIN_OFFLOAD feature.
+ *
+ * gfid                        - Gfid
+ */
+#define NV2080_CTRL_CMD_VGPU_MGR_INTERNAL_SHUTDOWN_GSP_VGPU_PLUGIN_TASK 
(0x20804002) /* finn: Evaluated from 
"(FINN_NV20_SUBDEVICE_0_VGPU_MGR_INTERNAL_INTERFACE_ID << 8) | 
NV2080_CTRL_VGPU_MGR_INTERNAL_SHUTDOWN_GSP_VGPU_PLUGIN_TASK_PARAMS_MESSAGE_ID" 
*/
+
+#define 
NV2080_CTRL_VGPU_MGR_INTERNAL_SHUTDOWN_GSP_VGPU_PLUGIN_TASK_PARAMS_MESSAGE_ID 
(0x2U)
+
+typedef struct 
NV2080_CTRL_VGPU_MGR_INTERNAL_SHUTDOWN_GSP_VGPU_PLUGIN_TASK_PARAMS {
+       NvU32 gfid;
+} NV2080_CTRL_VGPU_MGR_INTERNAL_SHUTDOWN_GSP_VGPU_PLUGIN_TASK_PARAMS;
+
+/*
+ * NV2080_CTRL_CMD_VGPU_MGR_INTERNAL_VGPU_PLUGIN_CLEANUP
+ *
+ * This command is used to cleanup all the GSP VGPU plugin task allocated 
resources after its shutdown.
+ * Can be called only with SR-IOV and with VGPU_GSP_PLUGIN_OFFLOAD feature.
+ *
+ * gfid [IN]
+ *  This parameter specifies the gfid of vGPU assigned to VM.
+ *
+ * Possible status values returned are:
+ *   NV_OK
+ *   NV_ERR_NOT_SUPPORTED
+ */
+#define NV2080_CTRL_CMD_VGPU_MGR_INTERNAL_VGPU_PLUGIN_CLEANUP (0x20804008) /* 
finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_VGPU_MGR_INTERNAL_INTERFACE_ID << 
8) | NV2080_CTRL_VGPU_MGR_INTERNAL_VGPU_PLUGIN_CLEANUP_PARAMS_MESSAGE_ID" */
+
+#define NV2080_CTRL_VGPU_MGR_INTERNAL_VGPU_PLUGIN_CLEANUP_PARAMS_MESSAGE_ID 
(0x8U)
+
+typedef struct NV2080_CTRL_VGPU_MGR_INTERNAL_VGPU_PLUGIN_CLEANUP_PARAMS {
+       NvU32 gfid;
+} NV2080_CTRL_VGPU_MGR_INTERNAL_VGPU_PLUGIN_CLEANUP_PARAMS;
+
 #endif
diff --git a/drivers/vfio/pci/nvidia-vgpu/nvkm.h 
b/drivers/vfio/pci/nvidia-vgpu/nvkm.h
index 8ad2241f7c5e..8e07422f99e5 100644
--- a/drivers/vfio/pci/nvidia-vgpu/nvkm.h
+++ b/drivers/vfio/pci/nvidia-vgpu/nvkm.h
@@ -88,4 +88,7 @@ static inline int nvidia_vgpu_mgr_get_handle(struct pci_dev 
*pdev,
 #define nvidia_vgpu_mgr_bar1_unmap_mem(m, mem) \
        m->handle.ops->bar1_unmap_mem(mem)
 
+#define nvidia_vgpu_mgr_get_engine_bitmap(m, b) \
+       m->handle.ops->get_engine_bitmap(m->handle.pf_drvdata, b)
+
 #endif
diff --git a/drivers/vfio/pci/nvidia-vgpu/vgpu.c 
b/drivers/vfio/pci/nvidia-vgpu/vgpu.c
index 124a1a4593ae..e06d5155bb38 100644
--- a/drivers/vfio/pci/nvidia-vgpu/vgpu.c
+++ b/drivers/vfio/pci/nvidia-vgpu/vgpu.c
@@ -7,6 +7,7 @@
 
 #include <nvrm/nvtypes.h>
 #include <nvrm/common/sdk/nvidia/inc/ctrl/ctrla081.h>
+#include <nvrm/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080vgpumgrinternal.h>
 
 #include "vgpu_mgr.h"
 
@@ -141,6 +142,91 @@ static int setup_mgmt_heap(struct nvidia_vgpu *vgpu)
        return 0;
 }
 
+static int shutdown_vgpu_plugin_task(struct nvidia_vgpu *vgpu)
+{
+       struct nvidia_vgpu_mgr *vgpu_mgr = vgpu->vgpu_mgr;
+       NV2080_CTRL_VGPU_MGR_INTERNAL_SHUTDOWN_GSP_VGPU_PLUGIN_TASK_PARAMS 
*ctrl;
+
+       ctrl = nvidia_vgpu_mgr_rm_ctrl_get(vgpu_mgr, &vgpu->gsp_client,
+                       
NV2080_CTRL_CMD_VGPU_MGR_INTERNAL_SHUTDOWN_GSP_VGPU_PLUGIN_TASK,
+                       sizeof(*ctrl));
+       if (IS_ERR(ctrl))
+               return PTR_ERR(ctrl);;
+
+       ctrl->gfid = vgpu->info.gfid;
+
+       return nvidia_vgpu_mgr_rm_ctrl_wr(vgpu_mgr, &vgpu->gsp_client,
+                                         ctrl);
+}
+
+static int cleanup_vgpu_plugin_task(struct nvidia_vgpu *vgpu)
+{
+       struct nvidia_vgpu_mgr *vgpu_mgr = vgpu->vgpu_mgr;
+       NV2080_CTRL_VGPU_MGR_INTERNAL_VGPU_PLUGIN_CLEANUP_PARAMS *ctrl;
+
+       ctrl = nvidia_vgpu_mgr_rm_ctrl_get(vgpu_mgr, &vgpu->gsp_client,
+                       NV2080_CTRL_CMD_VGPU_MGR_INTERNAL_VGPU_PLUGIN_CLEANUP,
+                       sizeof(*ctrl));
+       if (IS_ERR(ctrl))
+               return PTR_ERR(ctrl);
+
+       ctrl->gfid = vgpu->info.gfid;
+
+       return nvidia_vgpu_mgr_rm_ctrl_wr(vgpu_mgr, &vgpu->gsp_client,
+                                         ctrl);
+}
+
+static int bootload_vgpu_plugin_task(struct nvidia_vgpu *vgpu)
+{
+       struct nvidia_vgpu_mgr *vgpu_mgr = vgpu->vgpu_mgr;
+       struct nvidia_vgpu_mgmt *mgmt = &vgpu->mgmt;
+       NV2080_CTRL_VGPU_MGR_INTERNAL_BOOTLOAD_GSP_VGPU_PLUGIN_TASK_PARAMS 
*ctrl;
+       DECLARE_BITMAP(engine_bitmap, NV2080_GPU_MAX_ENGINES);
+       int ret, i;
+
+       ctrl = nvidia_vgpu_mgr_rm_ctrl_get(vgpu_mgr, &vgpu->gsp_client,
+                       
NV2080_CTRL_CMD_VGPU_MGR_INTERNAL_BOOTLOAD_GSP_VGPU_PLUGIN_TASK,
+                       sizeof(*ctrl));
+       if (IS_ERR(ctrl))
+               return PTR_ERR(ctrl);
+
+       ctrl->dbdf = vgpu->info.dbdf;
+       ctrl->gfid = vgpu->info.gfid;
+       ctrl->vmPid = 0;
+       ctrl->swizzId = 0;
+       ctrl->numChannels = vgpu->chid.num_chid;
+       ctrl->numPluginChannels = 0;
+
+       bitmap_clear(engine_bitmap, 0, NV2080_GPU_MAX_ENGINES);
+
+       /* FIXME: nvkm seems not correctly record engines. two engines are 
missing. */
+       nvidia_vgpu_mgr_get_engine_bitmap(vgpu_mgr, engine_bitmap);
+
+       for_each_set_bit(i, engine_bitmap, NV2080_GPU_MAX_ENGINES)
+               ctrl->chidOffset[i] = vgpu->chid.chid_offset;
+
+       ctrl->bDisableDefaultSmcExecPartRestore = false;
+       ctrl->numGuestFbSegments = 1;
+       ctrl->guestFbPhysAddrList[0] = vgpu->fbmem_heap->addr;
+       ctrl->guestFbLengthList[0] = vgpu->fbmem_heap->size;
+       ctrl->pluginHeapMemoryPhysAddr = mgmt->heap_mem->addr;
+       ctrl->pluginHeapMemoryLength = mgmt->heap_mem->size;
+       ctrl->ctrlBuffOffset = 0;
+       ctrl->initTaskLogBuffOffset = mgmt->heap_mem->addr +
+                                     init_task_log_buff_offset();
+       ctrl->initTaskLogBuffSize = init_task_log_buff_size();
+       ctrl->vgpuTaskLogBuffOffset = ctrl->initTaskLogBuffOffset +
+                                     ctrl->initTaskLogBuffSize;
+       ctrl->vgpuTaskLogBuffSize = vgpu_task_log_buff_size();
+       ctrl->bDeviceProfilingEnabled = false;
+
+       ret = nvidia_vgpu_mgr_rm_ctrl_wr(vgpu_mgr, &vgpu->gsp_client,
+                                        ctrl);
+       if (ret)
+               return ret;
+       return 0;
+}
+
 /**
  * nvidia_vgpu_mgr_destroy_vgpu - destroy a vGPU instance
  * @vgpu: the vGPU instance going to be destroyed.
@@ -154,6 +240,8 @@ int nvidia_vgpu_mgr_destroy_vgpu(struct nvidia_vgpu *vgpu)
        if (!atomic_cmpxchg(&vgpu->status, 1, 0))
                return -ENODEV;
 
+       WARN_ON(shutdown_vgpu_plugin_task(vgpu));
+       WARN_ON(cleanup_vgpu_plugin_task(vgpu));
        nvidia_vgpu_mgr_free_gsp_client(vgpu_mgr, &vgpu->gsp_client);
        clean_mgmt_heap(vgpu);
        clean_chids(vgpu);
@@ -207,10 +295,16 @@ int nvidia_vgpu_mgr_create_vgpu(struct nvidia_vgpu *vgpu, 
u8 *vgpu_type)
        if (ret)
                goto err_alloc_gsp_client;
 
+       ret = bootload_vgpu_plugin_task(vgpu);
+       if (ret)
+               goto err_bootload_vgpu_plugin_task;
+
        atomic_set(&vgpu->status, 1);
 
        return 0;
 
+err_bootload_vgpu_plugin_task:
+       nvidia_vgpu_mgr_free_gsp_client(vgpu_mgr, &vgpu->gsp_client);
 err_alloc_gsp_client:
        clean_mgmt_heap(vgpu);
 err_setup_mgmt_heap:
-- 
2.34.1

Reply via email to