kvm+qemu显卡直通


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)

  1. lsmod | grep -i vfio (这个是vfio模块化)
  2. cat /libs/modules/$(uname -r)/modules.builtin | grep -i vfio (这个是linux内核编译的模块 ubuntu20.04 vfio内核自带了)
  3. 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)

  1. 因为我是ubuntu需要安装Liquorix,其他系统大同小异 按教程安装就可以了,安装好后重启,选择对应内核
  2. nano /etc/default/grub 在 GRUB_CMDLINE_LINUX_DEFAULT 最后加入 pcie_acs_overrid=downstream 保存 并运行update-grub 重启
  3. 重启后运行 iommuamd.sh 再看

显卡-声卡驱动问题 (如果存在的话)

? 如上图我们可以看到 VGA驱动已经是 vfio-pci 而Audio声卡驱动还不是。 直通给虚拟机。 它们的驱动必须都是 vfio-pci 解决办法就是将snd_hda_intel加入黑名单。
nano /etc/modprobe.d/blacklist.conf 添加 blacklist snd_hda_intel 保存退出重启
就可以看到正常了

8.开始配置我们的虚拟机

  1. sudo apt install qemu-kvm qemu-utils libvirt-daemon-system libvirt-clients bridge-utils virt-manager ovmf

  2. sudo usermod -aG libvirt $USER

  3. sudo systemctl restart libvirtd.service
    如果打开显示 Not Connection 建议重启一下

  4. 建立虚拟机 可以参考视频
    https://www.bilibili.com/video/BV1by4y1s7bf?spm_id_from=333.1007.top_right_bar_window_history.content.click 如果失效了 可以用下面的网盘
    https://www.aliyundrive.com/s/SzW7tKdyHhD 提取码: fg83

  5. 相关错误

    1. 如果遇到了 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

9.相关日志位置

xxxx.log in /var/log/libvirt/qemu (虚拟机日志 虽然启动 但没正常运行 查看 xxx为你虚拟机名字)
custom_hooks.log in/var/log/libvirt (钩子没按预期运行 查看)
xlibvirtd.log in /var/log/libvirt/
journalctl 或者 dmesg (一般发生虚拟机无法启动 查看)

参考资料:

https://mathiashueber.com/pci-passthrough-ubuntu-2004-virtual-machine/
https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF#Setting_up_an_OVMF-based_guest_VM
https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF_(简体中文)#如果客户机所用显卡插在_CPU_提供的_PCI-E_插槽中
https://stackoverflow.com/questions/66491436/modprobe-vfio-pci-not-working-inside-vm-what-do-i-do-wrong
https://forum.level1techs.com/t/ubuntu-18-04-vfio-pcie-passthrough/127011
https://forum.level1techs.com/t/ubuntu-17-04-vfio-pcie-passthrough-kernel-update-4-14-rc1/119639
https://developer.ibm.com/tutorials/l-pci-passthrough/
https://github.com/pavolelsig/passthrough_helper_ubuntu/blob/master/tail.sh
https://liquorix.net/
https://passthroughpo.st/explaining-csm-efifboff-setting-boot-gpu-manually/
https://blog.csdn.net/alex_mianmian/article/details/118678510
https://www.v2ex.com/t/602942
https://ryan4yin.space/posts/qemu-kvm-usage/
https://www.codeplayer.org/Blog/双显卡笔记本独显直通.html