Skip to content

单显卡直通教程

Published: at 17:15

本文配置了单显卡下的显卡直通。由于只有一张显卡,因此 Linux 侧的 Display Manager 和虚拟机无法共存。而这就是单显卡直通的原理所在:在直通期间将显卡释放,通过 PCI 直通给虚拟机使用;在虚拟机不再使用显卡时,重新启动 Display Manager 以继续使用 Linux 桌面。

本文中的配置主要参考了 Single-GPU-Passthrough-for-Arch-Linux 的教程。

ToC

IOMMU

由于个人在配置这篇文章之前就已经开启了 IOMMU,所以本文也跳过这一步骤。在 Hooks 之前的步骤可以参考上文提及的教程。

Hooks

单显卡直通配置的核心,通过配置虚拟机启动和关闭的钩子,实现显卡的自动释放和回收。首先线获得脚本:

Terminal window
1
sudo wget 'https://raw.githubusercontent.com/PassthroughPOST/VFIO-Tools/master/libvirt_hooks/qemu' -O /etc/libvirt/hooks/qemu

创建目录:

Terminal window
1
sudo mkdir /etc/libvirt/hooks/qemu.d /etc/libvirt/hooks/qemu.d/win10 /etc/libvirt/hooks/qemu.d/win10/prepare /etc/libvirt/hooks/qemu.d/win10/prepare/begin /etc/libvirt/hooks/qemu.d/win10/release /etc/libvirt/hooks/qemu.d/win10/release/end

创建 /etc/libvirt/hooks/qemu.d/win10/prepare/begin/start.sh

1
#!/bin/bash
2
## Helpful to read output when debugging
3
set -x
4
5
# Stop display manager
6
systemctl stop display-manager.service
7
## Uncomment the following line if you use GDM
8
#killall gdm-x-session
9
10
# Unbind VTconsoles
11
echo 0 > /sys/class/vtconsole/vtcon0/bind
12
echo 0 > /sys/class/vtconsole/vtcon1/bind
13
14
# Unbind EFI-Framebuffer
15
echo efi-framebuffer.0 > /sys/bus/platform/drivers/efi-framebuffer/unbind
16
17
# Avoid a Race condition by waiting 2 seconds. This can be calibrated to be shorter or longer if required for your system
18
sleep 2
19
20
# Unload all Nvidia drivers
21
modprobe -r nvidia_drm
22
modprobe -r nvidia_modeset
23
modprobe -r nvidia_uvm
24
modprobe -r nvidia
25
26
## Load vfio
27
modprobe vfio
28
modprobe vfio_iommu_type1
29
modprobe vfio_pci

创建 /etc/libvirt/hooks/qemu.d/win10/release/end/stop.sh

1
#!/bin/bash
2
set -x
3
4
## Unload vfio
5
modprobe -r vfio_pci
6
modprobe -r vfio_iommu_type1
7
modprobe -r vfio
8
9
# Rebind VT consoles
10
echo 1 > /sys/class/vtconsole/vtcon0/bind
11
echo 1 > /sys/class/vtconsole/vtcon1/bind
12
13
nvidia-xconfig --query-gpu-info > /dev/null 2>&1
14
echo "efi-framebuffer.0" > /sys/bus/platform/drivers/efi-framebuffer/bind
15
16
modprobe nvidia_drm
17
modprobe nvidia_modeset
18
19
modprobe nvidia_uvm
20
modprobe nvidia
21
22
# Restart Display Manager
23
systemctl start display-manager.service

将所有脚本都设置为可执行:

Terminal window
1
sudo chmod +x /etc/libvirt/hooks/qemu
2
sudo chmod +x /etc/libvirt/hooks/qemu.d/win10/prepare/begin/start.sh
3
sudo chmod +x /etc/libvirt/hooks/qemu.d/win10/release/end/stop.sh

创建虚拟机

  1. 打开 virt-manager,在 编辑-Preferences 中找到 启用 XML 编辑 并打勾
  2. 新建虚拟机,选择本地安装,找到 ISO 并加载。 注意,虚拟机的名称必须为 win10
  3. 确定 Customize configuration before install 是勾选的,因为在启动之前我们需要进行一些设置
  4. 将固件设置为 OVMF_CODE
  5. 勾选 CPU 数-拓扑-手动设置 CPU 拓扑,根据实际情况设置
  6. 开始安装
  7. Windows 安装成功后,关闭虚拟机。然后重启 libvirt 以激活 Hook
Terminal window
1
sudo systemctl restart libvirtd.service

修改 VBIOS

网上很多的教程都需要这一步,但我实际测试下来,现在好像已经不需要这一步的操作了。

最后准备

  1. 删除 USB Redirector 1USB Redirector 2
  2. 删除 Sound ich9
  3. 删除 Channel spice
  4. 进入 概况 页,在 XML 中找到以下内容并删除
1
<graphics type="spice" autoport="yes">
2
<listen type="address"/>
3
<image compression="off"/>
4
</graphics>
1
<audio id="1" type="spice"/>
  1. 直通鼠标和键盘:在 添加硬件 - USB 主机设备 的详情页面中找到对应 USB 设备
  2. 直通显卡:在 添加硬件 - PCI 主机设备的详情页中找到显卡和音频设备并添加
  3. 网卡。因为我显示器上还有一张单独的网卡,所以我选择把它也直通进去

配置完成,试着启动一下虚拟机吧(