前言

为了提高虚拟机的性能,或是扩展其使用场景。有时候,我们需要让虚拟机直接访问到硬件资源。

开启 PCI Passthrough 需要硬件支持。

IOMMU

IOMMU Enable

查看当前主机是否支持

dmesg | grep -e DMAR -e IOMMU

如果没有输出,则表示不支持。

修改内核启动参数

修改 /etc/default/grub

GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on"
GRUB_CMDLINE_LINUX_DEFAULT="quiet amd_iommu=on"

更新 grub

Proxmox:  update-grub
OpenSUSE: grub2-mkconfig -o /etc/grub2-efi.cfg
CentOS:   grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg

重新启动主机

检查 grub 是否更新成功

cat /proc/cmdline | grep iommu

检查 IOMMU 是否开启

dmesg | grep "Virtualization Technology for Directed I/O"

dmesg | grep -e DMAR -e IOMMU | grep enable

PT Mode

Intel 与 AMD 芯片组均能够通过添加 "iommu=pt" 参数开启 PT 模式,以 Intel 为例:

按照如下修改 /etc/default/grub 并更新 grub

GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt"

PT 模式只为直通模式中使用的设备启用 IOMMU,这将防止 Linux 试图接触 (touching) 无法直通的设备。

Interrupt Remapping

要使用 PCI passthrough,Interrupt Remapping 是必须的。

Interrupt Remapping 能够工作在较新的设备上,你可以使用下面的命令查看当前的主机是否支持 Interrupt Remapping:

dmesg | grep 'remapping'

如果你看到了下面任何一行

"AMD-Vi: Interrupt remapping enabled"
"DMAR-IR: Enabled IRQ remapping in x2apic mode" ('x2apic' can be different on old CPUs, but should still work)

那么当前的主机是能够支持 Interrupt Remapping 的。

然而,如果当前的主机不支持 interrupt remapping,你可以使用如下命令开启 unsafe interrupt remapping:

echo "options vfio_iommu_type1 allow_unsafe_interrupts=1" > /etc/modprobe.d/iommu_unsafe_interrupts.conf

完成上述修改后,你需要更新 initramfs 并重新启动系统

update-initramfs -u -k all

另外,你也可以尝试配置 Interrupt Remapping 的内核引导参数

intremap={on,off,nosid,no_x2apic_optout}

验证 IOMMU 分组

find /sys/kernel/iommu_groups/ -type l

VFIO

Required Moudules

修改 /etc/modules,开启以下 Kernel Moudules

vfio
vfio_iommu_type1
vfio_pci
vfio_virqfd

为 PCI 设备开启 VFIO

以 Intel 核心显卡为例:

查询 PCI 设备的 ID

lspci -nn| grep 'Intel Corporation' | grep HD

00:02.0 VGA compatible controller [0300]: Intel Corporation HD Graphics 630 [8086:5912] (rev 04)
00:1f.3 Audio device [0403]: Intel Corporation 100 Series/C230 Series Chipset Family HD Audio Controller [8086:a170] (rev 31)

绑定为 VFIO 设备

修改 /etc/modprobe.d/vfio.conf

options vfio-pci ids=8086:5912,8086:a170 disable_vga=1

在物理机禁用 Intel 核心显卡和音频,创建并修改 /etc/modprobe.d/custom-blacklist.conf

blacklist snd_hda_intel
blacklist snd_hda_codec_hdmi
blacklist i915

完成上述修改后,你需要更新 initramfs 并重新启动系统

update-initramfs -u -k all

重新启动系统后,确认 Intel 核心显卡使用的 driver 是不是 vfio-pci

lspci -nnk| grep -C1 vfio

现在你可以使用 virt-manager 或 Proxmox 在虚拟机上分配 PCI 设备了。

其他的内核启动参数

这里列举可能会用到的部分内核启动参数

pcie_acs_override=downstream,multifunction
video=vesafb:off
video=efifb:off
video=simplefb:off
initcall_blacklist=sysfb_init
video=vesa:off
转载请注明出处。本博客所有内容均为作者个人工作经验的总结,请不要视作为 sop,受制于可能完全不同的使用场景,本博客的观点并不可靠,仅供参考。