作者AKSN74 (AKS-74n)
看板Linux
标题[分享] GPU Passthrough设定及一些眉角分享
时间Sun May 30 14:12:01 2021
虽然说自己很早之前就有接触这块,KVM目前搞GPU Passthrough还是透过VFIO来做
不过从最後一次玩到现在也已经有几年的时间,就没什麽在追了
直到最近NVIDIA在3月底的时候宣布开放GeForce显卡也可以在KVM上做Passthrough後
就又燃起了一些兴趣,在经过一些搜索整理後,贴一个给各位分享
请注意: 1. 文章很长
2. 里面会有一些截图以及贴在pastebin的一些指令或参数说明的网址
https://i.imgur.com/Sxcl2MQ.png
https://i.imgur.com/U9Lww9C.png
事前准备:硬体与BIOS
先列一下我的配备
---------------------------------------------------
CPU: AMD Ryzen 5 5600X
MB: ASUS ROG STRIX B550-E
RAM: Patriot Viper Steel DDR4-3200 16GB*2
Host GPU: AMD Radeon VII or AMD Radeon RX 6900XT
Guest GPU: NVIDIA GeForce RTX 3090
SSD1: Seagate 火梭鱼 1TB M.2
SSD2: Plextor M9PeGN
HDD: WD 1TB 黑标
---------------------------------------------------
Host OS: Fedora 34 Workstation
Guest OS: Windows 10 21H1
---------------------------------------------------
之所以用Fedora的原因是Fedora在Kernel还有一些KVM套件上都很新
但最主要的原因是Ubuntu 20.04的Mesa版本还没有办法支援Big Navi GPU
以及很早之前做的时候也是使用Fedora才会选择继续使用
硬体方面,有两张GPU以上(包含内显)、且CPU还有BIOS都支援IOMMU的话就可以尝试
AMD的CPU基本上在IOMMU这部分几乎是支援的,Intel就要看
而且就算CPU支援,板厂还不一定有BIOS选项可以开
虽然说这部分有所谓的ACS Override这个方法可以做,但那是下下策
以我目前这个平台为例,主要确定IOMMU是启用的就行了
但需要注意Resizable BAR(就是AMD自称的SAM技术)请务必关闭
目前这个已经确定会影响到Passthrough的运作
另外,设定与使用VM的过程中可能会需要另外接讯号线或是键鼠
因此建议使用有多个输入切换的萤幕,并且另外准备一组键盘或滑鼠
事前准备:Fedora 34设定
装完系统後,首先必须先开启IOMMU功能。请编辑/etc/default/grub档案
在GRUB_CMDLINE_LINUX内加入:
amd_iommu=on
iommu=pt
(P.S 如果是Intel就改成intel_iommu即可)
(P.S.S 这两个选项在Kernel 5.8之後的AMD平台上不用加也会默认启用IOMMU,至少在
Ubuntu 20.04还有Fedora 34上面是如此,不过我们也有对IOMMU运作模式做设定
因此建议还是加一下)
--
另外Windows 10会有因KVM的msrs纠错导致BSOD的问题,因此也将忽略msrs的选项也加入
kvm.ignore_msrs=1
kvm.report_ignored_msrs=0
加入之後会变下图这样:
https://i.imgur.com/8iDiBAb.png
完毕之後产生新的GRUB启动设定档,在EFI模式下的Fedora 34是使用以下指令:
# grub2-mkconfig -o /boot/grub2/grub.cfg
(* 33以前的请改路径成/boot/efi/EFI/fedora/grub.cfg)
--
重开机後,使用以下的bash script检查要挂载的GPU是否在独立的IOMMU群组中
https://i.imgur.com/4NrmGM5.png
执行script会出现像下图图片的样子
https://i.imgur.com/YqloBRA.png
以这张图为例,要挂的RTX3090在IOMMU群组ID是17,所谓独立的意思是
在17这个群组内除了RTX3090还有它的HDMI输出装置外,
没有其他的PCI-E装置存在
如果有存在其他的装置,只有两个方法可以处理:
1. 将其他装置连同GPU一起被VFIO掌控,但这些装置在Linux系统内将不会运作
2. 使用ACS Override Patch
--
确定GPU处在独立的IOMMU群组後就可以进行下一步,把VFIO模组给带起来
首先到/etc/dracut.conf.d/内,建立一个新的conf档案
然後在档案内写入以下资讯
add_drivers+=" vfio vfio_pci vfio_iommu_type1 vfio_virqfd "
(注意包含空格)
储存後使用dracut -fv产生新的initramfs档案
--
接着再编辑/etc/default/grub档案,在同一个位置的後面再新增几个参数:
rd.driver.pre=vfio-pci
vfio-pci.ids=<GPU的装置ID>,<GPU HDMI的装置ID>
video=efifb:off (选择性)
两个的装置ID都可以透过上面的IOMMU群组查询指令或者是使用lspci -n去找到
以RTX3090为例,其GPU本身还有HDMI的装置ID写进grub内会是:
vfio-pci.ids=10de:2204,10de:1aef
(P.S vfio-pci.ids这个在比较早的作法是可以直接加入进/etc/modprobe.d内就行了
但VFIO在Kernel 5.8後开始就已被整合进核心套件中而不再是单纯的Module
因此使用modprobe.d的方式在部分Linux Distro上会无效)
另外video=efifb:off这个参数
这个是如果要挂的卡是插在主机板的第一条PCI-E上,才必须要加的参数
加完之後会像下图这样:
https://i.imgur.com/YZjY0lw.png
重开机後:使用lspci -k指令检查GPU是否已被vfio-pci使用,成功的话如下图:
https://i.imgur.com/P3nylrL.png
这样前置作业就算完成。
设定网路、安装套件并建立VM
首先先建立给VM用的bridge,我是直接使用NetworkManager的指令去建立的
可以Google一下怎麽建立
之後安装VM管理套件
$ sudo dnf install @virtualization
另外还需要安装OVMF,这个是让VM可以使用UEFI环境的韧体套件
由於目前新的显卡大多都已经是UEFI韧体,因此VM也必须建立在UEFI模式下
$ sudo dnf install edk2-ovmf
由於Fedora的virt-manager没办法透过登出再登入的方式直接取得权限,因此需要重开机
--
准备好Windows 10的ISO以及VirtIO driver的ISO,照一般建立VM的程序下去安装
在建立VM的时候留意以下几点就好(也可以装好Win10之後再做):
1. 安装的时候机器类型选择Q35,并且将韧体改为UEFI类型的韧体 (不带secboot的)
2. CPU model请改为host-passthrough,并且设定好CPU拓朴(尤其是Socket的部分)
3. 网路model请改成virtio,效能比较好
4. 虚拟磁碟的部分请先使用SATA就好,原因後面会说
5. 别忘了也要把VirtIO driver的ISO另外建立一个虚拟光碟机挂载起来
--
安装完Win10并手动上好网路驱动後,先下载好NVIDIA的驱动在系统内,然後关机
关机後把要给VM用的显卡及其HDMI音源给挂进去
https://i.imgur.com/YGMJprZ.png
--
接下来有两种方式可以选择
1. 直接开机,并且用virt-manager的视窗装驱动
2. 把虚拟显卡还有Spice显示器给拿掉,并把键盘滑鼠的USB给挂进去
然後挂载的卡接上萤幕 (USB挂载方式如图)
https://i.imgur.com/VnQLcgM.png
我个人会比较推第二种,原因是就过去经验,N卡驱动对於QXL这类的虚拟显卡不太友善
为了不要在安装或者日後使用过程产生side-effect,所以我会习惯接萤幕来装
--
装驱动的过程与结束就是见真章的时候了
NV在3月底公布自R465版本的驱动开始支援KVM的GPU Passthrough
因此从这版本之後就不需再加一些额外的VM参数来绕过驱动的检查机制
基本上不会再有装完驱动出现Code 43的问题存在,有的话较大的可能是硬体或KVM问题
但如果是挂A卡的话就需要留意了,A卡部分型号会有Code 43或者是没办法reset的问题
目前所知道的是旧的Polaris系列多多少少都有这问题存在,其他的还没有测试过
後续的一些调校
主要是针对VM设定还有CPU做一些优化上的调整,包括了模拟Hyper-V、CPU核心绑定
以及虚拟平台上的一些设定参考
这段牵涉到一些XML档案上的修改,不过新的virt-manager有支援直接编辑的功能了
因此不再需要透过virsh edit去做修改
--
首先在features的部分,目前国外不少都是使用以下的参数设定,照抄即可
https://i.imgur.com/KiPWzKv.png
--
接着如果你希望一些CPU核心能够被VM完全独占的话,可以设定一下CPU绑定
https://i.imgur.com/F03inIY.png
这边需要注意的是每一个实体核心的编号还有核心架构
通常在有开HT的情况下,每一个线程的编号是根据每一个核心的第一个线程下去排
比如在双核四线上来说,它的编号会是:
Core #0 thread #0 -> thread #0
Core #1 thread #0 -> thread #1
Core #0 thread #1 -> thread #2
Core #1 thread #1 -> thread #3
也就是说,假设我要让其中一核的线程都给VM使用,那我对应的设定会是:
vCore #0 <- thread #1
vCore #1 <- thread #3
这样才是正确的,如果直接照实体核心线程的编号下去排,就会变成跨核心在跑
这会导致VM的效能不好
同时,在分配核心上也需要考虑到跨CCX甚至跨CCD的问题 (Ryzen上面容易遇到)
可以在linux上安装一款名为lstopo的工具来看实体CPU Topology状况
最後还需要到CPU的区块,将其中一个参数加入,以套用CPU绑定的设定
https://i.imgur.com/DRLz74U.png
--
clock的部分也要做修改,除了增加效能外
同时也能够防止Windows VM的时间在开机时与Host不同步的问题
https://i.imgur.com/AJcyGmE.png
额外套件或设定
目前GPU Passthrough若要拿来打游戏的话,都会准备另一台萤幕或键鼠
或者是用多输入的萤幕然後切换讯号源,或者直接挂Host端的键鼠
不过如果不想这麽麻烦的话,现在也有一个开源软体叫looking-glass
https://looking-glass.io/
简单来说,这套软体是使用IVSHMEM配合Windows的DXGI去做影像撷取、复制
并且把复制出来的影像资料再透过Host端的client给渲染出来
另外输入的部分则是使用Spice当作输入来源
算是可以做到不用另外搬萤幕也不用另外挂键鼠进去的一个方案
安装方式官网上面的wiki专区也有写,我个人觉得算是写得很完整
不过要使用这套软体的话需要注意几件事:
1. 只有影像,声音的部分要另外搞
2. 此软体建议使用EGL而非OpenGL,如果是用AMD显卡当作Host GPU的话
需要注意amdgpu-pro的Mesa驱动不支援EGL,建议使用Kernel自带的amdgpu驱动
3. 由於牵涉到影像传输,因此使用这套软体玩游戏会有部分效能损失
效能损失程度与解析度、画面变化、还有萤幕更新率有关
4. 用这套就我自己测试,还是要让Guest GPU接线,只不过可以用dummy代替
--
声音的部分则可以用Scream代替,并且用网路传输的方式将声音从Guest传至Host
https://github.com/duncanthrax/scream
具体的安装与用法可以直接参照github上的说明
或者是透过QEMU用一套Audio Passthrough也是可以
不过Fedora从33後改用pipewire作为音源管理介面後
我还在找有没有透过pipewire来实作的方式
--
另外,如果希望能够在VM内使用完整的USB功能
建议将Host端的其中一组USB控制器也挂进去VM内使用
因为KVM自带的libusb passthrough并不是所有接USB的装置都可以使用(比如iPhone)
而400跟500系列的USB 3.1 G2是另外独立出来的控制器
可以考虑将USB 3.1挂进去VM内使用
目前遇到的问题
1. 前面提到的虚拟磁碟为何要选用SATA的原因
这个问题说真的我不太确定是QEMU、Guest端的driver、还是Kernel的问题
简单来说,我目前只要用virtio-blk或者是virtio-scsi
进系统後用一段时间就会BSOD,Error讯息是VIDEO_DXGIKRNL_FATAL_ERROR
做了很多测试,包括换Kernel、换NV driver等等都无解
但用SATA就一点事情都没有,後来也发现用SATA的磁碟效能也跟一般差不多
问了不少群组上的老外他们也是一点头绪都没有
所以就先用SATA了
--
2. 开一些类似监控的软体偶而会触发自动重开
像是GPU-Z有时开了会直接让VM重开机,八成是在侦测PCI-E的时候出问题
另外GPU-Z就算开起来了,在PCI-E资讯那边也不是显示正确的资讯
我在猜是否有可能是AMD在KVM上面还是有一点问题在
大约是这样,目前在这方面还是有不少东西需要去探讨与厘清,毕竟这水还满深的
另外我接触到国外有在使用的,不少是使用Archlinux,也有使用像Manjaro或是Pop!_OS
也有跟我一样是使用Fedora的,Ubuntu反而还比较少一点
如果各位硬体条件符合的话多少可以尝试看看
--
https://i.imgur.com/paUBacY.png
https://i.imgur.com/vsJ0Suy.png
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 114.46.94.187 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/Linux/M.1622355127.A.128.html
※ 编辑: AKSN74 (114.46.94.187 台湾), 05/30/2021 14:12:50
※ 编辑: AKSN74 (114.46.94.187 台湾), 05/30/2021 14:21:31
1F:推 anderwei: 感谢分享,最近也有打算搞一个kvm windows配gpu passth 05/30 16:43
2F:→ anderwei: rough,只是因为是开在无萤幕的伺服器上,不知道到时候 05/30 16:43
3F:→ anderwei: 会不会遇到一堆坑XD 05/30 16:43
4F:推 AreLies: 推 05/30 16:59
5F:推 HMKRL: 一楼搞无萤幕的可能需要加一些参数把efifb关掉抢回GPU 05/30 19:55
6F:→ HMKRL: 我之前用PVE这样搞还没加的时候一pass就会开始闪雪花 然後 05/30 19:56
7F:→ HMKRL: 直接kernel panic整个连hypervisor一起死掉 05/30 19:56
8F:推 tennyleaz: 推 05/31 13:22
9F:→ tennyleaz: 我之前也在Proxmox VE上面弄好了 05/31 13:22
10F:→ tennyleaz: GPU Passthrough给Windows 10 05/31 13:22
11F:→ tennyleaz: 跑了3DMark感觉还ok 05/31 13:23
12F:推 a58524andy: 推 06/01 08:51
13F:→ zwin: 推 06/04 01:06
14F:→ brli7848: 虚拟机的windows可以用原本的随机版序号启用吗? 06/10 16:35
不行,Machine ID完全不同
除非是彩盒版
※ 编辑: AKSN74 (111.249.101.66 台湾), 06/10/2021 20:42:58