引言:为什么你需要一台 4K 复古游戏机
在 4K 显示器已经成为标配的今天,那些陪伴我们童年的经典游戏却面临着令人尴尬的显示问题——原始分辨率拉伸到 4K 后画面糊成一片,LCD 的响应延迟让平台跳跃游戏的操作手感大打折扣。与此同时,现代 GPU 虚拟化技术的成熟让我们有机会在一台机器上同时运行 Windows 游戏宿主和 Linux 工作站,通过 PCIe 直通将显卡直接分配给虚拟机,实现近乎原生的游戏性能。本文将完整记录从零搭建一台 KVM GPU 直通复古游戏服务器的全过程。
一、硬件选型:寻找最佳性价比组合
1.1 CPU 与主板的选择
GPU 直通的核心依赖是 CPU 的 IOMMU(输入输出内存管理单元)支持。Intel 平台需要 VT-d,AMD 平台需要 AMD-Vi(即 SVM + IOMMU)。建议选择支持 ACS(Access Control Services)拆分的主板,这样可以将同一 PCIe 根端口下的设备分到不同的 IOMMU 组中。具体推荐配置:
- AMD 平台:Ryzen 5/7 系列 + B550/X570 主板,性价比最优
- Intel 平台:12代+ Core i5/i7 + B660/Z690 主板,需确认 VT-d 已开放
- 内存:至少 32GB,为虚拟机分配 16GB,宿主保留 16GB
- 显卡:建议两张卡——一张低功耗核亮机卡(如 GT 710)给宿主,一张主显卡直通给虚拟机
1.2 为什么需要两张显卡
GPU 直通意味着显卡完全脱离宿主控制,交由虚拟化层(VFIO)接管。宿主失去显卡后无法输出画面,因此需要一张额外的显卡维持宿主运行。对于支持核显的 Intel CPU,可以直接使用核显输出宿主画面。
二、Linux 宿主系统准备
2.1 启用 IOMMU 与 VFIO
编辑 GRUB 配置以启用 IOMMU 内核参数:
/etc/default/grub:
GRUB_CMDLINE_LINUX_DEFAULT="intel_iommu=on iommu=pt"
或者对于 AMD 平台:
GRUB_CMDLINE_LINUX_DEFAULT="amd_iommu=on iommu=pt"
生成新 GRUB 配置后重启系统,验证 IOMMU 分组:
#!/bin/bash
shopt -s nullglob
for d in /sys/kernel/iommu_groups/*/devices/*; do
n='${d#*/iommu_groups/*}'; n='${n%%/*}'
printf 'IOMMU Group %s: ' "$n"
lspci -nns "${d##*/}"
done
2.2 绑定显卡到 VFIO 驱动
找到目标显卡的 PCI ID(如 10de:1f08 和 10de:10f8),编写 VFIO 配置:
/etc/modprobe.d/vfio.conf:
options vfio-pci ids=10de:1f08,10de:10f8
softdep nouveau pre: vfio-pci
softdep nvidia pre: vfio-pci
softdep snd_hda_intel pre: vfio-pci
重建 initramfs 后重启,确认驱动绑定成功:
lspci -nnk -d 10de:1f08
Kernel driver in use: vfio-pci
三、KVM 虚拟机配置
3.1 创建 Windows 虚拟机
使用 virt-manager 或 XML 定义创建虚拟机,关键优化点包括:
- CPU 模式:host-passthrough + 拓扑优化(使用 host 的物理核心布局)
- 磁盘:virtio-blk 或 virtio-scsi,cache=none, io=threads
- 网络:virtio-net + Bridge 桥接
- 内存:16GB,启用 hugepages(大页内存)减少 TLB miss
3.2 PCIe 直通配置
在虚拟机 XML 中添加 hostdev 设备定义:
<hostdev mode="subsystem" type="pci" managed="yes">
<driver name="vfio"/>
<source>
<address domain="0x0000" bus="0x01" slot="0x00" function="0x0"/>
</source>
<address type="pci" domain="0x0000" bus="0x03" slot="0x00" function="0x0"/>
</hostdev>
3.3 性能调优关键参数
<features>
<hyperv>
<relaxed state="on"/>
<vapic state="on"/>
<spinlocks state="on" retries="8191"/>
<vendor_id state="on" value="randomid"/>
</hyperv>
<kvm>
<hidden state="on"/>
</kvm>
</features>
<cpu mode="host-passthrough" match="exact" check="none">
<topology sockets="1" cores="8" threads="1"/>
<feature policy="require" name="topoext"/>
</cpu>
关键优化说明:
- hyperv vendor_id 隐藏 KVM 特征,避免 NVIDIA 驱动检测到虚拟机后拒绝安装
- kvm hidden 状态隐藏 Hypervisor 存在,某些 DRM 保护的游戏需要此设置
- hyperv 的 relaxed/vapic/spinlocks 显著提升 Windows 虚拟机的计时器精度
四、输入设备与音频方案
4.1 方案一:USB 控制器直通
直通整个 USB 控制器到虚拟机,宿主上的键盘鼠标自动与虚拟机关联,零延迟零抖动。缺点是该控制器上的所有设备(包括 U 盘)都无法在宿主机上使用。
4.2 方案二:Evdev 输入直通
通过 libevdev 将宿主机的键盘鼠标事件直接转发到虚拟机,延迟约 0.1ms。配置文件示例:
<input type="evdev">
<source dev="/dev/input/by-id/usb-Logitech_G502-event-mouse"/>
</input>
4.3 音频方案
推荐使用 Scream(网络音频接收端)或直接通过 HDMI/DP 音频输出。Scream 方案在虚拟机内安装驱动,通过网络将音频传输到宿主机 PulseAudio:
sudo apt install scream
sudo systemctl enable --now scream@eth0
五、性能实测与游戏兼容性
实测平台:Ryzen 5 5600X + RTX 3070 直通 + 32GB DDR4-3200 + Samsung 980 Pro NVMe
| 游戏 | 原生 Windows 帧率 | KVM 直通帧率 | 性能损失 |
|---|---|---|---|
| Hollow Knight | 165 fps | 163 fps | 1.2% |
| Celeste | 300 fps | 295 fps | 1.7% |
| Elden Ring | 60 fps | 58 fps | 3.3% |
| DOOM Eternal (Vulkan) | 200 fps | 192 fps | 4.0% |
| Hades | 144 fps | 140 fps | 2.8% |
大多数游戏性能损失在 1%~5% 之间,几乎无法感知。对于反作弊软件(如 BattlEye/EAC),部分游戏可能需要额外的隐藏配置:在 QEMU 命令行中添加 -cpu host,kvm=on,+hypervisor 并配合 hyperv vendor_id 隐藏。
六、进阶:GPU 分片虚拟化(vGPU / SR-IOV)
如果你希望让多个虚拟机同时共享同一张 GPU,NVIDIA 的 vGPU 技术(需要 GRID 授权)或 Intel GVT-g(集成显卡)是可行方案。AMD 平台目前无官方 vGPU 方案,但开源项目 Looking Glass 可以实现低延迟的画面串流回宿主机:
git clone https://github.com/gnif/LookingGlass.git
cd LookingGlass
mkdir client/build && cd client/build
cmake ..
make -j$(nproc)
sudo make install
Looking Glass 通过共享内存(IVSHMEM)直接在宿主机和虚拟机间传输帧缓冲,延迟低至 ~1ms,视觉效果接近直接使用物理显示器。
结语
KVM GPU 直通技术已经相当成熟,无论是玩游戏还是做 GPU 计算工作站,都能获得接近原生的性能体验。在 Linux 宿主上运行日常开发工作,需要游戏时切换到 Windows 虚拟机,一台设备满足双重需求——这正是开源虚拟化技术赋予我们的自由。随着 Intel GVT-d、SR-IOV 等技术的普及,未来的 GPU 虚拟化将更加精细化和普及化。

发表评论 取消回复