summaryrefslogtreecommitdiffstats
path: root/kernel/main.c
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-13 19:07:41 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-13 19:07:41 -0400
commit4b745a1c2c0534a1850b6efe6710536b2225c3f4 (patch)
tree63cedd53fec1366c1d698c57f46fa57a64b9049d /kernel/main.c
parent00e54c13c7c9030c4d5f7151467f2d85a3730e29 (diff)
downloadopen-iov-4b745a1c2c0534a1850b6efe6710536b2225c3f4.tar.gz
open-iov-4b745a1c2c0534a1850b6efe6710536b2225c3f4.zip
Phase 1: Add GSP Emulation Engine (host-side)
- New kernel/gsp_emulation.h: GSP emulation context and API - New kernel/gsp_emulation.c: Per-mdev emulation thread with: - Adaptive polling of doorbell at BAR0+0x110C00 - Shared memory RPC processing (4KB at BAR0+0x1000) - Dispatch for all 12 RPC types via firmware-decompiled handlers - MSI-X completion interrupt injection via eventfd - Statistics tracking (processed/failed RPCs, latency) - Modified kernel/main.c: Integrate gsp_emu_init/cleanup in device lifecycle - Modified kernel/Makefile: Add gsp_emulation.o to build - Modified kernel/gsp_rpc_client.h: Export gsp_rpc_emulation_set/is_enabled
Diffstat (limited to 'kernel/main.c')
-rw-r--r--kernel/main.c129
1 files changed, 70 insertions, 59 deletions
diff --git a/kernel/main.c b/kernel/main.c
index 7d12203..efe5082 100644
--- a/kernel/main.c
+++ b/kernel/main.c
@@ -17,6 +17,7 @@
#include "nvidia-vgpu-vfio.h"
#include "bar_emulation.h"
#include "gsp_comm.h"
+#include "gsp_emulation.h"
#include "memory.h"
#include "irq.h"
#include "migration.h"
@@ -450,76 +451,86 @@ static void __exit nv_vgpu_exit(void)
static void nv_vgpu_device_init_work(struct work_struct *work)
{
- struct nv_vgpu_device *vgpu = container_of(work, struct nv_vgpu_device, init_work);
- int ret;
-
- mutex_lock(&vgpu->lock);
- vgpu->state = NV_VGPU_STATE_INITIALIZING;
- mutex_unlock(&vgpu->lock);
-
- ret = nv_vgpu_bar_init(vgpu);
- if (ret) {
- nv_vgpu_err(vgpu, "BAR init failed: %d", ret);
- goto err_state;
- }
-
- ret = nv_vgpu_irq_init(vgpu);
- if (ret) {
- nv_vgpu_err(vgpu, "IRQ init failed: %d", ret);
- goto err_bar;
- }
-
- ret = nv_vgpu_memory_init(vgpu);
- if (ret) {
- nv_vgpu_err(vgpu, "Memory init failed: %d", ret);
- goto err_irq;
- }
-
- ret = nv_vgpu_gsp_init(vgpu);
- if (ret) {
- nv_vgpu_err(vgpu, "GSP init failed: %d", ret);
- goto err_memory;
- }
-
- ret = nv_vgpu_migration_init(vgpu);
- if (ret) {
- nv_vgpu_warn(vgpu, "Migration init failed: %d", ret);
- }
-
- mutex_lock(&vgpu->lock);
- vgpu->state = NV_VGPU_STATE_READY;
- mutex_unlock(&vgpu->lock);
-
- nv_vgpu_info(vgpu, "vGPU device initialized successfully");
- return;
-
+ struct nv_vgpu_device *vgpu = container_of(work, struct nv_vgpu_device, init_work);
+ int ret;
+
+ mutex_lock(&vgpu->lock);
+ vgpu->state = NV_VGPU_STATE_INITIALIZING;
+ mutex_unlock(&vgpu->lock);
+
+ ret = nv_vgpu_bar_init(vgpu);
+ if (ret) {
+ nv_vgpu_err(vgpu, "BAR init failed: %d", ret);
+ goto err_state;
+ }
+
+ ret = nv_vgpu_irq_init(vgpu);
+ if (ret) {
+ nv_vgpu_err(vgpu, "IRQ init failed: %d", ret);
+ goto err_bar;
+ }
+
+ ret = nv_vgpu_memory_init(vgpu);
+ if (ret) {
+ nv_vgpu_err(vgpu, "Memory init failed: %d", ret);
+ goto err_irq;
+ }
+
+ ret = nv_vgpu_gsp_init(vgpu);
+ if (ret) {
+ nv_vgpu_err(vgpu, "GSP init failed: %d", ret);
+ goto err_memory;
+ }
+
+ /* Initialize GSP emulation engine (host-side) */
+ ret = gsp_emu_init(vgpu);
+ if (ret) {
+ nv_vgpu_err(vgpu, "GSP emulation init failed: %d", ret);
+ goto err_gsp;
+ }
+
+ ret = nv_vgpu_migration_init(vgpu);
+ if (ret) {
+ nv_vgpu_warn(vgpu, "Migration init failed: %d", ret);
+ }
+
+ mutex_lock(&vgpu->lock);
+ vgpu->state = NV_VGPU_STATE_READY;
+ mutex_unlock(&vgpu->lock);
+
+ nv_vgpu_info(vgpu, "vGPU device initialized successfully");
+ return;
+
+err_gsp:
+ nv_vgpu_gsp_cleanup(vgpu);
err_memory:
- nv_vgpu_memory_cleanup(vgpu);
+ nv_vgpu_memory_cleanup(vgpu);
err_irq:
- nv_vgpu_irq_cleanup(vgpu);
+ nv_vgpu_irq_cleanup(vgpu);
err_bar:
- nv_vgpu_bar_cleanup(vgpu);
+ nv_vgpu_bar_cleanup(vgpu);
err_state:
- mutex_lock(&vgpu->lock);
- vgpu->state = NV_VGPU_STATE_ERROR;
- mutex_unlock(&vgpu->lock);
+ mutex_lock(&vgpu->lock);
+ vgpu->state = NV_VGPU_STATE_ERROR;
+ mutex_unlock(&vgpu->lock);
}
static void nv_vgpu_device_cleanup_work(struct work_struct *work)
{
- struct nv_vgpu_device *vgpu = container_of(work, struct nv_vgpu_device, cleanup_work);
+ struct nv_vgpu_device *vgpu = container_of(work, struct nv_vgpu_device, cleanup_work);
- nv_vgpu_migration_cleanup(vgpu);
- nv_vgpu_gsp_cleanup(vgpu);
- nv_vgpu_memory_cleanup(vgpu);
- nv_vgpu_irq_cleanup(vgpu);
- nv_vgpu_bar_cleanup(vgpu);
+ nv_vgpu_migration_cleanup(vgpu);
+ gsp_emu_cleanup(vgpu);
+ nv_vgpu_gsp_cleanup(vgpu);
+ nv_vgpu_memory_cleanup(vgpu);
+ nv_vgpu_irq_cleanup(vgpu);
+ nv_vgpu_bar_cleanup(vgpu);
- mutex_lock(&vgpu->lock);
- vgpu->state = NV_VGPU_STATE_UNINITIALIZED;
- mutex_unlock(&vgpu->lock);
+ mutex_lock(&vgpu->lock);
+ vgpu->state = NV_VGPU_STATE_UNINITIALIZED;
+ mutex_unlock(&vgpu->lock);
- nv_vgpu_info(vgpu, "vGPU device cleaned up");
+ nv_vgpu_info(vgpu, "vGPU device cleaned up");
}
static NV_STATUS nv_vgpu_vfio_probe(struct pci_dev *pdev, NvU32 vgpu_type_id, NvU32 *vgpu_id)