Fedora qemu/kvm gpu 直通(passthrough) 筆記

來自舊文章移植

該文章來源: https://hackmd.io/@U9m9FarsR0SQGVuSmTJNiw/HkBjGlwuq
日期: 2022/6/3

原本打算用 Windows 的 docker 開遊戲伺服器就好,不過總會覺得效能很差,所以想用原生 Linux 開伺服器。
由於要用同一台電腦開 Windows 玩遊戲,所以雙開(dual boot)就不適合我的需求。
於是乎,用 vm 並且 gpu passthrough 成了唯一選項(大概),但也是最難搞的一個,因為 Linux 發行版、版本、硬體的不同,網路上各種不同方法,許多都因為是很久以前版本的方法所以不管用,更不用說大多數都英文(雖然大部分都看得懂),導致我弄了整整快三天了吧…

這篇作為筆記,記錄我實作的過程,因為發行版、硬體的不同,過程會有所不同,僅供參考。

使用硬體

  • CPU: intel i7-10700kf
  • GPU1: nvidia rtx3060 ti (作為 guest, Windows)
  • GPU2: nvidia gt710 (作為 host, Linux)
  • Mother: msi z590 torpedo

BIOS

開啟 intel VT-D 功能,我的 bios 預設是關閉的,位於 Overclocking\CPU Features,需打開(Enabled)

安裝 nvidia 驅動

要先有 nvidia 的驅動,否則進 vm 沒多久會崩潰 Fedora 安裝方式見 https://rpmfusion.org/Howto/NVIDIA

安裝虛擬套件

1
2
3
sudo yum -y install @virtualization
sudo systemctl start libvirtd
sudo systemctl enable libvirtd

若不想每次開 vm 都要輸入密碼的話:

1
sudo usermod -aG libvirt $USER

取得 pci id

1
lspci -nn | grep NVIDIA

找到需要直通的 gpu,後面的 [] 裡面是等下需要用到的 pci id,VGA 跟 Audio 都需要用到,例如我的 01:00.0, 01:00.1,其 id 為 10de:2489, 10de:228b

grep 設定

1
sudo nano /etc/default/grub

在 GRUB_CMDLINE_LINUX="… 後面加入 intel_iommu=on iommu=pt vfio-pci.ids=...,... rd.driver.pre=vfio_pci (…,… 為 pci id)

儲存設定:

1
sudo grub2-mkconfig -o /boot/efi/EFI/fedora/grub.cfg

設定載入 vfio-pci 模組

1
sudo nano /etc/dracut.conf.d/10-vfio.conf

加入以下並儲存: add_drivers+=" vfio_pci vfio vfio_iommu_type1 vfio_virqfd "

1
sudo dracut --force /boot/initramfs-$(uname -r).img

重啟電腦

檢查是否設定成功

檢查 iommu 是否啟動

1
dmesg | grep -i -e DMAR -e IOMMU

看是否有 “IOMMU enabled”

檢查 vfio 是否啟用

1
dmesg | grep -i vfio

查看是否有出現需要的id

此外,可以透過以下指令檢查該 gpu 是否使用 vfio-pci (Kernel driver in use: vfio-pci)

1
lspci -nnk -d (id)

設定 vm

基本上在 virt-manager 上新增 gpu, audio 的 pci 就完成 passthrough 了

如果常用到一半藍屏的話

可以試試

1
sudo nano /etc/modprobe.d/kvm.conf

增加 options kvm ignore_msrs=1

個人遇到的問題

(個人推測)
由於我要直通的卡插在第一個 pcie 的槽,開機時會預設使用一下這張卡,然後再切另一張。

設定開機後重設 gpu

主要遇到問題是要直通的卡(pci 設備)需要重設,否則虛擬機(vm)開啟時會崩潰,然後就開不起來。

建立一個腳本,記得 chmod +x pcie_hot_reset.sh

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/bin/bash

dev=$1

if [ -z "$dev" ]; then
    echo "Error: no device specified"
    exit 1
fi

if [ ! -e "/sys/bus/pci/devices/$dev" ]; then
    dev="0000:$dev"
fi

if [ ! -e "/sys/bus/pci/devices/$dev" ]; then
    echo "Error: device $dev not found"
    exit 1
fi

echo "Removing $dev..."

echo 1 > "/sys/bus/pci/devices/$dev/remove"

echo "Rescanning bus..."

echo 1 > "/sys/bus/pci/rescan"

然後我要設定開機時自動使用該腳本

1
sudo nano /etc/systemd/system/gpu_reset@.service

內容: (ExecStart 自行修改)

1
2
3
4
5
6
7
8
9
[Unit]
Description=GPU reset at startup.

[Service]
Type=simple
ExecStart=/bin/bash /home/user/pcie_hot_reset.sh %i

[Install]
WantedBy=multi-user.target
1
2
sudo chmod 644 /etc/systemd/system/gpu_reset@.service
sudo systemctl enable gpu_reset@01:00.0.service gpu_reset@01:00.1.service 

設定 X11 預設顯示 GPU

我的 X11 會預設使用要直通的卡,導致當那張卡有接螢幕時,會連 Linux 登入畫面都無法顯示,所以我用以下設定預設顯示 GPU 為 gt710 那張

1
sudo nano /etc/X11/xorg.conf

加入

1
2
3
4
5
6
Section "Device"
    Identifier     "Device1"
    Driver         "nvidia"
    VendorName     "NVIDIA Corporation"
    BusID          "PCI:3:0:0"
EndSection

參考

> 跟灰貓借的網站 ouo
使用 Hugo 建立
主題 StackJimmy 設計