KVM直通的核心答案是:CPU带VT-d或AMD-Vi(也就是IOMMU),主板PCIe分组足够独立,加上一块支持直通的设备,配置就能跑通,性能接近物理机,损耗基本感知不到。
直通这事,听着绕,拆开了就三件事:硬件支不支持、IOMMU分组行不行、驱动绑没绑对,下面按这个逻辑展开。
KVM显卡直通硬件要求有哪些下限
先别急着翻配置教程,硬件这关过不了,后面全是白折腾,直通不是KVM单独能决定的,它依赖CPU、主板、设备三层配合。
CPU侧的关键点:VT-d与AMD-Vi缺一不可
CPU得同时满足两个条件:虚拟化扩展和DMA重映射,Intel平台叫VT-x和VT-d,AMD平台叫AMD-V和AMD-Vi,后者才是直通的关键,说白了,没有VT-d,设备就像没有钥匙,DMA内存访问的路直接被封死。
- Intel阵营,酷睿从六代左右开始基本全系带VT-d,至强更不用提。
- AMD阵营,锐龙从初代起就内置AMD-Vi,EPYC是标配。
- 检查方法很简单,
grep -E 'vmx|svm' /proc/cpuinfo看虚拟化功能,dmesg | grep -i iommu看IOMMU有没有在实际工作。
行业共识认为,直通后的设备性能和物理机几乎一致,瓶颈主要在主板的DMA重映射开销上,CPU代数太老,中断处理能力弱,直通后网络吞吐会掉一块,但GPU运算这类大块数据搬运影响很小。
主板和IOMMU分组决定成败
很多用户CPU明明支持,却直通失败,问题全出在主板上,直通的最小单位不是物理设备,而是IOMMU分组,一个组里的设备必须整体分配,不能拆开。
- 消费级主板经常把显卡x16插槽和M.2、x1插槽塞进同一组,你想直通显卡,结果把NVMe固态也绑进去了,虚拟机一开机宿主机就丢盘。
- 解决办法有两个:一是换插槽位置,看哪根槽独立分组;二是用内核参数
pcie_acs_override=downstream强行拆组,但会降低安全性,生产环境慎用。 - 服务器主板和工作站主板的IOMMU分组通常干净得多,双路Xeon或EPYC平台基本一根槽一组。
业内专家指出,多数IOMMU分组问题源于消费级主板的PCIe通道复用设计,这属于硬件层面的成本取舍,软件层面只能靠ACS补丁绕。
显卡直通的隐藏门槛
直通显卡给虚拟机,和普通插显卡不一样,宿主机自己也得有个显示输出,要么用核显,要么再插一张亮机卡,如果你把唯一一张显卡直通进去,宿主机直接黑屏,管理全靠SSH。
- N卡在虚拟机里容易报驱动错误代码43,需要隐藏KVM的虚拟化特征才能绕过,这个后面细说。
- A卡相对好办,但部分老型号在重置上会卡住,虚拟机重启后显卡不工作,得整机断电才能恢复。
- 核显直通是另一种玩法,Intel核显可以通过GVT-g拆分给多个虚拟机用,但那是vGPU路线,和本篇文章讨论的PCIe直通不是一回事。
除了显卡,NVMe固态、独立网卡、USB控制器都可以直通,KVM直通配置步骤本身大同小异,核心逻辑都是把物理设备从宿主机驱动剥离,挂到vfio-pci上再交给虚拟机。
KVM虚拟机直通配置步骤:从BIOS到虚拟机
硬件确认没问题,就开始实操,下面以PCIe显卡直通为例,完整走一遍流程,如果你用的是Proxmox VE(也就是PVE),界面不一样但底层路径一样。
第一步:确认支持状态,两条命令看清家底
在宿主机上执行:
lspci -nn | grep -i nvidia
记下显卡的设备ID,10de:1b06,这个ID后面绑定驱动要用,再查看IOMMU分组,可以直接用现成脚本:
#!/bin/bash
shopt -s nullglob
for g in $(find /sys/kernel/iommu_groups/ -maxdepth 0 -type d | sort -V); do
echo "IOMMU Group ${g##/}:"
for d in $g/devices/; do
echo -e "t$(lspci -nns ${d##/})"
done;
done;
如果这个脚本输出的分组里,显卡所在组合并了其他不相干设备,第一步就得解决分组问题,否则后面免谈。
第二步:改内核参数,打开IOMMU大门
编辑 /etc/default/grub,在 GRUB_CMDLINE_LINUX_DEFAULT 里加上:
quiet intel_iommu=on iommu=pt
AMD平台改成:
quiet amd_iommu=on iommu=pt
iommu=pt 的意思是预先建立直通需要的映射,减少运行时开销,更新引导配置后重启,Debian系用 update-grub,RHEL系用 grub2-mkconfig
,路径略有差异但原理一致。
第三步:绑定vfio-pci,让设备改嫁
重启后,创建 /etc/modprobe.d/vfio.conf:
options vfio-pci ids=10de:1b06,10de:10ef
后面那个ID是显卡对应的声卡设备,通常绑在一块,接着屏蔽显卡默认驱动:
echo "blacklist nvidia" >> /etc/modprobe.d/blacklist.conf
echo "blacklist nouveau" >> /etc/modprobe.d/blacklist.conf
重建内存盘镜像,Debian系执行 update-initramfs -u,RHEL系执行 dracut --force,再重启,lspci -nnk 能看到显卡Driver显示为 vfio-pci,说明绑定成功。
第四步:在虚拟机配置里添加PCI设备
用virt-manager或者直接编辑XML,如果走图形界面,编辑虚拟机的硬件信息,添加PCI Host Device,选中显卡的两个function即可,手动XML则是这样:
<hostdev mode='subsystem' type='pci' managed='yes'>
<source>
<address domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
</source>
</hostdev>
managed='yes' 让libvirt自动处理驱动切换,CPU模式建议设成 host-passthrough,让虚拟机直接看到宿主机的CPU特性集。
第五步:处理N卡报错43的特殊配置
NVIDIA驱动检测到虚拟机环境会拒绝工作,报错代码43,解决方式是把虚拟机伪装成物理机,在XML的 <features> 区域加:
<hyperv> <relaxed state='on'/> <vapic state='on'/> <spinlocks state='on' retries='8191'/> </hyperv> <kvm> <hidden state='on'/> </kvm>
同时给虚拟机加锁页内存,直通设备需要固定内存不换出:
<memoryBacking> <locked/> </memoryBacking>
上述配置完成后开虚拟机,进系统装驱动,就能正常使用了。
直通之后的事:性能感知与排错经验
直通不是配完就完事,性能调优和故障排查是另一个坑。
KVM直通性能损耗到底可不可感知
从数据路径看,直通设备绕过QEMU的软件模拟层,虚拟机直接通过DMA访问物理设备,中间只经过IOMMU的地址翻译,相对于全虚拟化,这条路短得多。
- 显卡直通打游戏,帧数差距在跑分里看得出来,实际游戏体验基本没差。
- 网卡直通横向对比,小包转发性能比virtio-net高,但CPU中断负载也更高。
- NVMe直通对比virtio-blk,顺序读写差距不大,延迟和4K随机性能有明显提升。
有一些玩家执着于KVM显卡直通打游戏,核心原因就是Windows虚拟机里的GPU性能接近于物理机,配合CPU pinning和CPU大页,体验非常接近原生。
报错排查顺序和常见坑
遇到直通失败,按顺序查,别乱试。
dmesg | grep -i vfio看设备有没有被vfio接管。lspci -nnk确认设备驱动的绑定状态。- 虚拟机日志看有没有中断冲突。
- N卡报43先检查
hidden state开没开。
多数直通失败都卡在这几个点上:IOMMU分组拆不开、驱动绑定顺序不对、虚拟机固件选错(UEFI和SeaBIOS对PCIe直通的支持有差异)、还有卡在ACS override导致的设备诡异行为,踩坑后复盘,90%都能解开。
KVM直通常见问题快速问答
KVM直通显卡需要什么样的CPU配置?
至少4核心起步,支持VT-d或AMD-Vi,如果你打算直通显卡玩游戏,建议6核心以上,并且开启CPU pinning,把物理核心固定分给虚拟机,减少调度抖动。
直通和SR-IOV有什么区别?
直通是整个物理设备独占给一台虚拟机,SR-IOV是把设备切成多个虚拟功能分给多台虚拟机,SR-IOV适用于网卡和部分数据中心GPU,能实现硬件级多路复用,但配置门槛高,也需要设备本身支持。
直通后虚拟机蓝屏或死机怎么排查?
先把宿主机的dmesg日志翻一遍,vfio绑定阶段报错,通常是IOMMU分组或者驱动冲突;虚拟机运行中死机,优先考虑中断问题,调整MSI中断模式往往能解决,NVIDIA显卡蓝屏多半是驱动检测到虚拟化环境,按上文方式隐藏KVM特征。
直通是KVM的一项成熟能力,硬件达标后按流程操作,成功率很高,把步骤走稳,虚拟机和物理机的边界就在你手里。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/628612.html





