本文仅为个人研究探索 GPU 的部分心得分享,不直接涉及未公开机密,但也请勿用作非法用途和商业用途。
前言
四年前,vGPU Unlock 项目 横空出世,为 20 系及以前的部分游戏显卡在 KVM 虚拟化平台下开启了专业显卡功能:GPU 虚拟化,为云办公、云游戏、多租户隔离云计算、小模型云推理用户带来了福音。
GPU 虚拟化,就是一张 GPU(显卡)切分为多张 vGPU(虚拟显卡) ,每张 vGPU 分配给一个虚拟机,
如 2080TI 11G:
- 每个用户分 1G 显存,可切出 11 张虚拟显卡,足可支撑 11 个用户的简单办公场景。
- 每个用户分 2G 显存,可切出 5 张虚拟显卡,足可以支撑 5 个用户的小游戏场景。
- 每个用户分 3.5G 显存,可切出 3 张虚拟显卡,足可以支撑 3 个用户的中型游戏场景。
GPU 虚拟化为云办公、云游戏、云计算等场景提供了强大的助力。
但四年过去了,它最高支持的卡……还是 2080Ti。
在这漫长攻坚期内,一众业界翘楚相继投身破局之战,最终却无不铩羽而返,从 vGPU unlock
项目启动至今,以 30 系为代表的新显卡的技术防线始终固若金汤,从未被人突破。129 120 111 99 93 91 89 8 46 39 16
皮蛋熊花了 7 个月时间进行方案梳理,逆向调试,不断总结,不断试错,终于攻破新版 vGPU 方案的防线,自此 GRID 方案支持的所有同代游戏显卡均可启用 vGPU,包括 30 系列、40 系列等(当前英伟达官方并未发布 vGPU 支持 50 系),为低成本 GPU 虚拟化带来了新的可能性。 下面是一些解说视频和成功截图:
解说和演示视频:
- 四年守望,七月磨刀,30系vGPU解锁,拿下!
- 第二期视频
成功截图:
- 510 驱动下 3080 解锁 vGPU
- 550 驱动下 3080 解锁 vGPU
- 535 驱动下 4080Super 解锁 vGPU
可选方案
市场方案和尝鲜尝试
GPU 虚拟化切分出的 vGPU,可以为虚拟机提供强大的图形助力。vGPU 能够让虚拟机支持 DX9/DX11/DX12/OpenGL/Vulkan 等图形 API,也可以让虚拟机支持 CUDA/OPENCL/DML 等并行计算 API,更可以让虚拟机支持 NVENC/NVDEC 加速视频编解码。vGPU 可以极大的增强虚拟机的 GPU 性能,使其无限接近真机的使用体验。
市面上支持 vGPU 的虚拟化可选方案有很多,比如 ESXi、Xen、KVM、HyperV 等,其中
- ESXi:vmware 公司推出的虚拟化平台
- Xen:开源虚拟化平台,分为半虚拟化 Xen-PV 和全虚拟化 Xen-HVM。代表平台:Citrix
- KVM:开源虚拟化平台,各个 linux 发行版中均内置。代表平台:ProxmoxVE 支撑软件:QEMU-KVM
- HyperV:微软推出的虚拟化平台
如果是个人用户想要直接体验 GPU 虚拟化,可以考虑使用 HyperV 平台的 Easy-GPU-PV 脚本,国内外应有不少教程可以检索到,按照 Easy-GPU-PV
关键词即可直达。
体验限制初现
但随着你深入使用 HyperV,你会逐渐的发现一些 HyperV 虚拟化下存在的一些固有限制,比如
- HyperV 大量使用半虚拟化技术,导致各类专用软件、游戏过虚拟化检测困难
- 缺乏 GPU 资源隔离,虚拟机的 GPU 问题可能会连带搞崩主机
- 没有官方支持,缺乏官方兼容性列表,缺少一些企业级特性
- 驱动强耦合,虚拟机中 GPU 驱动和 Host 主机的 GPU 驱动必须完全一致
- 某些专业设计软件的 CUDA、编解码接口出现兼容问题
这个时候你想解决这些问题,遍寻方案时你就会发现 NVIDIA 提供了一个企业级的解决方案,NVIDIA GRID,其广泛支持 ESXi、Xen、KVM、HyperV 平台。但其要求颇高,不仅需要是高端专业显卡,而且需要额外购买 License。这种企业级的方案虽然可以完整覆盖个人场景上的需求,但成本完全不是个人能够承受的。
解锁方案
但好在在 KVM 下还有 Unlock 项目可解锁游戏显卡使用该专业功能,在
- FastAPI-DLS: 解决授权问题
- vgpu_unlock vgpu_unlock-rs: 解决 20 系及其以前的显卡解锁 vGPU 功能
- Nvidia vGPU Guide: 解决 20 系及其以前驱动检测
这三个项目助力下,20 系列及其以前的部分显卡的 vGPU 解锁应畅通无阻。
$ nvidia-smi vgpu
Tue Jan 24 20:21:43 2023
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 525.85.07 Driver Version: 525.85.07 |
|---------------------------------+------------------------------+------------+
| GPU Name | Bus-Id | GPU-Util |
| vGPU ID Name | VM ID VM Name | vGPU-Util |
|=================================+==============================+============|
| 0 NVIDIA GeForce RTX 208... | 00000000:01:00.0 | 0% |
+---------------------------------+------------------------------+------------+
解锁综述
unlock 原理简述
vgpu_unlock/rs
项目所做的工作就是在 vmiop 插件到内核驱动的调用链中间添加了一级充当中间人传假话,用于劫持部分调用。
英伟达内核驱动 ↔ 中间人 ↔ VMIOP
- 当 VMIOP 问内核驱动是否支持 vGPU 时候,中间人返回给 VMIOP 支持。
- 当 VMIOP 问内核驱动是什么显卡的时候,中间人返回给 VMIOP 同代支持 vGPU 的型号, 比如 20 系列返回 RTX 6000 。
通过这样子的中间人假传话的机制欺瞒 VMIOP,让其认为显卡是正常支持 vGPU 的显卡,再配合下面内核部分工作:
Nvidia vGPU Guide
项目所作工作就是修改 Host 内核驱动,使其在两处检测中返回特定值:
- 检测显卡是否是支持 vGPU 的型号
isGridLicenseSupported
,强制修改函数逻辑,返回支持。 - 检测显卡特性函数
gpuDetectVgxBranding
强制返回BRANDING_TYPE_VGX
。
自此就攻破了 vGPU 的限制,完成了 20 系以前的解锁。
SR-IOV 新方案特点
但 30 系全面转向为 SR-IOV 的解决方案,这也导致四年时间社区所有业界翘楚折戟沉沙,因为要正面突破这个方案难入登天。
该方案实现了部分 GPU 硬件资源的切割,利用 PCIe 的虚拟化能力,生成多个 PCIe 虚拟功能设备,也就是 1 个 PF 生成多个 VF,每个 VF 直接分配给虚拟机,虚拟机使用 GPU 资源时候不用多次跨越 Guest/Host 进行通讯和资源分配,而是直接在 Guest 内部的 VF 层面完成读写,进一步减少了软件/CPU 开销,提升了部分场景下 GPU 的性能表现和硬件隔离能力。
SR-IOV 是一个硬件上的功能,在 PCIe 初始化的时候相关 Cap 就需要被置位,提供这个初始化能力的就是 vBIOS 了。英伟达在 10 系 GPU 的时候就给硬件启动链路上了强校验机制,修改后的 vBIOS 无法被刷入显卡,强制用夹子夹芯片的办法虽然可以刷入,但因为没有可信的签名,是不会被启动的。同时 enfuse 中存在额外配置,当刷入不同型号的 vBIOS,也不会被启动。
因此在没有一个可信签名的私钥、没有致命漏洞被发掘之前,修改 vBIOS 这条路基本上是被堵死的。
新的思路
KVM 虚拟化下的 NVIDIA GRID 方案在 30 系列的时候全面转向为 SR-IOV,因上述新方案特点已无正面突破可能,我们可以想办法让其退回到老的 Mdev 方案。基于此思路,我们开启了探索之路并成功尝试,如无意外,接下来的半年时间我会逐渐分享多篇探索过程中的心得附于下文,敬请期待:
- 探索心得 1
- 探索技能 1
- 设计方案揭秘 1
......
小结
请永远相信美好的事情即将发生,皮蛋熊历经磨难找到了道生一,一生二,二生三的道路。虽然皮蛋熊因为无法硬抗英伟达法务,导致无法公布直接的成品,但皮蛋熊会尽量总结探索过程中使用到的方法、手段、经验以及梳理的部分设计方案和一篇关联论文。和网友交流,期待有心网友能够在皮蛋熊提供的资料中找到三生万物这条路,但请注意,任何技术探索都应在合法合规为前提。
参考资料
- kvm 虚拟化平台搭建
- Hyper-V 虚拟化平台 GPU 分区和 GPU 半虚拟化技术比较及应用建议
- NVIDIA Virtual GPU (vGPU) Software
- Easy-GPU-PV 脚本:HyperV 下 GPU-PV
- FastAPI-DLS: 解决授权问题
- vgpu_unlock vgpu_unlock-rs: 解决 20 系及其以前的显卡解锁 vGPU 功能
- Nvidia vGPU Guide: 解决 20 系及其以前驱动检测
评论区