前言

在学校实验室有需求组装一台服务器,加上预算限制,又有玩虚拟化的想法,于是拼了一台I9-13900K+Tesla P40这种看似洋垃圾又不是洋垃圾方案的玩意(

由于早年在unraid上有一些不是很好的体验,认为还是business稳定,尝试了esxi。ESXI先是由于大小核问题会PSOD,解决办法是启动项加上

cpuUniformityHardCheckPanic=FALSE

禁掉cpu统一性检测。最后放弃的原因是核显无法sr-iov虚拟化,显示支持,但是无法拆分,状况就是一直重启。

后面换了pve7,先是碰到了安装界面都进不去,倒腾半天。然后IGPU SR-IOV需要6.1内核,搞上了后发现Nvidia的grid驱动装不上了,可能因为内核太新,也没找到相关patch。无奈退到最后的unraid上。
(pve还碰到了13th报mce hardware的问题,引导参数带上intel_idle.max_cstate=1解决)
别问为啥没winserver,winserver各种去掉打不上,一小时蓝屏10次给我整麻了


偷了个懒,直接用的开心整合版(

需求

这么搞是有几个需求,一是有多个人,所以要多台“云主机”,然后其中有两台需要nvidia的vgpu跑模型之类的,剩下的给核显+虚拟显示器就够了。虽然uhd770可以sr-iov虚拟化7个出来,但是这玩意的性能emmm,自己掂量(
所以还是就带个显卡亮个机就好

核显虚拟化

修改

核显为uhd770,unraid 6.11.5为5.19内核来着。
需要用到
Kernel image supported SR-IOV for Unraid OS

unraid的引导参数可能要加上

intel_iommu=on iommu=pt

把release的文件替换掉unraid u盘根目录的文件,原文件自行做好备份。
然后在u盘下的config/modprobe.d下修改i915.conf(没有文件/文件夹就自行创建)在i915.conf的最后一行添加上

options i915 enable_guc=7

然后修改config下的go文件
最后添加上

modprobe i915
echo 7 > /sys/devices/pci0000:00/0000:00:02.0/sriov_numvfs

注意,这里的echo后面的数字,是指要开几个虚拟显卡,比如我这开7个就是7,2个就是改成2,最大为7。

开机,改qemu参数

开机,去直通的地方看。可以看到类似下图所示的

此处不需要勾选拆分直通啥的,看到有你设定数量的虚拟显卡就行。
然后装系统方面可以参考vGPU (SR-IOV) with Intel 12th Gen iGPU [Updated 2023]
大概就是,win的话就是vnc模式装机,装好进去后开3389。关机,把虚拟化出来的核显分配,关掉vnc,用mstsc连进去,打最新驱动就行。linux的话6.1内核以上,然后装i915-sriov-dkms,grub设定i915.enable_nuc=3啥的,具体看上面那个参考吧。

此处重点说下把虚拟化的核显给虚拟机的步骤

注:千万不要把原来的核显通给虚拟机,只能通虚拟出来的!

正常情况如上图通给虚拟机,然后切换到xml视图,找到这张显卡的部分,例如我这里是

    <hostdev mode='subsystem' type='pci' managed='yes'>
      <driver name='vfio'/>
      <source>
        <address domain='0x0000' bus='0x00' slot='0x02' function='0x1'/>
      </source>
      <alias name='hostdev0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/>
    </hostdev>

我给的设备是00:02.1的,正常igpu是00:02.0,中间02是slot,小数点后是function。如果不修改的话开机是看不到这个设备的。我们要改成

    <hostdev mode='subsystem' type='pci' managed='yes'>
      <driver name='vfio'/>
      <source>
        <address domain='0x0000' bus='0x00' slot='0x02' function='0x1'/>
      </source>
      <alias name='hostdev0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
    </hostdev>

source不动,因为原地址本来就是这个值,改下面的address中的function为0,开机就能看到设备了。

注意unraid特性,从xml视图切回去修改后在xml中改的会部分失效

虚拟显示器

给两个方案,一是直接用parsec远程软件自带的Virtual Display Driver,然后parsec设置里打开Fall back to virtual display。
二是用usbmmidd驱动,这个教程网上大把,但是我这边测得装了这个后parsec连上去鼠标会重影,没找到好的办法解决。

Nvidia vgpu

家用卡自行想办法用vgpu_unlock啥的,此处不提。

关于vgpu驱动,验证,分类等自行参考Proxmox Nvidia Telsa P4 显卡 vGPU 方案

驱动用法

在网上有看到插件版的,要会员,就先跳过(
然后在unraid论坛看到有人制作了一份驱动
UNRAID 6.11.5 NVIDIA VGPU 驱动
在其中给定的链接中下驱动,这边建议直接扔进启动u盘的根目录。
文中说了主机不能硬解,没有其需求,跳过。
打开unraid的终端,输入

installpkg /boot/nvidia-vgpu-525.60.12-unraid.txz

装上驱动后输入

nvidia-smi


能出现信息就正常。
输入

mdevctl types


可以看到支持虚拟出来的种类和参数,各取所需。
然后创建设备
自行生成一个uuid,一个设备对应一个uuid

mdevctl start -u xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx -p 0000:01:00.0 --type nvidia-53

xxx代表的就是uuid,-p后面跟着独显pci地址,type是你选择的哪种类型,我这里是nvidia-53。
创好后输入

mdevctl list


可以看到你创的设备。

修改qemu参数

打开你要给的虚拟机编辑界面,xml模式。
在device中,可以考虑加在

<memballoon model='none'/>

上面

    <hostdev mode='subsystem' type='mdev' managed='no' model='vfio-pci' display='off'>
      <source>
        <address uuid='xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx'/>
      </source>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
    </hostdev>

其中,xxx就是刚刚创建用到的uuid,slot可以自行改,不冲突即可。
保存,开机,打上vgpu专用的驱动,驱动版本不能大于主机用的版本。

修改为开机自启

由于unraid的系统是只读的,所以除了插件外,系统中的更改重启复原。
一句话,把安装驱动命令,创建设备命令,直接写进/boot/config/go文件中,往下加就完事了。

虚拟显示器

三个字:不需要
Nvidia的vgpu估计是考虑到给服务器用,自带一个叫Nvidia NGX的虚拟显示器,还是独显直连(

获取vgpu授权

参考来自民间的VGPU授权fastapi-dls
unraid直接有docker功能,参考里面的直接把docker搭上就完事了,端口不和ssl冲突的话自定义下。
win篇:
开好docker后,有vgpu的虚拟机中浏览器打开

https://x.x.x.x/client-token

x是这个docker所在的ip地址,改了端口的自行加上端口号。
正常情况会有个文件下载,把文件放到

C:\Program Files\NVIDIA Corporation\vGPU Licensing\ClientConfigToken

重启虚拟机,powershell输入

nvidia-smi -q


可以看到已经授权。

Linux:

curl --insecure -X GET https://x.x.x.x/client-tokenn -o /etc/nvidia/ClientConfigToken/client_configuration_token.tok
service nvidia-gridd restart
nvidia-smi -q | grep "License"

此处为collinwebdesigns/fastapi-dls的readme,查看授权方式与win一样。

最后来张虚拟机图:

KVM隐藏

修改虚拟机参数的features部分

<features>
    <acpi/>
    <apic/>
    <hyperv>
      <relaxed state='on'/>
      <vapic state='on'/>
      <spinlocks state='on' retries='8191'/>
      <vendor_id state='on' value='anything'/>
    </hyperv>
    <kvm>
      <hidden state='on'/>
    </kvm>
    <vmport state='off'/>
    <ioapic driver='kvm'/>
  </features>

加上kvm这段。

嵌套虚拟化

貌似是说unraid6.11以上已经默认开了嵌套虚拟化。
如果没有的话去unraid的grub启动参数加上

pcie_acs_override=downstream pci=assign-busses acpi_enforce_resources=lax kvm-intel.nested=1

修改虚拟机参数

  <cpu mode='host-passthrough' check='partial' migratable='on'>
    <topology sockets='1' dies='1' cores='10' threads='2'/>
    <feature policy='require' name='ds'/>
    <feature policy='require' name='acpi'/>
    <feature policy='require' name='ss'/>
    <feature policy='require' name='ht'/>
    <feature policy='require' name='tm'/>
    <feature policy='require' name='pbe'/>
    <feature policy='require' name='dtes64'/>
    <feature policy='require' name='monitor'/>
    <feature policy='require' name='ds_cpl'/>
    <feature policy='require' name='vmx'/>
    <feature policy='require' name='smx'/>
    <feature policy='require' name='est'/>
    <feature policy='require' name='tm2'/>
    <feature policy='require' name='xtpr'/>
    <feature policy='require' name='pdcm'/>
    <feature policy='require' name='osxsave'/>
    <feature policy='require' name='tsc_adjust'/>
    <feature policy='require' name='clflushopt'/>
    <feature policy='require' name='intel-pt'/>
    <feature policy='require' name='md-clear'/>
    <feature policy='require' name='stibp'/>
    <feature policy='require' name='ssbd'/>
    <feature policy='require' name='xsaves'/>
    <feature policy='require' name='pdpe1gb'/>
    <feature policy='require' name='invtsc'/>
    <feature policy='disable' name='hypervisor'/>
  </cpu>

在cpu这块里加上或者修改

<feature policy='disable' name='hypervisor'/>


可以看到任务管理器里不会有“虚拟机:是”的文字了,而是显示L1,L2,L3缓存和虚拟化已启用。这种情况下一些游戏检测就可以过了,例如原神(

END

目前就记得这些,以后还有啥坑在补上。