# Install and First Run > **What this page is.** From a fresh Ubuntu host with a supported NVIDIA GPU > to a guest VM running a stock NVIDIA driver and `nvidia-smi`, in about half > an hour. Condensed from the maintained guide > [`../docs/02-getting-started/01-install-and-first-run.md`](../docs/02-getting-started/01-install-and-first-run.md); > the docs tree wins on disagreement. Status: 2026-10-12, tree `master @ 2f066727`. Tags: `[live]` verified path; `[target]` roadmap item. ## 1. Prerequisites **Host** * Ubuntu 22.04 or 24.04, x86_64 (aarch64 is a `[target]`); * an NVIDIA GPU covered by the current emulation profile (Turing TU104 is the reference — see [`Hardware-Software-Matrix.md`](Hardware-Software-Matrix.md)); * a working **host** NVIDIA driver (`nvidia-smi` runs on the host; Open-IOV does not modify it); * IOMMU enabled (`intel_iommu=on` / `amd_iommu=on`), hugepages configured, kernel headers for the running kernel; * `qemu-system-x86_64` with KVM; libvirt optional; * root (or sudo) for module load and mdev creation. **Guest** * Ubuntu 24.04 server (the reference guest), or any Linux with the matching stock NVIDIA driver available; * **no Open-IOV component at all** — that is the point ([`System-Overview.md`](System-Overview.md)). ## 2. Get the code and build ```bash git clone https://git.vgpu.io/open-iov.git cd open-iov ./install.sh deps # build/runtime dependencies ./install.sh nvidia # optional: NVIDIA OpenRM modules + build glue ./install.sh firmware # GSP firmware image (verified) ./install.sh build # kernel module + userspace ``` `install.sh` is safe to re-run. The manual equivalent, and the order that matters: ```bash make kernel # first: generates Module.symvers ./scripts/build_nvidia_openrm.sh # optional (see below) make userspace ``` **Build order matters.** NVIDIA's OpenRM modules resolve symbols that `vgsp.ko` exports; building them in the wrong order produces `Unknown symbol` failures at load time. **The OpenRM stage is optional.** It is needed only for the native vGPU-management workflows in which NVIDIA's modules are built against the symbols `vgsp.ko` exports. The QEMU/emulated path uses the distribution driver that already manages the physical GPU; `load-stack` skips the OpenRM submodule when a distribution driver is present. ## 3. Load the stack and create a virtual GPU ```bash ./scripts/stack_manager.sh status # what is currently loaded ./scripts/stack_manager.sh load-stack # vfio/mdev prereqs -> vgsp.ko -> (optional) nvidia ./scripts/stack_manager.sh mdev-create # create a vGPU mediated device ./scripts/stack_manager.sh mdev-list # inspect /sys/bus/mdev/devices/ ``` The mdev device *is* the virtual GPU; everything after this treats it like any other VFIO device. ## 4. Launch a reference guest ```bash ./scripts/stack_manager.sh qemu # reference raw-QEMU guest with the mdev ``` To integrate with your own stack (libvirt, Xen, ...), attach the mdev exactly as any VFIO device: ```xml
``` **Attach behind a root port, not on the root bus.** QEMU rewrites a device's PCIe capability when it detects a root-complex-integrated endpoint, which changes the link capabilities the guest driver sees. The reference script does this for you. ## 5. Install the stock driver in the guest Inside the guest: ```bash sudo apt update sudo apt install -y linux-headers-generic build-essential # The validated combination is the stock 570.144 Linux runfile (the same # driver version as the emulation target). sudo sh ./NVIDIA-Linux-x86_64-570.144.run sudo reboot ``` Verify: ```bash nvidia-smi # must list the virtual GPU lsmod | grep -c nvidia ``` If `nvidia.ko` fails to probe, capture host dmesg, guest dmesg, guest `lspci -vvv` and the guest module parameters, and file an issue. ## 6. First CUDA check ```bash # in the guest git clone https://github.com/NVIDIA/cuda-samples.git cd cuda-samples/Samples/1_Utilities/deviceQuery && make && ./deviceQuery ``` **Expectation today** (`[live]` unless noted): driver probe, `nvidia-smi`, device enumeration and the full CUDA **driver-API** smoke complete end to end (`ALL OK`, 64-byte payload round-trips). CUDA **kernel execution** is the current frontier: a guest launch is forwarded and reaches the engine queue, but engine execution is not yet observed (`[wall]`) — see [`Project-Status.md`](Project-Status.md) and [`Execution-Frontier.md`](Execution-Frontier.md) before drawing conclusions from a kernel that does not run. ## 7. Day-to-day operations ```bash ./scripts/stack_manager.sh up # build all + load + create mdev ./scripts/stack_manager.sh status # modules, mdev, vfio, firmware ./scripts/stack_manager.sh test # host test suite ./scripts/stack_manager.sh unload # correct-order teardown ./scripts/stack_manager.sh cleanup-crash ``` Load order is prerequisites → kernel module → (optional) NVIDIA OpenRM → firmware; unload is the reverse. Do not `rmmod` by hand while a VM holds the mdev. ## 8. Watching the emulation work The module logs with the prefix **`vgsp-:`** (for example `vgsp-rpc:`, `vgsp-sema:`, `vgsp-work:`) plus per-RPC traces: ```bash sudo dmesg -w | grep -i 'vgsp' # live sudo dmesg -T | grep -i 'vgsp' | tail -50 ``` Developer debug knobs (module parameters) are documented in the repository's debugging workflow document. ## 9. Troubleshooting index | Symptom | Start here | |---|---| | Module will not load | `dmesg`, `modinfo vgsp.ko`, stale module state → `cleanup-crash` | | No mdev type for your GPU | [`Hardware-Software-Matrix.md`](Hardware-Software-Matrix.md) | | Guest sees wrong PCIe link speed/width | attach behind a root port (section 4) | | `nvidia.ko` probe fails in guest | guest dmesg + `lspci -vvv` + [`Driver-Lifecycle-Field-Guide.md`](Driver-Lifecycle-Field-Guide.md) | | `nvidia-smi` works, a CUDA kernel does not run | expected today — the execution frontier, not your setup ([`Execution-Frontier.md`](Execution-Frontier.md)) | | VM boot fails or the guest hangs | `scripts/stack_manager.sh cleanup-crash`, then reboot | ## 10. Uninstall ```bash ./scripts/stack_manager.sh unload ``` The project never modifies your host driver's files; removing the module and its mdev devices returns the host to its previous state.