我们使用QEMU和Intel GVT-g部署具有虚拟视频卡转发功能的Windows虚拟机

如何使Intel GVT-g工作


大家好! 英特尔为这个永恒的问题提供了一个极好的解决方案:“我有一台笔记本电脑在Linux上,我需要通过硬件加速来运行Windows,但是我没有一台笨重的笔记本电脑带有两个GPU和液冷。” 他们使用他们的GPU或其他东西的架构,设法做到了这一点,以便您可以将集成的Intel GPU拆分为两个或更多GPU。


不幸的是,这远非简单...文档有些过时了,有些事情由于没有明显的原因而无法解释。 因此,在本文中,我将告诉您如何使用凉爽的virtio和Intel GVT-g快速驱动程序配置硬件加速的Windows虚拟机。


为此,您需要或多或少的现代化GPU( 译者注根据官方文档 ,GVT-g支持从第五代Intel Core和第四代Xeon开始集成的视频卡 )。


Windows屏幕截图


步骤1:配置内核


验证您有一个新的内核版本。 GVT-g的选项似乎已包含在4.8版之前,但是它们的确工作得更差,所以我建议使用最新的可用内核。 如果您足够原始,可以构建内核,请启用这些选项 。 同时禁用删除未使用的ksyms,因为此选项会导致bug


现在,您需要修复内核命令行参数。 重要选项是:


i915.enable_gvt=1 kvm.ignore_msrs=1 intel_iommu=on i915.enable_guc=0 

确保不要使用启用GuC加载的功能覆盖enable_guc=0 ,因为这将导致i915驱动程序崩溃。 引导时,进入工作环境并检查目录/sys/bus/pci/devices/0000:00:02.0/mdev_supported_types/ 。 如果不存在,则GVT-g不起作用。 检查原木和/或在枕头中哭泣。


为了解决该问题,您可以将这些模块添加到initramfs中,然后从其中删除i915。


有关更详细的日志记录,可以将drm.debug变量设置为某个值,例如,将其设置为0x02将包含来自驱动程序的消息。


步骤2:建立一个虚拟朋友


mdev_supported_types内部,您可以找到一整套目录。 该设置由您的图形内存量决定,每个子目录对应某种虚拟GPU。 其中的description文件包含有关此虚拟GPU支持的内存和分辨率的信息。 如果使用/create文件中的UUID输出/create具有大内存的虚拟GPU会给您带来无法理解的错误,那么您有几种选择。 首先,进入BIOS并添加视频内存(如果可能)。 如果这不起作用,则可以停止DM,切换到帧缓冲区,从那里创建所需的vGPU,然后返回到x11。 不幸的是,这种方法会导致许多错误,并且无法在笔记本电脑上达到60 FPS。 一种替代方法是创建一个较小的vGPU,并使用特殊程序来提高分辨率(CRU)。 这样,我设法达到了60 FPS,并且错误和冻结的发生率大大降低。


您可以使用以下命令创建vGPU:


 $ echo ${vGPU_UUID} | sudo tee /sys/bus/pci/devices/0000:00:02.0/mdev_supported_types/${vGPU_TYPE}/create 

并删除-这:


 $ echo 1 | sudo tee /sys/bus/mdev/devices/${vGPU_UUID}/remove 

译者注
您可以使用不带参数的uuidgen命令为vGPU生成UUID。 变量$ {vGPU_TYPE}表示mdev_supported_types目录中列出的类型之一。 还值得注意的是,每次重新启动时都必须重新创建vGPU,它们不会在两次操作系统启动之间保存。


步骤3:Cortana向您吼叫


下一步要得到更好的支持,要慢得多,也要痛苦得多-安装Windows10。请勿使用torrents或非官方下载文件,或旧版本的Windows, 此处提供正确的链接。 还值得下载带有virtio驱动程序的磁盘映像,该驱动程序专门用于加速此处的客户机 。 安装libvirtvirt-manager并运行libvirtd


 # systemctl start libvirtd 

运行virt-manager并确保您已连接到libvirt系统会话,而不是用户:
病毒管理器窗口


译者注
为了使virt-manager能够连接到系统会话,可以以root用户身份运行它,但是最好配置授权,例如,如Arch Wiki上所建议。


完成此操作后,就可以开始创建虚拟机了。 在设置对话框中,从本地iso图像中选择下载并找到下载的图像。 如果virt-manager无法将其识别为Windows 10映像,请手动选择它,因为这会加快Windows的速度,因为在这种情况下virt-manager提供了Microsoft的某些虚拟化界面。 创建磁盘映像或LVM分区并根据需要进行配置。 安装前的设置界面非常有限,因此我通常开始安装并立即停止以完全配置所有内容。 以下是一些设置:
虚拟机CPU设置
虚拟机网络设置


译者注
尽管存在关于在便携式计算机上设置虚拟机的文章,但由于某种原因,省略了有关使用无线适配器分配网络的问题。 事实是,virt-manager中的默认网络设置不适用于无线网络。 在这种情况下, 问题的答案和对此的评论会有所帮助。 作者还建议使用BIOS代替UEFI,这可能是因为UEFI需要其他配置。 另外,看来tianocore尚未与GVT-g配合使用,请参见bug 935 但是,就我而言,VM已启动,但Windows无法识别集成视频卡所连接的监视器。


如果您需要快速访问磁盘或什至在删除虚拟机文件时虚拟机具有压缩磁盘映像的能力(TRIM转发,为此,您需要使用qemu-img create -f qcow2 -o preallocation=metadata,lazy_refcounts此处的完整说明来创建映像),配置主驱动器以使用SCSI。 您将需要Windows虚拟机的驱动程序才能理解这种格式,因此请插入先前下载的Windows 10 virtio驱动程序磁盘。默认情况下,它们使用IDE,但是如果您改而使用,则可以加快安装速度,并减少使用旧代码的次数。用于SCSI DVD。 Windows开箱即用地支持此功能。 您也可以:


  • 强制USB使用USB 3.0
  • 添加spice,spice-webdav和qemu-ga通道,以便在VM和主机之间进行复制和粘贴以及文件共享
  • 删除未使用的虚拟硬件
  • 将模拟视频卡切换为QXL并将显示切换为SPICE,而不是收听网络(甚至是环回)( 译者注:否则,VM只会崩溃 )。
  • 将芯片类型切换为Q35,在BIOS设置旁边进行设置。
  • 喂狗

您还可以习惯于新朋友virsh edit 。 如果使用sudo -E运行它,则将使用环境变量(尤其是EDITOR)进行编辑,并且将使用libvirt系统会话,而不是用户会话。 例如,在此文件中,您可以在物理处理器和虚拟处理器之间分配对应关系,这是因为处理器缓存更加一致,并且调度程序的行为并不那么奇怪。 这是您可以放在其中的XML示例:


 <vcpu placement='static'>6</vcpu> <cputune> <vcpupin vcpu='0' cpuset='1'/> <vcpupin vcpu='1' cpuset='2'/> <vcpupin vcpu='2' cpuset='3'/> <vcpupin vcpu='3' cpuset='5'/> <vcpupin vcpu='4' cpuset='6'/> <vcpupin vcpu='5' cpuset='7'/> </cputune> <features> <hyperv> <relaxed state='on'/> <vapic state='on'/> <spinlocks state='on' retries='8191'/> <runtime state='on'/> <synic state='on'/> <stimer state='on'/> </hyperv> </features> <cpu mode='host-passthrough' check='none'> <topology sockets='1' cores='3' threads='2'/> </cpu> 

在此代码段中,我对VM进行配置,以使其看到具有三个物理核心的处理器,每个物理核心都有两个超线程。 此外,每个处理器/超线程都附加到其自己的超线程,并且此对应关系不会更改。 Windows Scheduler知道超线程并且可以正确使用它们,而不会将它们视为单独的处理器。 我还启用了一些默认情况下关闭的Hyper-V接口,这些接口可能不会起作用。 如果使用SPICE,则可以添加以下行以禁用压缩,因为仍然不使用外部网络访问VM。


 <graphics type='spice'> <listen type='none'/> <image compression='off'/> <jpeg compression='never'/> <zlib compression='never'/> <playback compression='off'/> <streaming mode='off'/> <!-- <gl enable='yes' rendernode='/dev/dri/by-path/pci-0000:00:02.0-render'/>     ,     libvirt --> </graphics> 

现在,您可以配置启动顺序并开始安装Windows。 如果您使用virtio或SCSI驱动器,Windows将找不到它。 您需要从所连接的驱动器安装SCSI驱动程序,它们位于virtscsi/amd64目录中。 一切应该顺利进行,Windows应该以缓慢而痛苦的而非加速模式启动。 Cortana将开始对您大吼大叫,并且您的网络将无法正常工作。 将其全部突破到桌面。 在此处,启动设备管理器,找到所有未识别的设备,然后从您连接的磁盘更新驱动程序。 您将获得一个稍快的Windows。


步骤4:有趣的部分


有三种方法可以从Windows在计算机屏幕上显示加速的虚拟VM。


  • VNC或其他某种远程访问协议(通常这是一个非常糟糕的解决方案)。 在此选项中,您仅需要连接vGPU并禁用所有其他显示器和视频卡。 同时设置display='off'设置。 您不需要稍后显示的igd-opregion选项。
  • SPICE(我无法达到30 FPS或更高的速度,但是可以在VM和主机之间正常使用剪贴板和文件传输)。
  • GTK +上的内置QEMU接口(共享剪贴板和文件传输不起作用,但使用补丁程序可以达到60 FPS)。

无论打算使用什么,都仍然必须使用第二个选项来安装GPU的驱动程序。 在编写本文时,Microsoft的内置驱动程序无法与GVT-g很好地配合,并且经常会损坏。 在将vGPU连接到VM之前,建议从Intel下载最新的驱动程序 (显然, Intel正在更改其分发驱动程序的方法 ,因此将来此步骤可能会有所不同或完全没有必要)。 现在,请确保您已创建vGPU。 打开virt-manager并用慢速的Cirrus替换快速QXL,以免发生冲突。 要将vGPU连接到VM,您需要打开virsh edit并在以下位置添加以下片段:


 <domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'> <hostdev mode='subsystem' type='mdev' managed='no' model='vfio-pci' display='on'> 

 <address uuid='fff6f017-3417-4ad3-b05e-17ae3e1a4615'/> 

  <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/> <rom enabled='no'/> </hostdev> <graphics type='spice'> <listen type='none'/> <image compression='off'/> <jpeg compression='never'/> <zlib compression='never'/> <playback compression='off'/> <streaming mode='off'/> <gl enable='yes' rendernode='/dev/dri/by-path/pci-0000:00:02.0-render'/> <!--      , virt-manager     ,        GL. ,      ,   auto. --> </graphics> <qemu:commandline> <qemu:arg value='-set'/> <qemu:arg value='device.hostdev0.x-igd-opregion=on'/> <!-- libvirt     ,      --> </qemu:commandline> </domain> 

注意:当我提供这样的XML代码片段时,应尽可能将其添加到当前的XML代码片段中,而不用替换任何内容。


确认您已为所有正在使用的vGPU创建了唯一的UUID,并且插槽号与任何其他PCI设备没有冲突。 如果插槽号在Cirrus GPU之后,则虚拟机将崩溃。 现在您可以启动虚拟机。 您需要安装virt-viewer才能看到两个显示! 您可以使用以下命令连接到VM


 $ sudo -E virt-viewer --attach 

其中一个显示为空白或未初始化,第二个为熟悉的小型非加速显示。 展开它,然后输入,为GPU安装驱动程序。 如果幸运的话,一切都会立即生效。 否则,您必须使用工作屏幕关闭并重新启动VM(不要重新启动)。 现在是时候打开终端并在内部运行dmesg -w 。 该命令将为您提供有关使用vGPU的问题和总体进度的一些有用信息。 例如,在启动时,KVM会抱怨MSR被阻止,然后在初始化vGPU时应该会收到一些不正确的访问消息。 如果太多,那是不对的。


如果系统启动,则可以打开显示设置并关闭非加速屏幕。 可以通过virt-viewer的“ 查看”菜单隐藏空白屏幕。 原则上,虚拟机已经可以使用,但是可以做几件事来实现更高的分辨率和更高的速度。


CRU实用程序非常有用。 您可以使用它,即使偶然发现一些图形工件或什至几乎是全黑屏幕,对于我来说,也可以运行该程序附带的Restart64.exe文件来重新启动Windows图形子系统。 我个人使用此实用程序在更适中的vGPU上使用更高的分辨率。


为了获得出色的60 FPS,您需要切换到GTK +上的内置QEMU监视器,而不支持与主机和类似的包子共享的剪贴板,并在其中更改一行并重建QEMU。 您还需要在XML中添加一堆讨厌的命令行参数。 卸下SPICE显示屏和Cirrus图形卡,并将vGPU的display属性设置为off (libvirt不支持GTK +上的显示屏,并且不允许不带显示屏display='on'情况下从display='on'引导)。


  <qemu:commandline> <qemu:arg value='-set'/> <qemu:arg value='device.hostdev0.x-igd-opregion=on'/> <qemu:arg value='-set'/> <qemu:arg value='device.hostdev0.display=on'/> <qemu:arg value='-display'/> <qemu:arg value='gtk,gl=on'/> <qemu:env name='DISPLAY' value=':1'/> <qemu:env name='GDK_SCALE' value='1.0'/> </qemu:commandline> 

在QEMU监视器上缩放HiDPI的效果非常差,因此我们将其关闭。 另外,您需要将DISPLAY变量设置为您正在使用的显示编号。 要为运行qemu的用户提供对X服务器的访问权限,请使用以下命令:


 # xhost si:localuser:nobody 

如果这不起作用,请尝试使用xhost + ,但请确保您使用的是防火墙。 否则,请尝试更安全的方法。


使用这种技巧,如果您不通过更改行来对其进行打补丁(如注释链接中所示),则由于QEMU中的此愚蠢错误 ,您仍然不会获得高于30 FPS的价格。 确保仅针对x86-64构建QEMU,除非打算在其他平台上使用它。 我连接了我的PKGBUILD,它不改变线路,但仅收集x86_64的QEMU,而此处没有网络存储支持。


如果您迷路了,可以看到我当前的libvirt XML


有用的链接


官方GVT-g调整指南
Dma-buf用户指南
NixOS Wiki上的Intel GVT-g设置文章
关于libvirt的Arch Wiki文章
无线接口上的KVM中的网络设置
英特尔GVT-g网站


PS:感谢aNNiMON在校对翻译文本和纠正错误方面的帮助。

Source: https://habr.com/ru/post/zh-CN437270/


All Articles