使用Virt-manager实现GPU透传时卡在Preparing host device致libvirtd冻结
解决libvirtd启动GPU透传macOS虚拟机时冻结的问题
关键排查步骤
1. 确认IOMMU分组独立性
执行 lspci -nnk 查看GPU及其音频控制器的IOMMU分组,必须保证它们单独在一个分组里,不能和南桥、网卡这类核心设备混组。如果分组不独立,要么进BIOS调整PCIe设置(比如关闭SR-IOV、改PCIe插槽链路宽度),要么加内核启动参数 pcie_acs_override=downstream,multifunction 强制拆分(注意这可能影响稳定性)。
2. 验证GPU ROM文件
别用通用ROM,必须提取对应型号的纯净版本。重新提取命令:
sudo dd if=/dev/vgaXXX of=gpu.rom bs=1M count=16
把 vgaXXX 换成你的GPU设备节点(比如 /dev/nvidia0)。然后检查虚拟机XML里的ROM路径是否正确,文件权限要设为 qemu:qemu 可读。
3. 卸载宿主机GPU内核模块
宿主机不能占用GPU,先查有没有加载相关模块:
lsmod | grep -E 'nvidia|amdgpu'
有加载的话直接卸载:
# NVIDIA用户 sudo modprobe -r nvidia_drm nvidia_modeset nvidia_uvm nvidia # AMD用户 sudo modprobe -r amdgpu
可以写个启动脚本自动处理,省得每次手动操作漏了。
4. 修正libvirt配置参数
打开虚拟机XML,检查这几点:
<domain>标签的type必须是kvm,还要加命名空间xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0"。- GPU透传的
<hostdev>节点里,要指定正确的PCI地址,加上禁用重置的配置:<hostdev mode='subsystem' type='pci' managed='yes'> <source> <address domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> </source> <address type='pci' domain='0x0000' bus='0x02' slot='0x00' function='0x0'/> <rom file='/path/to/your/gpu.rom'/> <driver name='vfio' reset='no'/> </hostdev> - 加QEMU命令行参数,禁用可能导致死锁的特性:
<qemu:commandline> <qemu:arg value='-device'/> <qemu:arg value='vfio-pci,host=01:00.0,romfile=/path/to/your/gpu.rom,x-vga=on'/> <qemu:arg value='-no-hpet'/> </qemu:commandline>
5. 检查宿主机硬件设置
进BIOS确认VT-d/AMD-Vi已经开启,同时关掉Secure Boot——不少GPU透传场景下Secure Boot会干扰vfio加载。另外把GPU插到CPU直连的PCIe插槽上,别用南桥转接的插槽,容易出IOMMU异常。
冻结后的应急恢复
如果libvirtd冻住了,systemctl restart libvirtd 没用的话:
- 先临时开无IOMMU模式:
echo 1 > /sys/module/vfio/parameters/enable_unsafe_noiommu_mode - 然后强杀libvirtd进程:
sudo kill -9 $(pidof libvirtd) - 重启宿主机后再重新排查配置问题。
内容的提问来源于stack exchange,提问作者Tropp
相关产品推荐
相关产品推荐

