Passing Nvidia GPU back to the host after GPU Passthrough without rebooting the host.
GPU直通:將Nvidia GPU從Linux系統除外(隔離),綁給VFIO核心模組,好讓Windows的QEMU/KVM虛擬機能夠使用Nvidia GPU玩遊戲。
我發動:遊戲王陷阱卡「來自異次元的歸還」!支付一半生命值,從自己的除外牌組盡可能特殊召喚怪獸到自己場上,這個回合結束之後怪獸移除。
在我們將Nvidia GPU直通給Windows虛擬機之後,Linux宿主機就無法使用Nvidia GPU了。那麼可不可以在虛擬機關機之後,不重開機,讓Linux暫時重新存取Nvidia GPU呢?
做得到,但是不直觀。
在不重開機情況下,將Nvidia GPU解除vfio-pci綁定,再載入Nvidia核心模組即可重新讓宿主機存取顯示卡。相反地,虛擬機需要顯示卡的話就得將其手動綁回去。
本文Ivon討論的僅僅是讓宿主機「暫時」取回GPU的作法,不是解除GPU直通的狀態。重開機後GPU依然是維持直通給虛擬機的樣子。
1. 設定Nvidia GPU直通#
- 系統:Ubuntu 24.04
- Nvidia閉源驅動版本:550
這台電腦已經 設定好Nvidia GPU直通,並未解除安裝Linux宿主機的Nvidia閉源驅動。
Nvidia閉源驅動建議用DKMS安裝,這樣它會跟著Linux核心自動更新。否則,若在GPU直通的情況下更新Linux系統,那Nvidia驅動可能就會消失。
如果Nvidia閉源驅動已經解除安裝,那麼你得將GPU直通完全解除,再嘗試用APT安裝Nvidia驅動。
2. 將GPU還給宿主機#
本節內容參考自bryansteiner的作法,雖然可以用libvirt hook自動化執行,也就是告訴Libvirt在虛擬機關機後就把GPU還給宿主機使用,可是我測試有時候會卡死,所以只好手動執行。
將Windows虛擬機關機。
執行指令
sudo lspci -nnk
,應該會看到正在使用Nvidia GPU的是vfio-pci核心模組
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GP107 [GeForce GTX 1050 Ti] [10de:1c82] (rev a1)
Subsystem: ASUSTeK Computer Inc. GP107 [GeForce GTX 1050 Ti] [1043:85d6]
Kernel driver in use: vfio-pci
Kernel modules: nvidiafb, nouveau
01:00.1 Audio device [0403]: NVIDIA Corporation GP107GL High Definition Audio Controller [10de:0fb9] (rev a1)
Subsystem: ASUSTeK Computer Inc. GP107GL High Definition Audio Controller [1043:85d6]
Kernel driver in use: vfio-pci
Kernel modules: snd_hda_intel
- 執行指令
nvidia-smi
,應該會顯示無法偵測到
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver
- 利用virsh指令,解除綁定vfio-pci裝置(
pci_0000_01_00_0
來自lscpi
結果)
sudo virsh nodedev-reattach pci_0000_01_00_0
sudo virsh nodedev-reattach pci_0000_01_00_1
- 取消載入vfio核心模組(如果無法移除,用指令
lsmod | grep vfio
看是哪些核心模組在干擾,並確認移除的順序正確)
sudo modprobe -r vfio_pci
sudo modprobe -r vfio_iommu_type1
sudo modprobe -r vfio
- 嘗試載入Nvidia核心模組
# 若無安裝閉源驅動只需載入:sudo modprobe nouveau
sudo modprobe nvidia_modeset
sudo modprobe nvidia_uvm
sudo modprobe nvidia
- 執行指令
sudo lspci -nnk
,應該會看到正在使用Nvidia GPU的變回nvidia核心模組
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GP107 [GeForce GTX 1050 Ti] [10de:1c82] (rev a1)
Subsystem: ASUSTeK Computer Inc. GP107 [GeForce GTX 1050 Ti] [1043:85d6]
Kernel driver in use: nvidia
Kernel modules: nvidiafb, nouveau, nvidia_drm, nvidia
01:00.1 Audio device [0403]: NVIDIA Corporation GP107GL High Definition Audio Controller [10de:0fb9] (rev a1)
Subsystem: ASUSTeK Computer Inc. GP107GL High Definition Audio Controller [1043:85d6]
Kernel modules: snd_hda_intel
- 執行
nvidia-smi
指令看能不能檢測到顯示卡資訊。
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 550.90.07 Driver Version: 550.90.07 CUDA Version: 12.4 |
|-----------------------------------------+------------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+========================+======================|
| 0 NVIDIA GeForce GTX 1050 Ti Off | 00000000:01:00.0 Off | N/A |
| 29% 37C P8 N/A / 75W | 4MiB / 4096MiB | 0% Default |
| | | N/A |
+-----------------------------------------+------------------------+----------------------+
- 之後可能要重新啟動桌面環境,應用程式才會用Nvidia顯示卡渲染。不然你就得用Nvidia
prime-run
指令強迫應用程式用Nvidia顯示卡渲染了,參見 Nvidia PRIME用法
3. 把GPU直通回虛擬機#
將步驟倒過來做
sudo modprobe -r nvidia_modeset
sudo modprobe -r nvidia_uvm
sudo modprobe -r nvidia
sudo modprobe vfio_pci
sudo modprobe vfio_iommu_type1
sudo modprobe vfio
sudo virsh nodedev-detach pci_0000_01_00_0
sudo virsh nodedev-detach pci_0000_01_00_1