diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-13 19:07:41 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-13 19:07:41 -0400 |
| commit | 4b745a1c2c0534a1850b6efe6710536b2225c3f4 (patch) | |
| tree | 63cedd53fec1366c1d698c57f46fa57a64b9049d /kernel/main.c | |
| parent | 00e54c13c7c9030c4d5f7151467f2d85a3730e29 (diff) | |
| download | open-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.c | 129 |
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) |
