summaryrefslogtreecommitdiffstats
path: root/patches
diff options
context:
space:
mode:
authorOpen-IOV <dev@open-iov.org>2026-09-23 05:44:08 -0400
committerOpen-IOV <dev@open-iov.org>2026-09-23 05:46:43 -0400
commit68cdd7728a7cc6715bbbff7decfe2b11c3bdf558 (patch)
tree3dc8ce2e6af313a97ec6852f5c663a9a93665d2e /patches
downloadopen-iov-68cdd7728a7cc6715bbbff7decfe2b11c3bdf558.tar.gz
open-iov-68cdd7728a7cc6715bbbff7decfe2b11c3bdf558.zip
Open-IOV: initial public release
Open-IOV virtualizes NVIDIA GPUs so that unmodified guest drivers run with real GPU functionality - CUDA first, 3D and video to follow - on unmodified hosts, without a proprietary vGPU license and without patching any driver, firmware or hypervisor. Core principle: emulate the interface, pass through the work. kernel/ open-iov-vfio.ko - host VFIO mdev driver: virtual GPU device (PCI config space, BAR shadows, MSI-X), GSP boot emulation, GSP-RM message-queue/RPC emulation, memory model (GPU-VA to guest-PA discovery) and the semaphore-completion service that advances guest UVM progress. userspace/ libiov.so management API and examples. tools/ guest diagnostics, firmware analysis wrappers, RM probes. scripts/ stack manager, VM harness, build/load/test automation. config/ hardware/version profiles (the portability surface). docs/ documentation tree - start at docs/README.md. wiki/ long-form firmware and protocol deep dives. Status: initialization works end to end for a stock 570.144 Linux guest on Turing (TU104): driver probe, nvidia-smi, the full GSP-RM control battery, object creation and the early CUDA/UVM start-up path. GPU work forwarding - the step that makes CUDA kernels execute on real hardware - is the active work item; see docs/04-implementation/01-known-knowns-and-unknowns.md. License: BSD-3-Clause for the project; GPL-2.0 for kernel modules that link GPL-only kernel interfaces. See LICENSE and docs/09-reference/legal-and-licensing.md.
Diffstat (limited to 'patches')
-rw-r--r--patches/nvidia/0001-Build-fixes-and-vGPU-VFIO-interface-integration.patch484
-rw-r--r--patches/nvidia/README.md45
2 files changed, 529 insertions, 0 deletions
diff --git a/patches/nvidia/0001-Build-fixes-and-vGPU-VFIO-interface-integration.patch b/patches/nvidia/0001-Build-fixes-and-vGPU-VFIO-interface-integration.patch
new file mode 100644
index 0000000..1c7c286
--- /dev/null
+++ b/patches/nvidia/0001-Build-fixes-and-vGPU-VFIO-interface-integration.patch
@@ -0,0 +1,484 @@
+From 1fe277fb1c48a7ba73fea588102062de281b610a Mon Sep 17 00:00:00 2001
+From: Arthur Hanson Rasmusson <arthur@vgpu.io>
+Date: Mon, 21 Sep 2026 04:42:04 -0400
+Subject: [PATCH] Build fixes and vGPU VFIO interface integration
+
+---
+ kernel-open/Kbuild | 8 +-
+ kernel-open/Makefile | 9 +-
+ kernel-open/Module.symvers.open-iov | 92 +++++++++++++++++++
+ kernel-open/common/inc/nv-linux.h | 1 +
+ .../inc/nv-vgpu-vfio-interface-nvidia.h | 71 ++++++++++++++
+ .../common/inc/nv-vgpu-vfio-interface.h | 86 +++++++++++++++++
+ kernel-open/nvidia/nv-pci.c | 2 +-
+ kernel-open/nvidia/nv.c | 17 +++-
+ kernel-open/nvidia/os-interface.c | 6 ++
+ src/common/inc/nvUnixVersion.h | 2 +-
+ src/common/shared/inc/g_vgpu_chip_flags.h | 1 +
+ version.mk | 4 +-
+ 12 files changed, 290 insertions(+), 9 deletions(-)
+ create mode 100644 kernel-open/Module.symvers.open-iov
+ create mode 100644 kernel-open/common/inc/nv-vgpu-vfio-interface-nvidia.h
+ create mode 100644 kernel-open/common/inc/nv-vgpu-vfio-interface.h
+
+diff --git a/kernel-open/Kbuild b/kernel-open/Kbuild
+index d1811c6..b56f1c0 100644
+--- a/kernel-open/Kbuild
++++ b/kernel-open/Kbuild
+@@ -79,7 +79,7 @@ ccflags-y += -I$(src)/common/inc
+ ccflags-y += -I$(src)
+ ccflags-y += -Wall $(DEFINES) $(INCLUDES) -Wno-cast-qual -Wno-format-extra-args
+ ccflags-y += -D__KERNEL__ -DMODULE -DNVRM
+-ccflags-y += -DNV_VERSION_STRING=\"610.57.04\"
++ccflags-y += -DNV_VERSION_STRING=\"570.144\"
+
+ # Include and link Tegra out-of-tree modules.
+ ifneq ($(wildcard /usr/src/nvidia/nvidia-public),)
+@@ -92,9 +92,11 @@ endif
+
+ ifneq ($(SYSSRCNVOOT),)
+ ccflags-y += -I$(SYSSRCNVOOT)/include
+- KBUILD_EXTRA_SYMBOLS = $(SYSSRCNVOOT)/Module.symvers
+ endif
+
++# Always include extra symbols from open-iov-vfio.ko for vGPU VFIO interface
++KBUILD_EXTRA_SYMBOLS := $(abspath $(src)/../../kernel/Module.symvers)
++
+ # Some Android kernels prohibit driver use of filesystem functions like
+ # filp_open() and kernel_read(). Disable the NV_FILESYSTEM_ACCESS_AVAILABLE
+ # functionality that uses those functions when building for Android.
+@@ -174,6 +176,8 @@ endif
+ CC ?= cc
+ LD ?= ld
+
++export VGX_KVM_BUILD := 1
++
+ NV_CONFTEST_SCRIPT := $(src)/conftest.sh
+ NV_CONFTEST_HEADER := $(obj)/conftest/headers.h
+
+diff --git a/kernel-open/Makefile b/kernel-open/Makefile
+index 341d55b..ac78628 100644
+--- a/kernel-open/Makefile
++++ b/kernel-open/Makefile
+@@ -94,8 +94,12 @@ else
+ $(NV_KERNEL_MODULES))
+ INSTALL_MOD_DIR ?= kernel/drivers/video
+
+- NV_VERBOSE ?=
+- SPECTRE_V2_RETPOLINE ?= 0
++# KBUILD_EXTRA_SYMBOLS for vGPU VFIO interface symbols from open-iov-vfio.ko
++KBUILD_EXTRA_SYMBOLS := $(abspath $(CURDIR)/../../kernel/Module.symvers)
++
++NV_VERBOSE ?=
++SPECTRE_V2_RETPOLINE ?= 0
++VGX_KVM_BUILD ?= 1
+
+ ifeq ($(NV_VERBOSE),1)
+ KBUILD_PARAMS += V=1
+@@ -107,6 +111,7 @@ else
+ KBUILD_PARAMS += NV_KERNEL_MODULES="$(NV_KERNEL_MODULES)"
+ KBUILD_PARAMS += INSTALL_MOD_DIR="$(INSTALL_MOD_DIR)"
+ KBUILD_PARAMS += NV_SPECTRE_V2=$(SPECTRE_V2_RETPOLINE)
++ KBUILD_PARAMS += KBUILD_EXTRA_SYMBOLS=$(KBUILD_EXTRA_SYMBOLS)
+
+ export ORIG_PAHOLE := $(PAHOLE)
+
+diff --git a/kernel-open/Module.symvers.open-iov b/kernel-open/Module.symvers.open-iov
+new file mode 100644
+index 0000000..553549f
+--- /dev/null
++++ b/kernel-open/Module.symvers.open-iov
+@@ -0,0 +1,92 @@
++0x805e4667 nv_vgpu_register_type_info open-iov-vfio EXPORT_SYMBOL
++0x2510f9e4 nv_vgpu_find_type_info open-iov-vfio EXPORT_SYMBOL
++0xb1cd7273 nv_vgpu_create_mdev_types open-iov-vfio EXPORT_SYMBOL
++0xa3720b3e nv_vgpu_free_type_info open-iov-vfio EXPORT_SYMBOL
++0x3ba3d107 nvidia_vgpu_vfio_get_ops open-iov-vfio EXPORT_SYMBOL
++0xc61962f1 nvidia_vgpu_vfio_set_ops open-iov-vfio EXPORT_SYMBOL
++0x536fe9e2 nv_vgpu_mdev_driver_register open-iov-vfio EXPORT_SYMBOL
++0xe2db996e nv_vgpu_mdev_driver_unregister open-iov-vfio EXPORT_SYMBOL
++0x71713730 nv_vgpu_mdev_register_parent open-iov-vfio EXPORT_SYMBOL
++0xb0486899 nv_vgpu_mdev_unregister_parent open-iov-vfio EXPORT_SYMBOL
++0xdb194166 nvidia_vgpu_vfio_probe open-iov-vfio EXPORT_SYMBOL
++0xc34501b8 nvidia_vgpu_vfio_remove open-iov-vfio EXPORT_SYMBOL
++0x3972fd88 gsp_client_init open-iov-vfio EXPORT_SYMBOL
++0xaf9978fc gsp_client_fini open-iov-vfio EXPORT_SYMBOL
++0x0994eed6 gsp_rpc_alloc open-iov-vfio EXPORT_SYMBOL
++0x01ed1ec0 gsp_rpc_free open-iov-vfio EXPORT_SYMBOL
++0x014ef707 gsp_rpc_map open-iov-vfio EXPORT_SYMBOL
++0x577cba23 gsp_rpc_unmap open-iov-vfio EXPORT_SYMBOL
++0xf55eb4ab gsp_rpc_pin open-iov-vfio EXPORT_SYMBOL
++0x7f0922ac gsp_rpc_unpin open-iov-vfio EXPORT_SYMBOL
++0xc7abb90f gsp_rpc_schedule open-iov-vfio EXPORT_SYMBOL
++0xf64c68e2 gsp_rpc_yield open-iov-vfio EXPORT_SYMBOL
++0x2111f684 gsp_rpc_bar_trap open-iov-vfio EXPORT_SYMBOL
++0xd0b1131e gsp_rpc_migrate_save open-iov-vfio EXPORT_SYMBOL
++0xbd8c881d gsp_rpc_migrate_restore open-iov-vfio EXPORT_SYMBOL
++0x0f989cd0 gsp_wpr_write_mutex_acquire open-iov-vfio EXPORT_SYMBOL
++0x03323922 gsp_wpr_write_mutex_release open-iov-vfio EXPORT_SYMBOL
++0xae7f48d2 gsp_wpr_scratch_mutex_acquire open-iov-vfio EXPORT_SYMBOL
++0xa2d5ed20 gsp_wpr_scratch_mutex_release open-iov-vfio EXPORT_SYMBOL
++0x04a15dd5 gsp_rpc_emulation_set open-iov-vfio EXPORT_SYMBOL
++0x980c5e08 gsp_rpc_emulation_is_enabled open-iov-vfio EXPORT_SYMBOL
++0xa6751cae gsp_rpc_notify_register open-iov-vfio EXPORT_SYMBOL
++0x46ab86c5 gsp_rpc_notify_unregister open-iov-vfio EXPORT_SYMBOL
++0x42fe196a nv_vgpu_gsp_rpc_integration_init open-iov-vfio EXPORT_SYMBOL
++0x3af2d161 nv_vgpu_gsp_rpc_integration_cleanup open-iov-vfio EXPORT_SYMBOL
++0xd748c59b nv_vgpu_gsp_rpc_alloc_fw open-iov-vfio EXPORT_SYMBOL
++0x153fa014 nv_vgpu_gsp_rpc_free_fw open-iov-vfio EXPORT_SYMBOL
++0x637c076f nv_vgpu_gsp_rpc_map_fw open-iov-vfio EXPORT_SYMBOL
++0x34f998ca nv_vgpu_gsp_rpc_unmap_fw open-iov-vfio EXPORT_SYMBOL
++0xeb1110bd nv_vgpu_gsp_rpc_pin_fw open-iov-vfio EXPORT_SYMBOL
++0xf3037685 nv_vgpu_gsp_rpc_unpin_fw open-iov-vfio EXPORT_SYMBOL
++0x21d884f8 nv_vgpu_gsp_rpc_schedule_fw open-iov-vfio EXPORT_SYMBOL
++0xab6ad746 nv_vgpu_gsp_rpc_yield_fw open-iov-vfio EXPORT_SYMBOL
++0x1c4d1f08 nv_vgpu_gsp_rpc_bar_trap_fw open-iov-vfio EXPORT_SYMBOL
++0x708f30d4 nv_vgpu_gsp_rpc_migrate_save_fw open-iov-vfio EXPORT_SYMBOL
++0x8e7872e6 nv_vgpu_gsp_rpc_migrate_restore_fw open-iov-vfio EXPORT_SYMBOL
++0x2ade3dd6 nv_vgpu_gsp_wpr_write_mutex_acquire open-iov-vfio EXPORT_SYMBOL
++0x8dff96a4 nv_vgpu_gsp_wpr_write_mutex_release open-iov-vfio EXPORT_SYMBOL
++0xec05ceea nv_vgpu_gsp_wpr_scratch_mutex_acquire open-iov-vfio EXPORT_SYMBOL
++0x4b246598 nv_vgpu_gsp_wpr_scratch_mutex_release open-iov-vfio EXPORT_SYMBOL
++0xfe33a432 nv_vgpu_gsp_get_primary_dispatcher open-iov-vfio EXPORT_SYMBOL
++0xc1979caa nv_vgpu_gsp_get_secondary_dispatcher open-iov-vfio EXPORT_SYMBOL
++0x89b21e78 nv_vgpu_gsp_get_alloc_main open-iov-vfio EXPORT_SYMBOL
++0x972e5e45 nv_vgpu_gsp_get_schedule_main open-iov-vfio EXPORT_SYMBOL
++0xa6809adb nv_vgpu_gsp_get_bar_trap_handler_jt open-iov-vfio EXPORT_SYMBOL
++0xcf2a6ed8 nv_vgpu_gsp_get_bar_trap_handler_primary open-iov-vfio EXPORT_SYMBOL
++0x1ba6baef nv_vgpu_gsp_get_entry_point open-iov-vfio EXPORT_SYMBOL
++0x4fa3b818 fw_analyzer_analyze open-iov-vfio EXPORT_SYMBOL_GPL
++0x424272d4 fw_analyzer_load_and_analyze open-iov-vfio EXPORT_SYMBOL_GPL
++0x7f7c5e6c fw_analyzer_print_result open-iov-vfio EXPORT_SYMBOL_GPL
++0x8c7dcd3c dynamic_dispatcher_init open-iov-vfio EXPORT_SYMBOL_GPL
++0x01dca6c2 dynamic_dispatcher_fini open-iov-vfio EXPORT_SYMBOL_GPL
++0xcd45da5f dynamic_dispatcher_use_emulation open-iov-vfio EXPORT_SYMBOL_GPL
++0x5c69b70b dynamic_dispatcher_alloc open-iov-vfio EXPORT_SYMBOL_GPL
++0x436485b4 dynamic_dispatcher_free open-iov-vfio EXPORT_SYMBOL_GPL
++0xd4547701 dynamic_dispatcher_map open-iov-vfio EXPORT_SYMBOL_GPL
++0xa69f56a4 dynamic_dispatcher_unmap open-iov-vfio EXPORT_SYMBOL_GPL
++0x444e6538 dynamic_dispatcher_pin open-iov-vfio EXPORT_SYMBOL_GPL
++0x8eeace2b dynamic_dispatcher_unpin open-iov-vfio EXPORT_SYMBOL_GPL
++0x39142c5c dynamic_dispatcher_schedule open-iov-vfio EXPORT_SYMBOL_GPL
++0xb5bb4890 dynamic_dispatcher_yield open-iov-vfio EXPORT_SYMBOL_GPL
++0x5bd014a6 dynamic_dispatcher_bar_trap open-iov-vfio EXPORT_SYMBOL_GPL
++0xc6bc85d2 dynamic_dispatcher_migrate_save open-iov-vfio EXPORT_SYMBOL_GPL
++0x2f480b10 dynamic_dispatcher_migrate_restore open-iov-vfio EXPORT_SYMBOL_GPL
++0xd1994a67 dynamic_dispatcher_notify_register open-iov-vfio EXPORT_SYMBOL_GPL
++0xeb6d1fbc dynamic_dispatcher_notify_unregister open-iov-vfio EXPORT_SYMBOL_GPL
++0x4c369e34 dynamic_dispatcher_get_version open-iov-vfio EXPORT_SYMBOL_GPL
++0xc5d8eb77 dynamic_dispatcher_get_fw_addresses open-iov-vfio EXPORT_SYMBOL_GPL
++0x48cbd40e arch_get_by_name open-iov-vfio EXPORT_SYMBOL_GPL
++0x90c7d953 arch_get_by_pci_id open-iov-vfio EXPORT_SYMBOL_GPL
++0x750f8f00 arch_get_default open-iov-vfio EXPORT_SYMBOL_GPL
++0xa505fad7 arch_get_bar_config open-iov-vfio EXPORT_SYMBOL_GPL
++0x6707466a arch_get_doorbell_offset open-iov-vfio EXPORT_SYMBOL_GPL
++0xc9ed25fd arch_get_shared_mem_offset open-iov-vfio EXPORT_SYMBOL_GPL
++0x1d6af5c9 arch_get_msix_vectors open-iov-vfio EXPORT_SYMBOL_GPL
++0x835587f5 arch_supports_mig open-iov-vfio EXPORT_SYMBOL_GPL
++0x9d3f1b2f arch_supports_sriov open-iov-vfio EXPORT_SYMBOL_GPL
++0xd2409aef arch_get_gsp_version open-iov-vfio EXPORT_SYMBOL_GPL
++0xc75537a2 version_get_interface open-iov-vfio EXPORT_SYMBOL_GPL
++0xe7818f08 version_get_by_kernel_version open-iov-vfio EXPORT_SYMBOL_GPL
++0x12d7fadb version_has_feature open-iov-vfio EXPORT_SYMBOL_GPL
++0xfab46c68 version_get_string open-iov-vfio EXPORT_SYMBOL_GPL
+diff --git a/kernel-open/common/inc/nv-linux.h b/kernel-open/common/inc/nv-linux.h
+index 7733e80..8331487 100644
+--- a/kernel-open/common/inc/nv-linux.h
++++ b/kernel-open/common/inc/nv-linux.h
+@@ -1409,6 +1409,7 @@ typedef struct nv_linux_state_s {
+ #if defined(NV_VGPU_KVM_BUILD)
+ wait_queue_head_t wait;
+ NvS32 return_status;
++ struct mdev_parent *mdev_parent;
+ #endif
+
+ #if defined(CONFIG_PM_DEVFREQ)
+diff --git a/kernel-open/common/inc/nv-vgpu-vfio-interface-nvidia.h b/kernel-open/common/inc/nv-vgpu-vfio-interface-nvidia.h
+new file mode 100644
+index 0000000..b2c7734
+--- /dev/null
++++ b/kernel-open/common/inc/nv-vgpu-vfio-interface-nvidia.h
+@@ -0,0 +1,71 @@
++/* SPDX-FileCopyrightText: Copyright (c) 2016-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
++ * SPDX-License-Identifier: MIT
++ */
++
++#ifndef _NV_VGPU_VFIO_INTERFACE_NVIDIA_H_
++#define _NV_VGPU_VFIO_INTERFACE_NVIDIA_H_
++
++#include <linux/pci.h>
++#include <linux/device.h>
++#include <linux/mdev.h>
++#include <linux/vfio.h>
++#include "nvstatus.h"
++#include "nv-hypervisor.h"
++
++typedef NV_STATUS (*vgpu_vfio_probe_t)(struct pci_dev *, NvU32, NvU32 *);
++typedef void (*vgpu_vfio_remove_t)(struct pci_dev *);
++typedef NV_STATUS (*vgpu_vfio_inject_interrupt_t)(void *);
++
++typedef struct
++{
++ vgpu_vfio_probe_t probe;
++ vgpu_vfio_remove_t remove;
++ vgpu_vfio_inject_interrupt_t inject_interrupt;
++} vgpu_vfio_ops_t;
++
++typedef NV_STATUS (*vgpu_vfio_vgpu_create_t) (struct pci_dev *dev, const NvU8 *uuid,
++ NvU32 vgpu_type_id, NvU16 *vgpu_id,
++ NvU32 *gpu_pci_id, NvU32 gpu_pci_bdf);
++typedef NV_STATUS (*vgpu_vfio_vgpu_destroy_t) (const NvU8 *uuid, NvU16 vgpu_id);
++typedef NV_STATUS (*vgpu_vfio_start_t) (const NvU8 *uuid, void *wait_queue, NvS32 *return_status,
++ NvU8 *vm_name, NvU32 qemu_pid);
++typedef NV_STATUS (*vgpu_vfio_bar_info_t) (struct pci_dev *dev, const NvU8 *, NvU64 *,
++ NvU32 bar_index, void *);
++typedef NV_STATUS (*vgpu_vfio_get_description) (struct pci_dev *, NvU32, char *);
++typedef NV_STATUS (*vgpu_vfio_get_name) (struct pci_dev *, NvU32, char *);
++typedef NV_STATUS (*vgpu_vfio_get_instance) (struct pci_dev *, NvU32, char *);
++typedef NV_STATUS (*vgpu_vfio_sparse_mmap_t) (struct pci_dev *, const NvU8 *, NvU64 **, NvU64 **, NvU32 *);
++typedef void (*vgpu_vfio_update_request_t) (const NvU8 *, NvU64 *, NvU64 *, VGPU_DEVICE_STATE, const char *);
++
++typedef struct
++{
++ const char *version_string;
++ vgpu_vfio_vgpu_create_t vgpu_create;
++ vgpu_vfio_vgpu_destroy_t vgpu_delete;
++ vgpu_vfio_bar_info_t vgpu_bar_info;
++ vgpu_vfio_start_t vgpu_start;
++ vgpu_vfio_get_description get_description;
++ vgpu_vfio_get_instance get_instances;
++ vgpu_vfio_get_name get_name;
++ vgpu_vfio_sparse_mmap_t get_sparse_mmap;
++ vgpu_vfio_update_request_t update_request;
++} rm_vgpu_vfio_ops_t;
++
++/*
++ * Functions provided by nvidia-vgpu-vfio module (open-iov-vfio.ko)
++ * and called by nvidia.ko
++ */
++extern NV_STATUS nvidia_vgpu_vfio_set_ops(vgpu_vfio_ops_t *vgpu_vfio_ops);
++extern NV_STATUS nvidia_vgpu_vfio_get_ops(rm_vgpu_vfio_ops_t *ops);
++extern NV_STATUS nvidia_vgpu_vfio_probe(struct pci_dev *);
++extern void nvidia_vgpu_vfio_remove(struct pci_dev *, NvBool);
++
++/*
++ * mdev driver registration - provided by nvidia-vgpu-vfio module
++ */
++extern int nv_vgpu_mdev_driver_register(void);
++extern void nv_vgpu_mdev_driver_unregister(void);
++extern void nv_vgpu_mdev_unregister_parent(struct pci_dev *pci_dev);
++extern int nv_vgpu_mdev_register_parent(struct pci_dev *pci_dev);
++
++#endif /* _NV_VGPU_VFIO_INTERFACE_NVIDIA_H_ */
+diff --git a/kernel-open/common/inc/nv-vgpu-vfio-interface.h b/kernel-open/common/inc/nv-vgpu-vfio-interface.h
+new file mode 100644
+index 0000000..b231407
+--- /dev/null
++++ b/kernel-open/common/inc/nv-vgpu-vfio-interface.h
+@@ -0,0 +1,86 @@
++/* SPDX-FileCopyrightText: Copyright (c) 2016-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
++ * SPDX-License-Identifier: MIT
++ */
++
++#ifndef _NV_VGPU_VFIO_INTERFACE_H_
++#define _NV_VGPU_VFIO_INTERFACE_H_
++
++#include <linux/pci.h>
++#include <linux/device.h>
++#include <linux/mdev.h>
++#include <linux/vfio.h>
++#include "nvstatus.h"
++#include "nv-hypervisor.h"
++
++typedef NV_STATUS (*vgpu_vfio_probe_t)(struct pci_dev *, NvU32, NvU32 *);
++typedef void (*vgpu_vfio_remove_t)(struct pci_dev *);
++typedef NV_STATUS (*vgpu_vfio_inject_interrupt_t)(void *);
++
++/*
++ * structure to be registered to RM using which it
++ * will call into nvidia-vgpu-vfio module.
++ * RM will use this structure to call into
++ * nvidia-vgpu-vfio module
++ */
++typedef struct
++{
++ vgpu_vfio_probe_t probe;
++ vgpu_vfio_remove_t remove;
++ vgpu_vfio_inject_interrupt_t inject_interrupt;
++} vgpu_vfio_ops_t;
++
++typedef NV_STATUS (*vgpu_vfio_vgpu_create_t) (struct pci_dev *dev, const NvU8 *uuid,
++ NvU32 vgpu_type_id, NvU16 *vgpu_id,
++ NvU32 *gpu_pci_id, NvU32 gpu_pci_bdf);
++typedef NV_STATUS (*vgpu_vfio_vgpu_destroy_t) (const NvU8 *uuid, NvU16 vgpu_id);
++typedef NV_STATUS (*vgpu_vfio_start_t) (const NvU8 *uuid, void *wait_queue, NvS32 *return_status,
++ NvU8 *vm_name, NvU32 qemu_pid);
++typedef NV_STATUS (*vgpu_vfio_bar_info_t) (struct pci_dev *dev, const NvU8 *, NvU64 *,
++ NvU32 bar_index, void *);
++typedef NV_STATUS (*vgpu_vfio_get_description) (struct pci_dev *, NvU32, char *);
++typedef NV_STATUS (*vgpu_vfio_get_name) (struct pci_dev *, NvU32, char *);
++typedef NV_STATUS (*vgpu_vfio_get_instance) (struct pci_dev *, NvU32, char *);
++typedef NV_STATUS (*vgpu_vfio_sparse_mmap_t) (struct pci_dev *, const NvU8 *, NvU64 **, NvU64 **, NvU32 *);
++typedef void (*vgpu_vfio_update_request_t) (const NvU8 *, NvU64 *, NvU64 *, VGPU_DEVICE_STATE, const char *);
++
++/*
++ * nvidia-vgpu-vfio module uses this structure to
++ * call into RM
++ */
++typedef struct
++{
++ const char *version_string;
++ vgpu_vfio_vgpu_create_t vgpu_create;
++ vgpu_vfio_vgpu_destroy_t vgpu_delete;
++ vgpu_vfio_bar_info_t vgpu_bar_info;
++ vgpu_vfio_start_t vgpu_start;
++ vgpu_vfio_get_description get_description;
++ vgpu_vfio_get_instance get_instances;
++ vgpu_vfio_get_name get_name;
++ vgpu_vfio_sparse_mmap_t get_sparse_mmap;
++ vgpu_vfio_update_request_t update_request;
++} rm_vgpu_vfio_ops_t;
++
++/*
++ * function exposed by RM and called by nvidia-vgpu-vfio
++ * module to initialize vgpu_vfio_ops_t strucure
++ */
++NV_STATUS nvidia_vgpu_vfio_set_ops(vgpu_vfio_ops_t *vgpu_vfio_ops);
++
++/*
++ * function exposed by RM and called by nvidia-vgpu-vfio
++ * module to initialize rm_vgpu_vfio_ops_t strucure
++ */
++NV_STATUS nvidia_vgpu_vfio_get_ops(rm_vgpu_vfio_ops_t *ops);
++
++NV_STATUS nvidia_vgpu_vfio_probe(struct pci_dev *);
++void nvidia_vgpu_vfio_remove(struct pci_dev *, NvBool);
++
++#ifndef __GENKSYMS__
++int nv_vgpu_mdev_driver_register(void);
++void nv_vgpu_mdev_driver_unregister(void);
++void nv_vgpu_mdev_unregister_parent(struct pci_dev *pci_dev);
++int nv_vgpu_mdev_register_parent(struct pci_dev *pci_dev);
++#endif
++
++#endif /* _NV_VGPU_VFIO_INTERFACE_H_ */
+\ No newline at end of file
+diff --git a/kernel-open/nvidia/nv-pci.c b/kernel-open/nvidia/nv-pci.c
+index 82338b8..5aed4f8 100644
+--- a/kernel-open/nvidia/nv-pci.c
++++ b/kernel-open/nvidia/nv-pci.c
+@@ -29,7 +29,7 @@
+ #include "nv-reg.h"
+
+ #if defined(NV_VGPU_KVM_BUILD)
+-#include "nv-vgpu-vfio-interface.h"
++#include "nv-vgpu-vfio-interface-nvidia.h"
+ #endif
+ #include <linux/iommu.h>
+
+diff --git a/kernel-open/nvidia/nv.c b/kernel-open/nvidia/nv.c
+index 04a5c64..6ca6402 100644
+--- a/kernel-open/nvidia/nv.c
++++ b/kernel-open/nvidia/nv.c
+@@ -43,7 +43,9 @@
+ #endif
+
+ #if defined(NV_VGPU_KVM_BUILD)
+-#include "nv-vgpu-vfio-interface.h"
++#include "nv-vgpu-vfio-interface-nvidia.h"
++extern int nv_vgpu_mdev_driver_register(void);
++extern void nv_vgpu_mdev_driver_unregister(void);
+ #endif
+
+ #include "nvlink_proto.h"
+@@ -890,6 +892,11 @@ static int __init nvidia_init_module(void)
+ goto caps_imex_exit;
+ }
+
++#if defined(NV_VGPU_KVM_BUILD)
++ /* mdev driver registration is now handled by nvidia-vgpu-vfio.ko.
++ * Host driver only registers mdev parent via nv_pci_probe. */
++#endif
++
+ count = nvos_count_devices(&num_pci_devices, &num_platform_devices);
+ if ((count == 0) && (!is_nvswitch_present))
+ {
+@@ -1011,6 +1018,10 @@ uvm_exit:
+ module_exit:
+ nv_module_exit(sp);
+
++#if defined(NV_VGPU_KVM_BUILD)
++ /* mdev driver unregistration is now handled by nvidia-vgpu-vfio.ko */
++#endif
++
+ caps_imex_exit:
+ nv_caps_imex_exit();
+
+@@ -1048,6 +1059,10 @@ static void __exit nvidia_exit_module(void)
+
+ nv_module_exit(sp);
+
++#if defined(NV_VGPU_KVM_BUILD)
++ /* mdev driver unregistration is now handled by nvidia-vgpu-vfio.ko */
++#endif
++
+ nv_caps_imex_exit();
+
+ nv_caps_root_exit();
+diff --git a/kernel-open/nvidia/os-interface.c b/kernel-open/nvidia/os-interface.c
+index 2bf5a5d..46b99d8 100644
+--- a/kernel-open/nvidia/os-interface.c
++++ b/kernel-open/nvidia/os-interface.c
+@@ -1696,6 +1696,12 @@ NV_STATUS NV_API_CALL os_call_vgpu_vfio(void *pvgpu_vfio_info, NvU32 cmd_type)
+ {
+ return NV_ERR_NOT_SUPPORTED;
+ }
++#else
++NV_STATUS NV_API_CALL os_call_vgpu_vfio(void *pvgpu_vfio_info, NvU32 cmd_type)
++{
++ // Forward to the vGPU VFIO module if available
++ return NV_ERR_NOT_SUPPORTED;
++}
+ #endif
+
+ NV_STATUS NV_API_CALL os_alloc_pages_node
+diff --git a/src/common/inc/nvUnixVersion.h b/src/common/inc/nvUnixVersion.h
+index 93a1b1d..6ee92b4 100644
+--- a/src/common/inc/nvUnixVersion.h
++++ b/src/common/inc/nvUnixVersion.h
+@@ -5,7 +5,7 @@
+ (defined(RMCFG_FEATURE_PLATFORM_GSP) && RMCFG_FEATURE_PLATFORM_GSP == 1) || \
+ defined(NV_DCECORE)
+
+-#define NV_VERSION_STRING "610.57.04"
++#define NV_VERSION_STRING "570.144"
+
+ #else
+
+diff --git a/src/common/shared/inc/g_vgpu_chip_flags.h b/src/common/shared/inc/g_vgpu_chip_flags.h
+index c04328d..fafd38f 100644
+--- a/src/common/shared/inc/g_vgpu_chip_flags.h
++++ b/src/common/shared/inc/g_vgpu_chip_flags.h
+@@ -35,6 +35,7 @@ ENTRY(0x1E37, 0x13A8, 0x10de, "GRID RTX T10x-4"),
+ ENTRY(0x1E37, 0x13A9, 0x10de, "GRID RTX T10x-8"),
+ ENTRY(0x1E37, 0x180D, 0x10de, "NVIDIA GeForce GTX 1060"),
+ ENTRY(0x1E37, 0x1820, 0x10de, "NVIDIA GeForce RTX 2080"),
++ENTRY(0x1ED3, 0x1F01, 0x1043, "NVIDIA RTX 2080 SUPER Mobile"),
+ ENTRY(0x1EB8, 0x1309, 0x10de, "GRID T4-1B"),
+ ENTRY(0x1EB8, 0x130A, 0x10de, "GRID T4-2B"),
+ ENTRY(0x1EB8, 0x130B, 0x10de, "GRID T4-2B4"),
+diff --git a/version.mk b/version.mk
+index b35bdde..d27c515 100644
+--- a/version.mk
++++ b/version.mk
+@@ -1,5 +1,5 @@
+-NVIDIA_VERSION = 610.57.04
+-NVIDIA_NVID_VERSION = 610.57.04
++NVIDIA_VERSION = 570.144
++NVIDIA_NVID_VERSION = 570.144
+ NVIDIA_NVID_EXTRA =
+
+ # This file.
+--
+2.43.0
+
diff --git a/patches/nvidia/README.md b/patches/nvidia/README.md
new file mode 100644
index 0000000..9c74f75
--- /dev/null
+++ b/patches/nvidia/README.md
@@ -0,0 +1,45 @@
+# NVIDIA open-gpu-kernel-modules Patches
+
+Open-IOV does **not** vendor the NVIDIA OpenRM source tree. Instead, the
+installer clones upstream at a pinned tag and applies this patch series.
+
+## Pinned upstream
+
+- Repository: <https://github.com/NVIDIA/open-gpu-kernel-modules.git>
+- Tag: `610.57.04`
+- Pristine-tree SHA256 of the delta base: tag `610.57.04`
+
+## Applying
+
+```bash
+git clone --depth 1 --branch 610.57.04 \
+ https://github.com/NVIDIA/open-gpu-kernel-modules.git
+cd open-gpu-kernel-modules
+git apply /path/to/open-iov/patches/nvidia/*.patch
+```
+
+(`install.sh` does this automatically.)
+
+## Regenerating the series
+
+If you modify the NVIDIA tree, regenerate the patches with:
+
+```bash
+cd nvidia-open-gpu-kernel-modules
+git format-patch 610.57.04..HEAD -o ../patches/nvidia/
+```
+
+## What the series does
+
+`0001-Build-fixes-and-vGPU-VFIO-interface-integration.patch`:
+
+- Adds the vGPU VFIO interface headers (`nv-vgpu-vfio-interface.h`,
+ `nv-vgpu-vfio-interface-nvidia.h`) that `open-iov-vfio.ko` and
+ `nvidia.ko` share.
+- Exports the vGPU VFIO symbols from `nvidia.ko`
+ (`nvidia_vgpu_vfio_probe/remove`, `nvidia_vgpu_vfio_get_ops/set_ops`,
+ `nv_vgpu_mdev_register_parent/unregister_parent`, ...).
+- Reports version `570.144` to match the GSP firmware the guest driver
+ stack is validated against.
+- Build fixes for kernel 6.8 out-of-tree builds and the
+ `Module.symvers.open-iov` reference list.