Posted on 

浅显易懂的显卡(PCI)直通教程

Linux下nVidia驱动太烂?直接交给虚拟机!

翻译并修改自Mathiashueber的博客,目前仅支持Ubuntu 20.04与Pop! _OS 20.04。

图例

软件名 代码 路径 名人名言

前言

这是在Ubuntu 20.04上使用显卡直通的教程。我已经尽量减少步骤,并使其浅显易懂,让隔壁家老奶奶也听得懂。:-)

该教程的最终目标是在以XUbuntu20.04作为宿主机,Windows10 2004作为虚拟机的操作系统。主要会focus on游戏用途。

不幸的是,设置过程会相当复杂。它包括必须的基本设置以及一些可选(主要是性能)的设置。为了保持这篇文章的可读性,并且因为我的目标是只将虚拟机用于游戏,所以我尽量减少了用于延迟优化的可选部分。我已经在文章中加入了可选项的链接–我希望这有意义。🙂

Ubuntu 20.04 中影响PCI直通的重大变更
内核版本

从5.4版本的内核开始,vfio-pci 驱动不再是一个内核模块,而是内置在内核中。我们必须找到一种不同的方法,而不是像我在18.04指南中推荐的那样,使用initramfs-tools/modules配置文件

QEMU版本

Ubuntu 20.04搭载了QEMU 4.2版本。它引入了音频方面的修复。如果你想使用旧版本的虚拟机,你需要注意下。

引导器

这不是Ubuntu 20.04的”问题”,但至少对一个基于Ubuntu的流行发行版–Pop!_OS 20.04来说是如此。

从19.04版本开始,Pop!_OS 20.04不再使用grub作为引导器。反之,它使用了systemd。这意味着在Pop!_OS 20.04中触发内核命令的方式不同。

VFIO, PCI直通和IOMMU的介绍

虚拟功能I/O(或VFIO)允许虚拟机直接访问PCI硬件资源,如GPU。设置了GPU直通的虚拟机可以获得接近于裸机的性能,这使得在Windows虚拟机中运行游戏成为可能。

让我做再解释解释,以实现我”对初学者友好”的崇高理想。

PCI设备被组织在所谓的IOMMU组中。为了将一个设备传递给虚拟机,我们必须将同一IOMMU组的所有设备也传递给它。在一个完美的设想中,每个设备都应该有自己的IOMMU组 – 不幸的是,理想很丰满,现实很骨感

直通的设备被隔离,因此不再对主机系统可用。此外,同一时间内,IOMMU组中的所有设备将被隔离。

这意味着,当一个设备是直通设备的 “IOMMU组亲戚” 时,即使虚拟机不需要它,它也不能再在主机上使用。

捐赠原作者!

感谢MathiasHueber的原稿!如果觉得这篇文章有用,就请他喝杯coffee吧

要求

为了成功地学习本指南,你所使用的硬件必须支持虚拟化,并有适当分离的IOMMU组。

本文使用的硬件

  • AMD Ryzen7 1800x (CPU)
  • Asus Prime-x370 pro (主板)
  • 2x 16 GB DDR4-3200 running at 2400MHz (内存)
  • Nvidia GeForce 1050 GTX (宿主机 GPU; PCIE插槽 1)
  • Nvidia GeForce 1060 GTX (虚拟机 GPU; PCIE插槽 2)
  • 500 GB NVME SSD (虚拟机 硬盘; M.2)
  • 500 GB SSD (宿主机 硬盘; SATA)
  • 750W 电源

在选配硬件时,我特意避免了打内核补丁的需要。因此,上述主板和CPU的组合不需要ACS覆盖补丁。

若你的主板没有适当的IOMMU分组,你可以尝试给内核打补丁来解决这个问题,或者自己修补内核

BIOS设置

在BIOS中启用以下选项:

  • Advanced \ CPU config - SVM Module -> enable
  • Advanced \ AMD CBS - IOMMU -> enable
注意!

ASUS Prime x370/x470/x570 pro主板搭配锐龙3000系列且BIOS版本为v.4602 – 5220时,PCI直通会报错!

错误:“Unknown PCI header type ‘127’“.

4406 (2019/03/11) 前的版本(包括该版)没有该问题;

5406 (2019/11/25) 后的版本(包括该版)没有该问题。

我使用的版本:4207 (8th Dec 2018)

宿主机系统设置

我安装了Xubuntu 20.04

Ubuntu 20.04自带了适合VFIO的5.4内核 - 用 uname -r 检查。

注意!

从4.15起,内核支持了锐龙的直通设置。

除了内核5.1,5.2,5.3及其所有的小版本。

在继续之前,请确保你的内核在VFIO环境下能很好地运行。

安装软件

安装QEMULibvirtvirt-manager

设置PCI直通

我们会把这些设备直通给虚拟机:

  • GPUx1: Nvidia GeForce 1060 GTX
  • USB端口x1
  • SSDx1: 500 GB NVME M.2

开启IOMMU

该步骤在Intel CPU与AMD CPU中有所差异:

GRUB: AMD CPU的设置

编辑GRUB设置:

GRUB_CMDLINE_LINUX_DEFAULT修改为:

更新GRUB文件:

重启系统。

GRUB: Intel CPU的设置

编辑GRUB设置:

GRUB_CMDLINE_LINUX_DEFAULT修改为:

更新GRUB文件:

重启系统。

systemd-boot: AMD CPU的设置

编辑systemd-boot设置:

重启系统。

systemd-boot: Intel CPU的设置

编辑systemd-boot设置:

重启系统。

重启后,验证IOMMU是否有开启:

dmesg输出
1
2
3
4
5
6
[ 0.792691] AMD-Vi: IOMMU performance counters supported 
[ 0.794428] AMD-Vi: Found IOMMU at 0000:00:00.2 cap 0x40
[ 0.794429] AMD-Vi: Extended features (0xf77ef22294ada):
[ 0.794434] AMD-Vi: Interrupt remapping enabled
[ 0.794436] AMD-Vi: virtual APIC enabled
[ 0.794688] AMD-Vi: Lazy IO/TLB flushing enabled

辨认虚拟机GPU

注意!

该步骤执行完毕后,宿主机将无法识别直通到虚拟机的GPU。现在,你必须要为给宿主机准备第二块GPU!

在这一章中,我们要把设备直通给虚拟机之前,识别和隔离这些设备。我们将会在合适的IOMMU组中寻找一个GPU和一个USB控制器。这意味着,要么两个设备都有自己的组,要么它们共享一个组。

我们的计划是将vfio-pci驱动应用于将要直通的GPU,然后再由普通显卡驱动来控制它。

这是该过程中最关键的一步。如果你的主板不能正确地进行IOMMU分组,你仍然可以尝ACS覆盖补丁来修补你的内核。

你可以使用bash脚本,以确定设备和它们的分组:

1
2
3
4
5
6
7
8
#!/bin/bash
# change to 999 if needed
shopt -s nullglob
for d in /sys/kernel/iommu_groups/{0..999}/devices/*; do
n=${d#*/iommu_groups/*}; n=${n%%/*}
printf 'IOMMU Group %s ' "$n"
lspci -nns "${d##*/}"
done;

来源:Arch Wiki+前999个iommu组的分类

脚本输出
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
IOMMU Group 0 00:01.0 Host bridge [0600]: Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-1fh) PCIe Dummy Host Bridge [1022:1452]
IOMMU Group 1 00:01.1 PCI bridge [0604]: Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) PCIe GPP Bridge [1022:1453]
IOMMU Group 2 00:01.3 PCI bridge [0604]: Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) PCIe GPP Bridge [1022:1453]
IOMMU Group 3 00:02.0 Host bridge [0600]: Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-1fh) PCIe Dummy Host Bridge [1022:1452]
IOMMU Group 4 00:03.0 Host bridge [0600]: Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-1fh) PCIe Dummy Host Bridge [1022:1452]
IOMMU Group 5 00:03.1 PCI bridge [0604]: Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) PCIe GPP Bridge [1022:1453]
IOMMU Group 6 00:03.2 PCI bridge [0604]: Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) PCIe GPP Bridge [1022:1453]
IOMMU Group 7 00:04.0 Host bridge [0600]: Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-1fh) PCIe Dummy Host Bridge [1022:1452]
IOMMU Group 8 00:07.0 Host bridge [0600]: Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-1fh) PCIe Dummy Host Bridge [1022:1452]
IOMMU Group 9 00:07.1 PCI bridge [0604]: Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) Internal PCIe GPP Bridge 0 to Bus B [1022:1454]
IOMMU Group 10 00:08.0 Host bridge [0600]: Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-1fh) PCIe Dummy Host Bridge [1022:1452]
IOMMU Group 11 00:08.1 PCI bridge [0604]: Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) Internal PCIe GPP Bridge 0 to Bus B [1022:1454]
IOMMU Group 12 00:14.0 SMBus [0c05]: Advanced Micro Devices, Inc. [AMD] FCH SMBus Controller [1022:790b] (rev 59)
IOMMU Group 12 00:14.3 ISA bridge [0601]: Advanced Micro Devices, Inc. [AMD] FCH LPC Bridge [1022:790e] (rev 51)
IOMMU Group 13 00:18.0 Host bridge [0600]: Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) Data Fabric: Device 18h; Function 0 [1022:1460]
IOMMU Group 13 00:18.1 Host bridge [0600]: Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) Data Fabric: Device 18h; Function 1 [1022:1461]
IOMMU Group 13 00:18.2 Host bridge [0600]: Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) Data Fabric: Device 18h; Function 2 [1022:1462]
IOMMU Group 13 00:18.3 Host bridge [0600]: Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) Data Fabric: Device 18h; Function 3 [1022:1463]
IOMMU Group 13 00:18.4 Host bridge [0600]: Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) Data Fabric: Device 18h; Function 4 [1022:1464]
IOMMU Group 13 00:18.5 Host bridge [0600]: Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) Data Fabric: Device 18h; Function 5 [1022:1465]
IOMMU Group 13 00:18.6 Host bridge [0600]: Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) Data Fabric: Device 18h; Function 6 [1022:1466]
IOMMU Group 13 00:18.7 Host bridge [0600]: Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) Data Fabric: Device 18h; Function 7 [1022:1467]
IOMMU Group 14 01:00.0 Non-Volatile memory controller [0108]: Micron/Crucial Technology P1 NVMe PCIe SSD [c0a9:2263] (rev 03)
IOMMU Group 15 02:00.0 USB controller [0c03]: Advanced Micro Devices, Inc. [AMD] X370 Series Chipset USB 3.1 xHCI Controller [1022:43b9] (rev 02)
IOMMU Group 15 02:00.1 SATA controller [0106]: Advanced Micro Devices, Inc. [AMD] X370 Series Chipset SATA Controller [1022:43b5] (rev 02)
IOMMU Group 15 02:00.2 PCI bridge [0604]: Advanced Micro Devices, Inc. [AMD] X370 Series Chipset PCIe Upstream Port [1022:43b0] (rev 02)
IOMMU Group 15 03:00.0 PCI bridge [0604]: Advanced Micro Devices, Inc. [AMD] 300 Series Chipset PCIe Port [1022:43b4] (rev 02)
IOMMU Group 15 03:02.0 PCI bridge [0604]: Advanced Micro Devices, Inc. [AMD] 300 Series Chipset PCIe Port [1022:43b4] (rev 02)
IOMMU Group 15 03:03.0 PCI bridge [0604]: Advanced Micro Devices, Inc. [AMD] 300 Series Chipset PCIe Port [1022:43b4] (rev 02)
IOMMU Group 15 03:04.0 PCI bridge [0604]: Advanced Micro Devices, Inc. [AMD] 300 Series Chipset PCIe Port [1022:43b4] (rev 02)
IOMMU Group 15 03:06.0 PCI bridge [0604]: Advanced Micro Devices, Inc. [AMD] 300 Series Chipset PCIe Port [1022:43b4] (rev 02)
IOMMU Group 15 03:07.0 PCI bridge [0604]: Advanced Micro Devices, Inc. [AMD] 300 Series Chipset PCIe Port [1022:43b4] (rev 02)
IOMMU Group 15 07:00.0 USB controller [0c03]: ASMedia Technology Inc. ASM1143 USB 3.1 Host Controller [1b21:1343]
IOMMU Group 15 08:00.0 Ethernet controller [0200]: Intel Corporation I211 Gigabit Network Connection [8086:1539] (rev 03)
IOMMU Group 15 09:00.0 PCI bridge [0604]: ASMedia Technology Inc. ASM1083/1085 PCIe to PCI Bridge [1b21:1080] (rev 04)
IOMMU Group 15 0a:04.0 Multimedia audio controller [0401]: C-Media Electronics Inc CMI8788 [Oxygen HD Audio] [13f6:8788]
IOMMU Group 16 0b:00.0 VGA compatible controller [0300]: NVIDIA Corporation GP107 [GeForce GTX 1050 Ti] [10de:1c82] (rev a1)
IOMMU Group 16 0b:00.1 Audio device [0403]: NVIDIA Corporation GP107GL High Definition Audio Controller [10de:0fb9] (rev a1)
IOMMU Group 17 0c:00.0 VGA compatible controller [0300]: NVIDIA Corporation GP104 [GeForce GTX 1060 6GB] [10de:1b83] (rev a1)
IOMMU Group 17 0c:00.1 Audio device [0403]: NVIDIA Corporation GP104 High Definition Audio Controller [10de:10f0] (rev a1)
IOMMU Group 18 0d:00.0 Non-Essential Instrumentation [1300]: Advanced Micro Devices, Inc. [AMD] Zeppelin/Raven/Raven2 PCIe Dummy Function [1022:145a]
IOMMU Group 19 0d:00.2 Encryption controller [1080]: Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) Platform Security Processor [1022:1456]
IOMMU Group 20 0d:00.3 USB controller [0c03]: Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) USB 3.0 Host Controller [1022:145c]
IOMMU Group 21 0e:00.0 Non-Essential Instrumentation [1300]: Advanced Micro Devices, Inc. [AMD] Zeppelin/Renoir PCIe Dummy Function [1022:1455]
IOMMU Group 22 0e:00.2 SATA controller [0106]: Advanced Micro Devices, Inc. [AMD] FCH SATA Controller [AHCI mode] [1022:7901] (rev 51)
IOMMU Group 23 0e:00.3 Audio device [0403]: Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) HD Audio Controller [1022:1457]

脚本输出的分析方法:

图一:脚本输出的分析方法
图一:脚本输出的分析方法

有趣的部分在于PCI bus id(图一中标红的部分)以及设备标识码(图一中标橙的部分)。

这些是我选择的分组方案:

分组方案
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
NVME M.2 
========
IOMMU group 14
01:00.0 Non-Volatile memory controller [0108]: Micron/Crucial Technology P1 NVMe PCIe SSD [c0a9:2263] (rev 03)
Driver: nvme

Guest GPU - GTX1060
=================
IOMMU group 17
0c:00.0 VGA compatible controller [0300]: NVIDIA Corporation GP104 [GeForce GTX 1060 6GB] [10de:1b83] (rev a1)
Driver: nvidia
0c:00.1 Audio device [0403]: NVIDIA Corporation GP104 High Definition Audio Controller [10de:10f0] (rev a1)
Driver: snd_hda_intel

USB host
=======
IOMMU group 20
0d:00.3 USB controller [0c03]: Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) USB 3.0 Host Controller [1022:145c]
Driver: xhci_hcd

$

图二:ASUS Prime x370-pro上隔离出的IOMMU组
图二:ASUS Prime x370-pro上隔离出的IOMMU组