我看过的教程大多是基于IOMMU来实现GPU直通的。但是有没有办法绕过IOMMU呢?我的内核是5.15.126
更新 1:
从libvirt.org我找到
<forward type='hostdev'> 接口可以有一个可选的驱动程序子元素,其名称属性设置为“vfio”(VFIO 是一种与 UEFI 安全启动兼容的新设备分配方法)或“kvm”(由 KVM 内核模块直接处理的传统设备分配)自 1.0.5 起(仅限 QEMU 和 KVM,需要内核 3.6 或更新版本)。指定时,如果主机上没有请求的设备分配方法,设备分配将失败。未指定时,在 VFIO 驱动程序可用并已加载的系统上默认为“vfio”,在较旧的系统或尚未加载 VFIO 驱动程序的系统上自 1.1.3 起默认为“kvm”(在此之前,默认值始终为“kvm”)。
但是当我使用以下格式编辑 xml 时
<hostdev mode='subsystem' type='pci' managed='yes'>
<driver name='kvm'/>
<source>
<address domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
</source>
<address type='pci' domain='0x0000' bus='0x08' slot='0x00' function='0x0'/>
</hostdev>
我无法启动机器
error: unsupported configuration: host doesn't support legacy PCI passthrough
更新 2
根据源代码,libvirt 8.0.0 似乎不支持设置 driver='kvm'。我会尝试降级
domain_conf.c
case VIR_NETWORK_FORWARD_DRIVER_NAME_KVM:
actual->data.hostdev.def.source.subsys.u.pci.backend =
VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM;
break;
qemu_hostdev.c:
case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("host doesn't support legacy PCI passthrough"));
return false;
更新 3:
来自 libvirt 发行说明
v5.7.0 (2019-09-03)
删除 KVM 分配支持
KVM 风格的 PCI 设备分配自 4.2.0 版起被弃用,并从 4.12.0 版内核中移除。Libvirt 长期以来默认使用 VFIO。也从 libvirt 中移除了对 KVM 设备分配的支持。
此外,libvirt 仅支持 3 个驱动程序
/* the backend driver used for PCI hostdev devices */
typedef enum {
VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT, /* detect automatically, prefer VFIO */
VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM, /* force legacy kvm style */
VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO, /* force vfio */
VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN, /* force legacy xen style, use pciback */
VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST
} virDomainHostdevSubsysPCIBackendType;
研究了一下午,好像结论是:不使用VFIO passthrough的GPU passthrough在不修改Linux内核版本5.15的情况下是无法实现的。
答案1
我的结论是:如果不修改 Linux 内核版本 5.15,则无法使用 VFIO 直通来实现 GPU 直通。
我找到了一种与 VFIO 的 no-IOMMU 模式相关的可能方法。目前,我卡在了一个点上。我将在实验后提供更新。
失败。看来 Qemu 6.2.0 对 no-IOMMU 提供的支持很少甚至没有。在 中hw/vfio/common.c
,VFIO_NOIOMMU_IOMMU 类型未在iommu_types
数组中列出。
static int vfio_get_iommu_type(VFIOContainer *container,
Error **errp)
{
int iommu_types[] = { VFIO_TYPE1v2_IOMMU, VFIO_TYPE1_IOMMU,
VFIO_SPAPR_TCE_v2_IOMMU, VFIO_SPAPR_TCE_IOMMU };
int i;
for (i = 0; i < ARRAY_SIZE(iommu_types); i++) {
if (ioctl(container->fd, VFIO_CHECK_EXTENSION, iommu_types[i])) {
return iommu_types[i];
}
}
error_setg(errp, "No available IOMMU models");
return -EINVAL;
}
如果您能提供更好的方法,我将不胜感激。