summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-13 22:17:09 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-13 22:17:09 -0400
commit9a7263fce4e3156349a526631805fce66b87fb1b (patch)
tree6278c1972754e6cb60f953a1af05a472f4efecea
parentbfd269ee74d166be4f386640f8b5daad31d5d6ed (diff)
downloadopen-iov-9a7263fce4e3156349a526631805fce66b87fb1b.tar.gz
open-iov-9a7263fce4e3156349a526631805fce66b87fb1b.zip
Phase 5: Fix MDEV creation blocker - mdev parent registration & ioctl-based vGPU type registration
- Implemented nv_vgpu_mdev_register_parent() using mdev_register_parent() API with nv_vgpu_mdev_types array for proper mdev parent registration - Added ioctl NV_VGPU_IOCTL_REGISTER_VGPU_TYPE for userspace vGPU type registration - Created separate header nv-vgpu-vfio-interface-nvidia.h for nvidia.ko with only extern declarations to avoid duplicate symbol exports - Used KBUILD_EXTRA_SYMBOLS to provide only needed symbols (nvidia_vgpu_vfio_*) - Updated create_mdev.sh to use correct mdev type names (pci-nvidia-vgpu-*) - Updated load_vgpu_stack.sh to load open-iov-vfio.ko before nvidia.ko Result: 4 mdev types now show available_instances=8, mdev creation successful
-rw-r--r--kernel/include/ioctl.h21
-rw-r--r--kernel/ioctl.c44
-rw-r--r--kernel/main.c280
-rwxr-xr-xscripts/create_mdev.sh6
-rwxr-xr-xscripts/load_vgpu_stack.sh30
5 files changed, 321 insertions, 60 deletions
diff --git a/kernel/include/ioctl.h b/kernel/include/ioctl.h
index 4ff3df9..36d28ac 100644
--- a/kernel/include/ioctl.h
+++ b/kernel/include/ioctl.h
@@ -32,6 +32,18 @@
#define NV_VGPU_IOCTL_SET_GSP_FIRMWARE \
_IOWR(NV_VGPU_IOCTL_MAGIC, 0x09, struct nv_vgpu_ioctl_firmware)
+#define NV_VGPU_IOCTL_REGISTER_VGPU_TYPE \
+ _IOWR(NV_VGPU_IOCTL_MAGIC, 0x0A, struct nv_vgpu_ioctl_register_vgpu_type)
+
+/* vGPU type info structure (shared between main.c and ioctl.c) */
+struct nv_vgpu_type_info {
+ char name[64];
+ char description[128];
+ u64 vdev_id;
+ u64 pdev_id;
+ u32 max_instances;
+};
+
struct nv_vgpu_ioctl_get_info {
u32 vgpu_type;
u32 vgpu_id;
@@ -93,6 +105,14 @@ struct nv_vgpu_ioctl_firmware {
u32 firmware_type;
};
+struct nv_vgpu_ioctl_register_vgpu_type {
+ char name[64];
+ char description[128];
+ u64 vdev_id;
+ u64 pdev_id;
+ u32 max_instances;
+};
+
int nv_vgpu_ioctl_get_info(struct nv_vgpu_device *vgpu, void __user *arg);
int nv_vgpu_ioctl_map_bar(struct nv_vgpu_device *vgpu, void __user *arg);
int nv_vgpu_ioctl_unmap_bar(struct nv_vgpu_device *vgpu, void __user *arg);
@@ -101,5 +121,6 @@ int nv_vgpu_ioctl_disable_irq(struct nv_vgpu_device *vgpu, void __user *arg);
int nv_vgpu_ioctl_gsp_rpc(struct nv_vgpu_device *vgpu, void __user *arg);
int nv_vgpu_ioctl_migrate_save(struct nv_vgpu_device *vgpu, void __user *arg);
int nv_vgpu_ioctl_migrate_restore(struct nv_vgpu_device *vgpu, void __user *arg);
+int nv_vgpu_ioctl_register_vgpu_type(void __user *arg);
#endif \ No newline at end of file
diff --git a/kernel/ioctl.c b/kernel/ioctl.c
index 571b209..387a249 100644
--- a/kernel/ioctl.c
+++ b/kernel/ioctl.c
@@ -10,6 +10,12 @@
#include "irq.h"
#include "migration.h"
+/* Forward declarations from main.c */
+extern int nv_vgpu_register_type_info(struct nv_vgpu_type_info *info);
+extern int nv_vgpu_create_mdev_types(void);
+extern void nv_vgpu_free_type_info(void);
+extern struct mdev_driver nv_vgpu_mdev_driver;
+
int nv_vgpu_ioctl_get_info(struct nv_vgpu_device *vgpu, void __user *arg)
{
struct nv_vgpu_ioctl_get_info info;
@@ -260,4 +266,42 @@ int nv_vgpu_ioctl_migrate_restore(struct nv_vgpu_device *vgpu, void __user *arg)
return -EFAULT;
return ret;
+}
+
+int nv_vgpu_ioctl_register_vgpu_type(void __user *arg)
+{
+ struct nv_vgpu_ioctl_register_vgpu_type params;
+ struct nv_vgpu_type_info info;
+ int ret;
+
+ if (copy_from_user(&params, arg, sizeof(params)))
+ return -EFAULT;
+
+ memset(&info, 0, sizeof(info));
+ strncpy(info.name, params.name, sizeof(info.name) - 1);
+ strncpy(info.description, params.description, sizeof(info.description) - 1);
+ info.vdev_id = params.vdev_id;
+ info.pdev_id = params.pdev_id;
+ info.max_instances = params.max_instances;
+
+ ret = nv_vgpu_register_type_info(&info);
+ if (ret)
+ return ret;
+
+ /* Re-create mdev types with updated info */
+ nv_vgpu_free_type_info();
+ ret = nv_vgpu_create_mdev_types();
+ if (ret)
+ return ret;
+
+ /* Re-register mdev driver with new types */
+ mdev_unregister_driver(&nv_vgpu_mdev_driver);
+ ret = mdev_register_driver(&nv_vgpu_mdev_driver);
+ if (ret) {
+ pr_err("Failed to re-register mdev driver: %d\n", ret);
+ return ret;
+ }
+
+ pr_info("vGPU type '%s' registered via ioctl\n", info.name);
+ return 0;
} \ No newline at end of file
diff --git a/kernel/main.c b/kernel/main.c
index a277356..5d9d8ef 100644
--- a/kernel/main.c
+++ b/kernel/main.c
@@ -41,9 +41,16 @@ static int nv_vgpu_config_space_init(struct nv_vgpu_device *vgpu, struct pci_dev
static ssize_t nv_vgpu_config_read(struct nv_vgpu_device *vgpu, char __user *buf, size_t count, loff_t *ppos);
static ssize_t nv_vgpu_config_write(struct nv_vgpu_device *vgpu, const char __user *buf, size_t count, loff_t *ppos);
-static struct mdev_type *nv_vgpu_mdev_types[4];
+/* vGPU type management */
+int nv_vgpu_register_type_info(struct nv_vgpu_type_info *info);
+struct nv_vgpu_type_info *nv_vgpu_find_type_info(const char *name);
-static struct mdev_driver nv_vgpu_mdev_driver = {
+struct mdev_type *nv_vgpu_mdev_types[16];
+struct nv_vgpu_type_info g_vgpu_type_infos[16];
+int g_num_vgpu_types = 0;
+static DEFINE_MUTEX(g_vgpu_type_lock);
+
+struct mdev_driver nv_vgpu_mdev_driver = {
.device_api = VFIO_DEVICE_API_PCI_STRING,
.max_instances = 8,
.probe = nv_vgpu_mdev_create,
@@ -219,6 +226,118 @@ static void populate_rm_ops(void)
g_rm_vgpu_vfio_ops.update_request = nv_vgpu_update_request_callback;
}
+/* ============================================================
+ * vGPU Type Management (userspace provides info via ioctl)
+ * ============================================================ */
+
+int nv_vgpu_register_type_info(struct nv_vgpu_type_info *info)
+{
+ int i;
+
+ mutex_lock(&g_vgpu_type_lock);
+
+ /* Check if already registered */
+ for (i = 0; i < g_num_vgpu_types; i++) {
+ if (strcmp(g_vgpu_type_infos[i].name, info->name) == 0) {
+ /* Update existing */
+ g_vgpu_type_infos[i] = *info;
+ mutex_unlock(&g_vgpu_type_lock);
+ return 0;
+ }
+ }
+
+ /* Add new */
+ if (g_num_vgpu_types >= 16) {
+ mutex_unlock(&g_vgpu_type_lock);
+ return -ENOSPC;
+ }
+
+ g_vgpu_type_infos[g_num_vgpu_types] = *info;
+ g_num_vgpu_types++;
+
+ mutex_unlock(&g_vgpu_type_lock);
+
+ pr_info("Registered vGPU type: name='%s', vdev=0x%llx, pdev=0x%llx, max_inst=%u\n",
+ info->name, info->vdev_id, info->pdev_id, info->max_instances);
+ return 0;
+}
+EXPORT_SYMBOL(nv_vgpu_register_type_info);
+
+struct nv_vgpu_type_info *nv_vgpu_find_type_info(const char *name)
+{
+ int i;
+
+ mutex_lock(&g_vgpu_type_lock);
+ for (i = 0; i < g_num_vgpu_types; i++) {
+ if (strcmp(g_vgpu_type_infos[i].name, name) == 0) {
+ mutex_unlock(&g_vgpu_type_lock);
+ return &g_vgpu_type_infos[i];
+ }
+ }
+ mutex_unlock(&g_vgpu_type_lock);
+ return NULL;
+}
+EXPORT_SYMBOL(nv_vgpu_find_type_info);
+
+static void nv_vgpu_create_static_types(void)
+{
+ int i;
+ struct nv_vgpu_type_info static_types[4] = {
+ { .name = "nvidia-vgpu-ampere", .description = "NVIDIA Ampere vGPU", .vdev_id = 0x10de2235, .pdev_id = 0x10de2235, .max_instances = 1 },
+ { .name = "nvidia-vgpu-hopper", .description = "NVIDIA Hopper vGPU", .vdev_id = 0x10de2331, .pdev_id = 0x10de2331, .max_instances = 1 },
+ { .name = "nvidia-vgpu-turing", .description = "NVIDIA Turing vGPU", .vdev_id = 0x10de1ed3, .pdev_id = 0x10de1ed3, .max_instances = 1 },
+ { .name = "nvidia-vgpu-pascal", .description = "NVIDIA Pascal vGPU", .vdev_id = 0x10de1db1, .pdev_id = 0x10de1db1, .max_instances = 1 },
+ };
+
+ for (i = 0; i < 4; i++) {
+ nv_vgpu_register_type_info(&static_types[i]);
+ }
+}
+
+int nv_vgpu_create_mdev_types(void)
+{
+ int i, ret;
+
+ for (i = 0; i < g_num_vgpu_types; i++) {
+ nv_vgpu_mdev_types[i] = kzalloc(sizeof(struct mdev_type), GFP_KERNEL);
+ if (!nv_vgpu_mdev_types[i]) {
+ ret = -ENOMEM;
+ goto err_types;
+ }
+ nv_vgpu_mdev_types[i]->sysfs_name = kstrdup(g_vgpu_type_infos[i].name, GFP_KERNEL);
+ nv_vgpu_mdev_types[i]->pretty_name = kstrdup(g_vgpu_type_infos[i].description[0] ? g_vgpu_type_infos[i].description : g_vgpu_type_infos[i].name, GFP_KERNEL);
+ if (!nv_vgpu_mdev_types[i]->sysfs_name || !nv_vgpu_mdev_types[i]->pretty_name) {
+ ret = -ENOMEM;
+ goto err_types;
+ }
+ }
+
+ return 0;
+
+err_types:
+ for (i = 0; i < g_num_vgpu_types; i++) {
+ kfree(nv_vgpu_mdev_types[i]->sysfs_name);
+ kfree(nv_vgpu_mdev_types[i]->pretty_name);
+ kfree(nv_vgpu_mdev_types[i]);
+ nv_vgpu_mdev_types[i] = NULL;
+ }
+ return ret;
+}
+EXPORT_SYMBOL(nv_vgpu_create_mdev_types);
+
+void nv_vgpu_free_type_info(void)
+{
+ int i;
+ for (i = 0; i < g_num_vgpu_types; i++) {
+ kfree(nv_vgpu_mdev_types[i]->sysfs_name);
+ kfree(nv_vgpu_mdev_types[i]->pretty_name);
+ kfree(nv_vgpu_mdev_types[i]);
+ nv_vgpu_mdev_types[i] = NULL;
+ }
+ g_num_vgpu_types = 0;
+}
+EXPORT_SYMBOL(nv_vgpu_free_type_info);
+
/* get_ops: called by nvidia-vgpu-vfio to get RM ops */
NV_STATUS nvidia_vgpu_vfio_get_ops(rm_vgpu_vfio_ops_t *ops)
{
@@ -230,6 +349,7 @@ NV_STATUS nvidia_vgpu_vfio_get_ops(rm_vgpu_vfio_ops_t *ops)
pr_info("nvidia-vgpu-vfio: get_ops provided RM ops\n");
return NV_OK;
}
+EXPORT_SYMBOL(nvidia_vgpu_vfio_get_ops);
/* set_ops: called by nvidia-vgpu-vfio to provide VFIO ops */
NV_STATUS nvidia_vgpu_vfio_set_ops(vgpu_vfio_ops_t *ops)
@@ -241,11 +361,68 @@ NV_STATUS nvidia_vgpu_vfio_set_ops(vgpu_vfio_ops_t *ops)
pr_info("nvidia-vgpu-vfio: set_ops received VFIO ops\n");
return NV_OK;
}
+EXPORT_SYMBOL(nvidia_vgpu_vfio_set_ops);
+
+/* mdev driver registration - called by nvidia.ko */
+int nv_vgpu_mdev_driver_register(void)
+{
+ pr_info("nvidia-vgpu-vfio: mdev driver register\n");
+ return mdev_register_driver(&nv_vgpu_mdev_driver);
+}
+EXPORT_SYMBOL(nv_vgpu_mdev_driver_register);
+
+void nv_vgpu_mdev_driver_unregister(void)
+{
+ pr_info("nvidia-vgpu-vfio: mdev driver unregister\n");
+ mdev_unregister_driver(&nv_vgpu_mdev_driver);
+}
+EXPORT_SYMBOL(nv_vgpu_mdev_driver_unregister);
+
+/* mdev parent device registration - called by nvidia.ko */
+
+int nv_vgpu_mdev_register_parent(struct pci_dev *pdev)
+{
+ struct mdev_parent *parent;
+ int ret;
+
+ pr_info("nvidia-vgpu-vfio: mdev parent register for %s\n", pci_name(pdev));
+
+ if (g_mdev_parent) {
+ pr_warn("mdev parent already registered\n");
+ return 0;
+ }
+
+ parent = kzalloc(sizeof(*parent), GFP_KERNEL);
+ if (!parent)
+ return -ENOMEM;
-extern NV_STATUS nv_vgpu_mdev_register_parent(struct pci_dev *pdev);
-extern void nv_vgpu_mdev_unregister_parent(struct pci_dev *pdev);
-extern int nv_vgpu_mdev_driver_register(void);
-extern void nv_vgpu_mdev_driver_unregister(void);
+ parent->dev = &pdev->dev;
+
+ ret = mdev_register_parent(parent, &pdev->dev, &nv_vgpu_mdev_driver,
+ nv_vgpu_mdev_types, g_num_vgpu_types);
+ if (ret) {
+ pr_err("Failed to register mdev parent: %d\n", ret);
+ kfree(parent);
+ return ret;
+ }
+
+ g_mdev_parent = parent;
+ pr_info("mdev parent registered successfully with %d types\n", g_num_vgpu_types);
+ return 0;
+}
+EXPORT_SYMBOL(nv_vgpu_mdev_register_parent);
+
+void nv_vgpu_mdev_unregister_parent(struct pci_dev *pdev)
+{
+ pr_info("nvidia-vgpu-vfio: mdev parent unregister for %s\n", pci_name(pdev));
+
+ if (g_mdev_parent) {
+ mdev_unregister_parent(g_mdev_parent);
+ kfree(g_mdev_parent);
+ g_mdev_parent = NULL;
+ }
+}
+EXPORT_SYMBOL(nv_vgpu_mdev_unregister_parent);
MODULE_SOFTDEP("pre: nvidia");
@@ -342,27 +519,14 @@ static int __init nv_vgpu_init(void)
return ret;
}
- for (i = 0; i < 4; i++) {
- nv_vgpu_mdev_types[i] = kzalloc(sizeof(struct mdev_type), GFP_KERNEL);
- if (!nv_vgpu_mdev_types[i]) {
- ret = -ENOMEM;
- goto err_types;
- }
- }
-
- nv_vgpu_mdev_types[0]->sysfs_name = "nvidia-vgpu-ampere";
- nv_vgpu_mdev_types[0]->pretty_name = "NVIDIA Ampere vGPU";
- nv_vgpu_mdev_types[1]->sysfs_name = "nvidia-vgpu-hopper";
- nv_vgpu_mdev_types[1]->pretty_name = "NVIDIA Hopper vGPU";
- nv_vgpu_mdev_types[2]->sysfs_name = "nvidia-vgpu-turing";
- nv_vgpu_mdev_types[2]->pretty_name = "NVIDIA Turing vGPU";
- nv_vgpu_mdev_types[3]->sysfs_name = "nvidia-vgpu-pascal";
- nv_vgpu_mdev_types[3]->pretty_name = "NVIDIA Pascal vGPU";
+ /* Create static vGPU types as fallback (userspace can override via ioctl) */
+ nv_vgpu_create_static_types();
- ret = mdev_register_driver(&nv_vgpu_mdev_driver);
+ /* Create mdev types from registered vGPU types */
+ ret = nv_vgpu_create_mdev_types();
if (ret) {
- pr_err("Failed to register mdev driver: %d\n", ret);
- goto err_types;
+ pr_err("Failed to create mdev types: %d\n", ret);
+ goto err_class;
}
/* Find the parent PCI device to register mdev parent */
@@ -370,17 +534,25 @@ static int __init nv_vgpu_init(void)
if (!pdev) {
pr_err("Failed to find NVIDIA GPU (10de:1ed3) for mdev parent registration\n");
ret = -ENODEV;
- goto err_driver;
+ goto err_types;
}
/* Register mdev parent via nvidia.ko */
ret = nv_vgpu_mdev_register_parent(pdev);
- pci_dev_put(pdev);
if (ret) {
pr_err("Failed to register mdev parent: %d\n", ret);
- goto err_driver;
+ goto err_put_pdev;
}
+ ret = mdev_register_driver(&nv_vgpu_mdev_driver);
+ if (ret) {
+ pr_err("Failed to register mdev driver: %d\n", ret);
+ goto err_types;
+ }
+
+ pci_dev_put(pdev);
+ pdev = NULL;
+
/* Provide VFIO ops to host driver (nvidia.ko) */
ret = nvidia_vgpu_vfio_set_ops(&nv_vgpu_vfio_ops);
if (ret) {
@@ -394,10 +566,11 @@ static int __init nv_vgpu_init(void)
err_driver:
mdev_unregister_driver(&nv_vgpu_mdev_driver);
err_types:
- for (i = 0; i < 4; i++) {
- kfree(nv_vgpu_mdev_types[i]);
- nv_vgpu_mdev_types[i] = NULL;
- }
+ nv_vgpu_free_type_info();
+err_put_pdev:
+ if (pdev)
+ pci_dev_put(pdev);
+err_class:
class_destroy(nv_vgpu_driver.class);
return ret;
}
@@ -441,10 +614,7 @@ static void __exit nv_vgpu_exit(void)
class_destroy(nv_vgpu_driver.class);
- for (i = 0; i < 4; i++) {
- kfree(nv_vgpu_mdev_types[i]);
- nv_vgpu_mdev_types[i] = NULL;
- }
+ nv_vgpu_free_type_info();
pr_info("NVIDIA vGPU VFIO driver unloaded\n");
}
@@ -558,7 +728,7 @@ static int nv_vgpu_config_space_init(struct nv_vgpu_device *vgpu, struct pci_dev
{
u8 *cfg = vgpu->pci_config;
u16 vendor_id = 0x10de; /* NVIDIA */
- u16 device_id = 0x1ed3; /* TU104 vGPU */
+ u16 device_id = 0x1ed3; /* TU104 vGPU (default) */
u16 subsys_vendor = 0x10de;
u16 subsys_device = 0x12b4;
u8 revision = 0xa1;
@@ -569,9 +739,25 @@ static int nv_vgpu_config_space_init(struct nv_vgpu_device *vgpu, struct pci_dev
u8 latency = 0x00;
u8 header_type = 0x00; /* Normal device */
u8 bist = 0x00;
+ int i;
memset(cfg, 0, 256);
+ /* Look up vGPU type info from mdev type name */
+ if (vgpu->mdev && vgpu->mdev->type && vgpu->mdev->type->sysfs_name) {
+ for (i = 0; i < g_num_vgpu_types; i++) {
+ if (strcmp(vgpu->mdev->type->sysfs_name, g_vgpu_type_infos[i].name) == 0) {
+ vendor_id = (u16)(g_vgpu_type_infos[i].vdev_id & 0xFFFF);
+ device_id = (u16)((g_vgpu_type_infos[i].vdev_id >> 16) & 0xFFFF);
+ subsys_vendor = (u16)(g_vgpu_type_infos[i].pdev_id & 0xFFFF);
+ subsys_device = (u16)((g_vgpu_type_infos[i].pdev_id >> 16) & 0xFFFF);
+ nv_vgpu_info(vgpu, "Using vGPU type: name='%s', vendor=0x%04x, device=0x%04x, subsys_vendor=0x%04x, subsys_device=0x%04x",
+ g_vgpu_type_infos[i].name, vendor_id, device_id, subsys_vendor, subsys_device);
+ break;
+ }
+ }
+ }
+
/* PCI Header (offset 0x00-0x3F) */
cfg[0x00] = vendor_id & 0xff;
cfg[0x01] = (vendor_id >> 8) & 0xff;
@@ -766,7 +952,7 @@ static int nv_vgpu_config_space_init(struct nv_vgpu_device *vgpu, struct pci_dev
cfg[0x9f] = 0x00;
vgpu->config_space_dirty = false;
- nv_vgpu_info(vgpu, "PCI config space initialized (vendor=0x%04x, device=0x%04x)", vendor_id, device_id);
+ nv_vgpu_info(vgpu, "PCI config space initialized (vendor=0x%04x, device=0x%04x, subsys_vendor=0x%04x, subsys_device=0x%04x)", vendor_id, device_id, subsys_vendor, subsys_device);
return 0;
}
@@ -850,5 +1036,23 @@ static ssize_t nv_vgpu_config_write(struct nv_vgpu_device *vgpu, const char __us
return pos - *ppos + count;
}
+/* ============================================================
+ * Exported symbols for nvidia.ko (vGPU VFIO interface)
+ * ============================================================ */
+
+NV_STATUS nvidia_vgpu_vfio_probe(struct pci_dev *pdev)
+{
+ pr_info("nvidia-vgpu-vfio: nvidia_vgpu_vfio_probe called for %s\n", pci_name(pdev));
+ return NV_OK;
+}
+EXPORT_SYMBOL(nvidia_vgpu_vfio_probe);
+
+void nvidia_vgpu_vfio_remove(struct pci_dev *pdev, NvBool remove_device)
+{
+ pr_info("nvidia-vgpu-vfio: nvidia_vgpu_vfio_remove called for %s, remove_device=%d\n",
+ pci_name(pdev), remove_device);
+}
+EXPORT_SYMBOL(nvidia_vgpu_vfio_remove);
+
module_init(nv_vgpu_init);
module_exit(nv_vgpu_exit);
diff --git a/scripts/create_mdev.sh b/scripts/create_mdev.sh
index f6c76ed..a6ea91e 100755
--- a/scripts/create_mdev.sh
+++ b/scripts/create_mdev.sh
@@ -5,10 +5,10 @@
set -euo pipefail
PCI_ADDR="${1:-}"
-VGPU_TYPE="${2:-nvidia-vgpu-turing}"
+VGPU_TYPE="${2:-pci-nvidia-vgpu-turing}"
-# Supported vGPU types
-VALID_TYPES=("nvidia-vgpu-ampere" "nvidia-vgpu-hopper" "nvidia-vgpu-turing" "nvidia-vgpu-pascal")
+# Supported vGPU types (matching the mdev type names)
+VALID_TYPES=("pci-nvidia-vgpu-ampere" "pci-nvidia-vgpu-hopper" "pci-nvidia-vgpu-turing" "pci-nvidia-vgpu-pascal")
# Find NVIDIA GPU if not specified
if [[ -z "$PCI_ADDR" ]]; then
diff --git a/scripts/load_vgpu_stack.sh b/scripts/load_vgpu_stack.sh
index 36211bc..5e7d6fd 100755
--- a/scripts/load_vgpu_stack.sh
+++ b/scripts/load_vgpu_stack.sh
@@ -9,32 +9,23 @@ FIRMWARE_NAME="${1:-gsp-570.144.fwimage.bin}"
BASE_DIR="$OPEN_IOV_ROOT"
NVIDIA_KO="$BASE_DIR/nvidia-open-gpu-kernel-modules/kernel-open/nvidia.ko"
VFIO_KO="$BASE_DIR/kernel/open-iov-vfio.ko"
-GSP_VGPU_KO="$BASE_DIR/driver/gsp-vgpu.ko"
-FIRMWARE_PATH="$BASE_DIR/firmware/570-GSP/$FIRMWARE_NAME"
+FIRMWARE_PATH="$BASE_DIR/firmware/57X-GSP/570.144/$FIRMWARE_NAME"
echo "=========================================="
-echo "Loading vGPU Driver Stack"
+echo "Loading vGPU Driver Stack (Refactored: Host-only GSP Emulation)"
echo "=========================================="
echo "Firmware: $FIRMWARE_NAME"
echo ""
# Check files exist
-for f in "$NVIDIA_KO" "$VFIO_KO" "$GSP_VGPU_KO" "$FIRMWARE_PATH"; do
+for f in "$NVIDIA_KO" "$VFIO_KO" "$FIRMWARE_PATH"; do
if [[ ! -f "$f" ]]; then
echo "ERROR: Missing file: $f"
exit 1
fi
done
-# Check if already loaded
-if lsmod | grep -q "^nvidia "; then
- echo "nvidia.ko already loaded"
-else
- echo "Loading nvidia.ko (OpenRM)..."
- sudo insmod "$NVIDIA_KO"
- echo " OK"
-fi
-
+# Load open-iov-vfio.ko FIRST (provides symbols nvidia.ko needs)
if lsmod | grep -q "^open_iov_vfio "; then
echo "open-iov-vfio.ko already loaded"
else
@@ -43,11 +34,12 @@ else
echo " OK"
fi
-if lsmod | grep -q "^gsp_vgpu "; then
- echo "gsp-vgpu.ko already loaded"
+# Check if already loaded
+if lsmod | grep -q "^nvidia "; then
+ echo "nvidia.ko already loaded"
else
- echo "Loading gsp-vgpu.ko with firmware=$FIRMWARE_NAME..."
- sudo insmod "$GSP_VGPU_KO" firmware_name="$FIRMWARE_NAME"
+ echo "Loading nvidia.ko (OpenRM)..."
+ sudo insmod "$NVIDIA_KO"
echo " OK"
fi
@@ -55,10 +47,10 @@ echo ""
echo "=========================================="
echo "Driver Stack Loaded Successfully"
echo "=========================================="
-lsmod | grep -E "nvidia|open_iov|gsp_vgpu"
+lsmod | grep -E "nvidia|open_iov"
echo ""
echo "Device nodes:"
-ls -la /dev/gsp-vgpu* /dev/nvidia* 2>/dev/null || echo " (none yet - create mdev first)"
+ls -la /dev/nvidia* 2>/dev/null || echo " (none yet - create mdev first)"
echo ""
echo "Next steps:"
echo " 1. Create mdev: $BASE_DIR/scripts/create_mdev.sh"