Sebuah proyek eksperimental bernama virtio-nvgpu menawarkan sesuatu yang selama ini tidak tersedia untuk GPU NVIDIA di lingkungan virtualisasi: akses nyaris native dari dalam guest KVM. Klaim di halaman proyeknya cukup spesifik, guest merender dalam rentang 2% dari mesin tempat ia berjalan, dan biaya CPU-nya sama.
Cara kerjanya berbeda dari pendekatan yang umum. Alih-alih menerjemahkan panggilan API grafis, virtio-nvgpu meneruskan ioctl driver kernel NVIDIA antara guest Linux dan host di level ABI driver. Guest menjalankan driver user-mode milik NVIDIA sendiri, tanpa dimodifikasi, dengan library yang sama, Vulkan dan NVENC yang sama, dan berbicara ke kartu yang sama.
Sasaran utamanya headless streaming: kompositor di dalam VM merender, mengomposit, dan meng-encode frame di GPU, lalu mengirim video terkompresi ke luar. VM-nya tidak punya monitor, dan host tetap memegang kartunya.
Hasil pengukuran yang dipublikasikan
Proyek ini tidak sekadar berjalan, tapi sudah diukur. Sebuah klien Wayland mempresentasikan gambar di dalam guest, lapisan capture meng-encode di perangkat milik game itu sendiri, dan H.264 keluar di sisi lain: 618 frame yang didekode ffmpeg tanpa error.
Pengukurannya dilakukan di RTX 3060 dengan driver 595.99.02, membandingkan guest terhadap host yang sama secara bare metal dengan beban headless Vulkan yang identik. Yang diukur adalah waktu frame guest relatif terhadap host, pada beberapa tingkat berat beban:
| Waktu host per frame | Waktu frame guest |
|---|---|
| 39 ms | 0,4% lebih cepat, dalam batas noise |
| 9,9 ms | 0,7% lebih cepat |
| 2,0 ms | 1,7% lebih lambat |
| 0,5 ms | 7,1% lebih lambat |
| 0,05 ms | 40,8% lebih lambat |
Cara membacanya penting. Di atas sekitar 2 ms per frame, yang menurut proyeknya adalah setiap frame yang digambar game, guest berada dalam rentang 2% dari bare metal. Di bawah angka itu, biaya menunggu GPU mulai terlihat dibandingkan frame yang hampir tidak ada isinya. Pada frame 0,5 ms, satu wake memakan sekitar 0,02 ms, dan frame itu sendiri hanya separuh dari waktu wake tersebut.
Sisi CPU juga diukur, karena GPU bersama hanya bernilai kalau guest-nya murah. Dengan beban tanpa pacing sekitar 100 fps selama 12 detik, satu guest memakai 0,37 detik CPU sementara host bare metal memakai 0,40 detik. Menurut proyeknya, tidak ada biaya yang keluar untuk penerusan di dalam render loop, karena memang tidak ada yang diteruskan: driver user-mode NVIDIA melakukan submit lewat memori yang sudah ia map, dan memori itu milik host. Dari 813.691 frame, backend hanya melayani 13.792 pesan, atau satu penyeberangan batas per 59 frame, dan hampir semuanya adalah penyiapan perangkat.
Beberapa guest di satu kartu
Bagian ini yang paling relevan untuk lingkungan multi-tenant. Empat guest dijalankan di satu RTX 3060 dengan beban yang sama di masing-masing. Hasilnya: 25,84, 26,49, 25,57, dan 25,79 fps, atau 103,7 fps jika digabung, dibandingkan 102,9 fps untuk satu guest saja. Median waktu frame-nya 39,165, 39,164, 39,168, dan 39,165 ms.
Artinya totalnya tidak bergerak ketika guest ditambah, dan pembagiannya merata sampai empat angka desimal. Keempatnya merender dengan benar pada waktu yang sama, dan keempatnya meng-encode H.264 sekaligus dengan pacing tepat 60 Hz, tanpa menyentuh batas sesi NVENC.
Yang perlu ditegaskan: empat adalah jumlah yang dijalankan, bukan batas yang ditemukan. Proyek ini menyebut delapan belum pernah dicoba.
Arsitektur dan pembagian lisensi
Repositori ini dibagi jadi empat komponen dengan tiga zona lisensi, dan pembagiannya disengaja. Bagian guest harus GPL karena menyentuh simbol kernel, bagian host sebaiknya permisif supaya orang lain bisa membangun di atasnya, dan definisi yang dipakai kedua sisi harus bisa disertakan dari keduanya.
| Direktori | Lisensi | Isi |
|---|---|---|
| driver/ | GPL-2.0 | Modul kernel guest. Mendaftarkan /dev/nvidia*, meneruskan ioctl dan mmap lewat virtqueue. Sengaja tidak sadar ABI. |
| device/ | Apache-2.0 | Perangkat virtio sebagai crate Rust tanpa VMM di daftar dependensinya. Semua urusan VMM jadi trait. |
| isolate/ | Apache-2.0 | Catatan desain, belum ada kode. Helper per-guest tersandbox yang nantinya memegang file descriptor perangkat asli. |
| protocol/ | BSD-3-Clause atau GPL-2.0+ | Format wire dan definisi ABI yang dipakai kedua sisi. Dual license supaya driver GPL dan crate Apache bisa menyertakan header yang sama. |
Alur kerjanya bertingkat. Driver kernel guest mendaftarkan /dev/nvidiactl, /dev/nvidia0 sampai /dev/nvidiaN, dan /dev/nvidia-uvm. Saat ada panggilan ioctl(), ia menyerialkan permintaan itu ke virtqueue kontrol. Saat mmap(), ia memetakan region memori bersama yang sesuai ke proses pemanggil dengan atribut caching yang benar. Driver guest hanya menyalin byte mentah dan tidak mengambil keputusan ABI apa pun.
Sisi device menerima permintaan, memetakan handle guest ke file descriptor perangkat host, melakukan terjemahan ioctl yang sadar ABI termasuk menulis ulang pointer dan file descriptor yang tertanam, lalu mengirimkannya ke perangkat host. Pembukuan buffer dan window ada di sini.
Ada juga virtqueue kedua yang berjalan ke arah sebaliknya. Host memantau setiap descriptor yang dibukanya dan memberi tahu ketika salah satunya jadi bisa dibaca. Itulah cara guest yang menunggu GPU dibangunkan. Tanpa itu, guest tidak bisa menunggu sama sekali: ia hanya melakukan polling pada descriptor yang dilaporkan kernel sebagai selalu siap, dan berputar tanpa henti.
Perbandingan dengan pendekatan lain
Proyek ini membandingkan pendekatannya dengan tiga alternatif yang sudah ada.
virtio-gpu dengan Venus. Venus menyerialkan setiap panggilan Vulkan atau OpenGL di guest, mengangkutnya lewat virtio, lalu memutarnya ulang di host. Untuk beban kerja yang berat draw call, ini masalah: game mengeluarkan 1.000 sampai 5.000 draw call per frame plus bind, update descriptor, dan transisi render pass, yang masing-masing diserialkan dan diputar ulang. Pada 60 fps anggaran frame-nya 16,6 ms, dan 1 sampai 3 ms untuk serialisasi berarti 6 sampai 18% habis sebelum kerja GPU dimulai. Selain itu, buffer GPU dimiliki host, sehingga kompositor guest tidak bisa melihat atau mengimpornya, yang berarti encoding di sisi guest tidak layak tanpa readback dan copy penuh lewat CPU.
DRM native context yang dipakai Intel dan AMD. Guest menjalankan driver Mesa asli, membangun command buffer secara lokal, dan hanya submission yang menyeberangi batas. Kepemilikan buffer dan encoding di sisi guest bekerja dengan benar. Masalahnya sederhana: pendekatan ini tidak ada untuk NVIDIA.
VFIO passthrough. Performa native dan tumpukan driver lengkap di guest, tapi seluruh GPU didedikasikan ke satu VM. Di lingkungan multi-tenant, itu sering bukan pilihan.
Perbedaan strukturalnya terlihat di jumlah penyeberangan batas. Venus menyeberang per panggilan API, ribuan kali per frame. virtio-nvgpu menyeberang per ioctl, dan render loop tidak mengeluarkan satu pun, karena submission hanyalah penulisan ke memori yang sudah dipetakan.
Sisi keamanan: yang harus dibaca lebih dulu
Ini bagian yang proyeknya sendiri nyatakan secara terbuka, dan penting dibaca sebelum mempertimbangkan pemakaian. Pertanyaan pertama yang biasanya diajukan orang keamanan adalah sejauh apa guest bisa menjangkau, dan jawaban jujurnya bukan "tidak bisa apa-apa".
Yang paling perlu dipahami: tidak ada batas IOMMU antara kerja GPU guest dan host. Kartunya milik driver NVIDIA host dan berada di domain IOMMU host. Guest menerima antarmuka ioctl dari driver, bukan perangkatnya. Yang memisahkan memori guest dari memori host adalah MMU milik GPU itu sendiri, dengan page table yang diprogram RM atas nama guest. Konsekuensinya, driver NVIDIA host masuk ke dalam trusted computing base.
Guest juga menyusun command stream-nya sendiri, dan itu justru alasan tidak ada biaya per submission. Yang menyempitkan permukaan serangan saat ini: ioctl yang tidak dijelaskan oleh profil ABI akan ditolak, bukan diteruskan. Ada opsi --permissive-abi yang mematikan perilaku itu untuk diagnosis, dan proyeknya menyatakan opsi itu akan berbicara lantang saat dipakai.
Yang belum tertangani, menurut daftar di repositori:
- Kelas
RM_ALLOCdan perintah kontrol RM belum difilter. - Ioctl UVM dan modeset belum punya tabel padanannya.
- Backend masih memegang descriptor host di dalam proses VMM. Helper isolate per-guest yang tidak berhak istimewa sudah didesain tapi belum dibangun.
Kesimpulan proyeknya sendiri jelas dan layak dikutip apa adanya: ini pengurangan permukaan serangan, bukan isolasi perangkat keras. VFIO passthrough dengan IOMMU secara tegas lebih kuat karena membatasi perangkat hanya ke memori guest sendiri, dan untuk penyewa yang saling tidak mempercayai, itu atau vGPU masih jadi jawabannya.
Versi driver: daftar eksplisit, bukan tebakan
ABI driver kernel NVIDIA tidak stabil, dan tata letak struct ioctl berubah antar rilis. Karena itu dukungannya eksplisit, dan seluruh daftarnya hanya tiga profil ABI: 535.129.03, 580.178.04, dan 595.71.05.
Cara kerjanya berbasis rentang, bukan titik. Rilis yang berada di antara dua profil akan memakai profil yang lebih rendah, dan versi yang lebih baru dari profil terakhir akan memakai profil terakhir. Versi yang lebih lama dari 535.129.03 ditolak, bukan ditebak. Alasan yang diberikan masuk akal: meneruskan ioctl yang tata letaknya belum pernah dilihat adalah cara mendapat jawaban salah yang terlihat masuk akal, bukan pesan error.
Versi yang benar-benar dijalankan ada dua. RTX 3060 dengan driver 595.99.02 sudah melewati semuanya: render, presentasi, encoding, dan semua angka di dokumen benchmark. RTX A2000 dengan driver 615.71.09 baru sampai tahap enumerasi dan render, belum di-benchmark dan belum diuji ulang. Proyeknya sendiri menulis, dua kartu dengan dua versi, dan hanya satu yang benar-benar diuji. Sisanya belum teruji.
Yang masuk dan tidak masuk lingkup
Yang disasar proyek ini: rendering Vulkan termasuk presentasi ke kompositor di dalam guest, rendering OpenGL headless lewat EGL, alokasi memori perangkat CUDA, interop CUDA ke Vulkan atau OpenGL dengan zero-copy, serta encoding NVENC dari pointer perangkat CUDA dan dekode NVDEC.
Yang secara sadar dikeluarkan: cudaMallocManaged() dan unified virtual memory penuh, scanout karena tidak ada display fisik, MIG dan SR-IOV, serta dukungan versi driver NVIDIA sembarang. Perlu dicatat juga bahwa presentasi ke kompositor di guest membutuhkan /dev/nvidia-drm dan /dev/nvidia-modeset, keduanya sudah diimplementasikan, dan keduanya bukan display: keduanya adalah cara sebuah buffer menjadi bisa dibagikan.
Proyek yang jadi acuan
Bagian prior art di repositori ini memberi gambaran yang jujur soal asal-usul pendekatannya. Yang paling langsung menginspirasi adalah gVisor nvproxy, yang meneruskan ioctl NVIDIA dari kontainer tersandbox ke driver host, menangani versi ABI, terjemahan pointer dan file descriptor, serta manajemen mmap GPU, dan sudah mendukung Vulkan, OpenGL, CUDA, dan NVENC di produksi. Definisi ABI dan logika handler-nya jadi referensi utama.
chromeos/virtio-media jadi contoh tata letaknya: driver guest berlisensi GPL berdampingan dengan crate perangkat Rust yang tidak bergantung VMM, dengan setiap urusan VMM di balik trait. WSL2 dengan /dev/dxg membuktikan pendekatan proxy GPU di level driver bisa jalan dalam skala besar, meski masalahnya berbeda karena menyasar host Windows. Dan DRM native context di Intel serta AMD jadi pembanding tujuan yang sama, sudah tercapai untuk vendor lain, dan belum ada padanannya untuk NVIDIA.
Cara menilai proyek ini dengan proporsional
Beberapa hal yang layak dipegang sebelum mempertimbangkan adopsi:
- Statusnya eksperimental. Proyek ini menyebut dirinya begitu di deskripsi repositorinya, dan banyak bagian pentingnya belum dibangun, terutama isolate per-guest.
- Angka benchmark berasal dari satu beban sintetis di satu kartu. Proyeknya sendiri menyatakan angkanya tidak mendukung perbandingan dengan hypervisor lain, karena tidak ada hypervisor lain yang dijalankan dalam pengujian itu.
- Multi-tenant belum aman. Tanpa batas IOMMU dan dengan isolate yang belum dibangun, ini bukan pengganti VFIO untuk penyewa yang saling tidak mempercayai.
- Dukungan driver terbatas dan berbasis rentang. Driver yang jauh lebih baru dari profil terakhir diterima dengan asumsi tidak ada yang berubah, dan asumsi itulah hal pertama yang harus dicurigai kalau driver baru bermasalah.
- Yang belum dicoba. Lebih dari empat guest, guest dengan beban lebih berat dari vkcube 720p, dua kartu dengan dua versi driver, dan CUDA di luar enumerasi.
Untuk tim yang menjalankan layanan streaming GPU di infrastruktur sendiri, pendekatan ini layak dipantau karena masalah yang disasar nyata: VFIO memboroskan satu GPU untuk satu VM, sementara Venus terlalu mahal untuk beban kerja yang padat draw call. Yang belum jelas adalah apakah pengurangan permukaan serangan yang ada sekarang cukup untuk dipakai di luar lingkungan yang sepenuhnya tepercaya. Sampai isolate per-guest itu dibangun dan diuji, jawabannya cenderung tidak.
Sumber
- nestrilabs/virtio-nvgpu, README, ARCHITECTURE.md, dan BENCHMARKS.md, diakses 25 September 2026: https://github.com/nestrilabs/virtio-nvgpu
- Diskusi publik atas proyek ini di Hacker News, halaman depan 24 September 2026: https://news.ycombinator.com/item?id=44670000
Catatan: seluruh angka benchmark, daftar fitur, dan catatan keamanan dalam artikel ini bersumber dari dokumentasi resmi repositori proyek dan belum diverifikasi lewat pengujian independen. Angka performa berasal dari satu beban sintetis pada satu kartu, dan proyeknya sendiri menyatakan hasil itu tidak mendukung perbandingan dengan hypervisor lain.
💬 Komentar (0)
Belum ada komentar. Jadilah yang pertama! 💬