kvm+qemu显卡直通
版权声明:转载请标明来源 侵权必究
1. 基础知识
qemu 仿真软件
kvm linux虚拟化模块
qemu-kvm 是qemu和kvm结合的库(这个不确定 看软件名猜的)
libvirt 这个是virt-manager的库(这个也是猜的)
virt-manager 是一个python写的虚拟机管理软件
我们用来直通的驱动是 vfio(Virtual Function IO) 驱动。
以下操作基于ubuntu系统。因为我是macbook用的是改版内核。但是大同小异。
我的显卡是 AMD的。
对了 因为Apple T2固件。我直通并没有成功。但也到了最后一步。如果介意可以直接关掉啦。
2.检查vfio是否运行
检查这个有几种办法可以参考(只要任何一项内容 说明vfio是启用的可以直接跳过步骤3)
- lsmod | grep -i vfio (这个是vfio模块化)
- cat /libs/modules/$(uname -r)/modules.builtin | grep -i vfio (这个是linux内核编译的模块 ubuntu20.04 vfio内核自带了)
- dmesg | grep -i vfio
3.开启vfio
nano /etc/modules 添加下面内容
softdep snd_hda_intel pre:vfio vfio_pci
softdep amdgpu pre:vfio vfio_pci #这个是一个排序可以让vfio驱动优先加载
vfio
vfio_iommu_type1
vfio_virqfd
4.查看pci设备
lspci -nnk
如上图 我的显卡是AMD Radeon RX 460 因为直通要把显卡整个设备直通过去 所以音频也需要记录他们的PCI ID
1002:67ef
1002:aae0
这里需要注意的是整个设备它是按组分的。iommuamd.sh脚本可以检查它是属于哪个组。当然前提是你必须开启IOMMU。
5.开启IOMMU
nano /etc/default/grub 找到 GRUB_CMDLINE_LINUX_DEFAULT 添加以下内容
intel_iommu=on (如果你cpu是amd的 则需要改成 amd_iommu = on) iommu=pt pcie_aspm=off vfio_iommu_type1.allow_unsafe_interrupts=1 vfio_pci.disable_vga=1 vfio_pci.disable_idle_d3=1 kvm.ignore_msrs=1 vfio-pci.ids=1002:67ef, 1002:aae0(这块要填写你自己的pci设备ID)
保存后运行下面命令 更新grub
update-grub
6.查看IOMMU分组
可以看到我的显卡在 group 1组。那么如果要直通显卡 这个组里的设备都要直通给虚拟机。显然是不可能的。 或者 给显卡换个插槽。这个更不可能。 我们只能使用ACS补丁来软分组。使我们的显卡为单独一组。 至于这个现象为什么。因为显卡在CPU的 PCI-E插槽里。显卡插的位置有关系。
7.解决IOMMU分组问题 安装linux zen-kernel
zen-kernel(https://github.com/zen-kernel/zen-kernel/wiki/FAQ)
- 因为我是ubuntu需要安装Liquorix,其他系统大同小异 按教程安装就可以了,安装好后重启,选择对应内核
- nano /etc/default/grub 在 GRUB_CMDLINE_LINUX_DEFAULT 最后加入 pcie_acs_overrid=downstream 保存 并运行update-grub 重启
- 重启后运行 iommuamd.sh 再看
显卡-声卡驱动问题 (如果存在的话)
如上图我们可以看到 VGA驱动已经是 vfio-pci 而Audio声卡驱动还不是。 直通给虚拟机。 它们的驱动必须都是 vfio-pci 解决办法就是将snd_hda_intel加入黑名单。
nano /etc/modprobe.d/blacklist.conf 添加 blacklist snd_hda_intel 保存退出重启
就可以看到正常了
8.开始配置我们的虚拟机
- sudo apt install qemu-kvm qemu-utils libvirt-daemon-system libvirt-clients bridge-utils virt-manager ovmf
- sudo usermod -aG libvirt $USER
- sudo systemctl restart libvirtd.service
如果打开显示 Not Connection 建议重启一下 - 建立虚拟机 可以参考视频 xxxx
- 相关错误
- 如果遇到了 BarX 错误 这可能是因为PCI-E造成的 那么我们需要再运行虚拟机之前输入以下命令 或者 直接将下面命令加入 libvirt hook shell 里。virt_startup.sh 里。即可。
echo 1 > /sys/bus/pci/devices/0000:01:00.0/remove
echo 1 > /sys/bus/pci/rescan
- 如果遇到了 BarX 错误 这可能是因为PCI-E造成的 那么我们需要再运行虚拟机之前输入以下命令 或者 直接将下面命令加入 libvirt hook shell 里。virt_startup.sh 里。即可。
9.相关日志位置
xxxx.log in /var/log/libvirt/qemu (虚拟机日志 虽然启动 但没正常运行 查看 xxx为你虚拟机名字)
custom_hooks.log in/var/log/libvirt (钩子没按预期运行 查看)
xlibvirtd.log in /var/log/libvirt/
journalctl 或者 dmesg (一般发生虚拟机无法启动 查看)