virtio-nvgpu는 KVM 가상 머신에서 거의 본래 수준의 NVIDIA GPU 성능을 가능하게 합니다

KVM 가상 머신 내부의 거의 본래 수준의 NVIDIA GPU 접근

핵심 요약: virtio-nvgpu는 호스트와 가상 머신 간에 NVIDIA 커널 드라이버의 ioctls를 드라이버 ABI 수준에서 전달하여, Linux KVM 가상 머신이 수정되지 않은 NVIDIA 사용자 모드 드라이버를 실행하고, 본래 시스템과 비교해 2% 내외의 렌더링 성능을 달성하며, 거의 추가적인 CPU 비용 없이 가능하게 합니다.


작동 방식

  • **가상 머신 커널 드라이버 (GPL)**는 일반적인 /dev/nvidia* 노드를 등록합니다. 각 ioctl() 호출 시 원시 요청을 virtqueue에 직렬화하고, mmap() 시에는 공유 메모리 창을 가상 머신 프로세스에 직접 매핑합니다.
  • **장치 크레이트 (Apache-2.0, Rust)**는 VMM 내에서 실행되며, 이러한 virtqueue 메시지를 수신하고 내장된 파일 디스크립터와 포인터를 변환한 후, 호스트의 NVIDIA 드라이버로 ioctl을 전달합니다. 버퍼 관리는 여기에 있습니다.
  • 이벤트 virtqueue는 GPU가 작업을 완료했을 때 가상 머신에 알립니다. 이로 인해 바쁜 폴링이 제거됩니다.
  • 격리 계획 – 미래의 각 가상 머신용 사전 격리된 보조 프로세스(isolate 컴포넌트)가 실제 장치 파일 디스크립터를 보유할 예정입니다. 현재는 VMM 프로세스가 직접 이를 보유하고 있습니다.

이 아키텍처는 chromeos/virtio-media를 모방합니다: GPL 라이선스의 가상 머신 드라이버와 허용성 라이선스를 가진, VMM에 종속되지 않는 장치 크레이트가 함께 있으며, 모든 VMM 상호작용은 트레이트로 표현됩니다.


성능 결과 (RTX 3060, 드라이버 595.99.02)

메트릭 가상 머신 (virtio-nvgpu) 본래 시스템 호스트
일반 게임 렌더링 프레임 시간 (≥2 ms) -0.4% ~ +1.7% (노이즈 수준 내) —
초경량 렌더링 프레임 시간 (≤0.5 ms) 최대 +40.8% (대기 비용이 주요 원인) —
100fps 비패스 실행 시 CPU 사용량 (12초) 0.37초 0.40초
프레임당 호스트-가상 머신 전환 횟수 ≈0.02 (약 59프레임당 1회) 수천 회 (Venus)
다중 가상 머신 스케일링 (RTX 3060에 4개 가상 머신) 총 103.7fps, 각각 약 25.8fps, 싱글 가상 머신 성능과 동일 —

해석: GPU 기반 작업 부하에 대해 가상 머신은 본래 시스템과 구분할 수 없으며, 프레임 예산이 GPU 깨우기 지연 시간(~0.02ms)보다 작은 경우에만 측정 가능한 손실이 나타납니다.


지원되는 사용 사례

  • Vulkan 및 OpenGL 렌더링 (헤드리스 EGL도 작동함)
  • 가상 머신 내부의 Wayland 컴포지터, 오프스크린 프레임 출력
  • CUDA 메모리 할당 및 Vulkan/GL과의 제로-코피 상호운용성
  • 가상 머신 측 CUDA 버퍼에서 직접 NVENC 인코딩 (H.264/H.265 출력)

이 설계는 물리적 스캔아웃, MIG/SR-IOV, 그리고 완전한 통합 가상 메모리(cudaMallocManaged)를 의도적으로 제외합니다.


드라이버 ABI 처리

NVIDIA의 커널 드라이버 ABI는 릴리스 간에 변경됩니다. virtio-nvgpu는 명시적인 ABI 프로파일을 제공합니다:

프로파일 적용 범위
535.129.03 535.129.03부터 다음 프로파일까지
580.178.04 580.178.04부터 다음 프로파일까지
595.71.05 595.71.05 및 이후 버전

535.129.03보다 오래된 드라이버는 거부됩니다. 더 새로운 드라이버는 마지막 프로파일에 따라 수용되며, 새로운 프로파일이 추가될 때까지 유지됩니다. 프로파일은 NVIDIA의 open-gpu-kernel-modules 소스에서 기계적으로 생성되며, 수동으로 입력된 것이 아닙니다.


다른 GPU 가상화 접근 방식과의 비교

접근 방식 가상 머신 드라이버 API 번역 GPU 공유 NVENC 지원 격리 수준
VFIO 패스스루 호스트 드라이버가 가상 머신 PCI 장치에 바인딩됨 없음 (네이티브) GPU당 하나의 VM (또는 전용 카드) 네이티브로 작동 강함 (IOMMU가 가상 머신 메모리를 격리함)
virtio-gpu + Venus 가상 머신 Mesa 드라이버 (virgl) 프레임당 단일 호출 직렬화 및 재생 여러 VM이 GPU 공유 불가능 (버퍼가 호스트에 존재함) 중간
virtio-nvgpu (이 프로젝트) 수정되지 않은 NVIDIA 사용자 모드 드라이버 드라이버 ABI 수준에서 ioctl 전달 (약 프레임당 1회 전환) 여러 VM이 단일 카드 공유 (최대 4개까지 테스트됨) 작동, 제로-코피 약함 – 모든 ioctl이 전달됨; 호스트 드라이버는 TCB에 있음

핵심 통찰: 그래픽 API가 아닌 커널 드라이버 수준에서 번역 경계를 이동함으로써, virtio-nvgpu는 Venus의 막대한 프레임당 호출 오버헤드를 제거하면서도 여러 가상 머신이 GPU를 공유할 수 있게 합니다.


보안 및 격리 고려 사항

  • 가상 머신 GPU 작업과 호스트 메모리 사이에 IOMMU 경계가 없음. 호스트 NVIDIA 드라이버는 호스트의 IOMMU 도메인에서 실행되며, 신뢰할 수 있는 컴퓨팅 기반(TCB)의 일부로 간주됨.
  • 현재 구현은 모든 드라이버 ioctl을 전달하지만, ABI 프로파일에서 명시적으로 거부된 것만 제외함. 디버깅을 위해 더 관대한 플래그(--permissive-abi)를 사용할 수 있음.
  • 미래 작업(isolate/)은 각 가상 머신용 격리된 보조 프로세스에 실제 장치 파일 디스크립터를 격리하려는 것이지만, 아직 구현되지 않음.
  • VFIO와 비교했을 때 공격 표면은 더 큼: 해킹된 가상 머신은 허용된 모든 ioctl을 실행할 수 있으며, 호스트에서 GPU를 공유하는 여러 프로세스를 실행하는 것과 유사함.

커뮤니티 피드백 (Hacker News 요약)

  • @refibrillator는 GPU 공유의 세 가지 주요 방법(VFIO, virtio-gpu/Venus, virtio-nvgpu)을 언급하고, virtio-nvgpu가 호스트 드라이버가 TCB에 있기 때문에 가장 약한 격리 수준을 제공한다고 지적함.
  • @orphereus는 왜 일반 GPU 패스스루를 사용하지 않는지 묻고, 답은 패스스루로 VM 간 GPU 공유가 불가능하다는 것임.
  • @markasoftware는 이 것이 gVisor의 nvproxy와 어떻게 다른지 묻고, README는 nvproxy를 직접적인 영감으로 언급하지만 차이점은 상세히 설명하지 않음.
  • @ericd는 VFIO 복잡성 없이 성능이 뛰어난 게임용 가상 머신에 대해 기대감을 표현함.
  • @majorchord는 Windows 가상 머신 지원 여부를 묻고, 현재 프로젝트는 Linux 가상 머신만 대상으로 함.

저장소 구조

디렉터리 라이선스 목적
driver/ GPL-2.0 virtqueue를 통해 ioctl과 mmap을 전달하는 가상 머신 커널 모듈
device/ Apache-2.0 VMM에 종속되지 않는 Rust 크레이트로 virtio 장치 및 ABI 번역 구현
isolate/ Apache-2.0 미래의 각 가상 머신용 격리된 보조 프로세스 설계 노트 (코드 없음)
gen/ — NVIDIA 소스에서 기계적으로 생성된 ABI 테이블
protocol/ BSD-3-Clause OR GPL-2.0+ 공유된 와이어 형식 및 ABI 정의

시작하기

  1. 가상 머신 드라이버(driver/)를 빌드하고 KVM 가상 머신 내부에 로드합니다.
  2. 필요한 트레이트(디스크립터 체인 I/O, 이벤트 처리, 가상 머신/호스트 메모리 매핑)를 구현하여 device/ 크레이트를 VMM에 통합합니다.
  3. 가상 머신 내부에서 Vulkan 또는 Wayland 애플리케이션을 실행합니다. README의 벤치마크 스크립트(BENCHMARKS.md)를 통해 거의 본래 수준의 성능을 검증할 수 있습니다.

제한 사항 및 미래 작업

  • 단일 RTX 3060에 최대 4개의 가상 머신에서 테스트됨; 더 많은 가상 머신은 테스트되지 않음.
  • 테스트된 드라이버 버전은 595.99.02 (RTX 3060)과 615.71.09 (RTX A2000)뿐이며, 다른 카드는 테스트되지 않음.
  • CUDA 기능은 전달되지만, 열거 외에는 철저히 검증되지 않음.
  • Windows 가상 머신 지원은 아직 없음. 프로젝트는 Linux만 대상으로 함.
  • 격리 개선(각 가상 머신용 사전 격리, seccomp 필터)은 계획되어 있으나 현재는 없음.

라이선스

저장소는 세 가지 라이선스 영역을 포함합니다: 가상 머신 드라이버는 GPL-2.0, 장치 크레이트와 isolate 설계는 Apache-2.0, 공유 프로토콜 헤더는 BSD-3-Clause (또는 GPL-2.0+)입니다.


결론적으로, virtio-nvgpu는 NVIDIA 드라이버 ioctl을 ABI 수준에서 전달함으로써, KVM 가상 머신이 거의 본래 수준의 GPU 성능을 달성하면서도 단일 카드를 여러 VM이 공유할 수 있음을 보여줍니다. 다만, VFIO 패스스루보다는 격리 수준이 약합니다.

Sources