diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 98cc05480f00fe669bf115c4550c08d4568a69a1..22c9144514014fb980f05f9fe03c2ba9adef83de 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -5364,17 +5364,6 @@ qemuBuildHostdevCommandLine(virCommandPtr cmd, /* PCI */ if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && subsys->type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) { - int backend = subsys->u.pci.backend; - - if (backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) { - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("VFIO PCI device assignment is not " - "supported by this version of qemu")); - return -1; - } - } - unsigned int bootIndex = hostdev->info->bootIndex; /* bootNet will be non-0 if boot order was set and no other @@ -5457,29 +5446,8 @@ qemuBuildHostdevCommandLine(virCommandPtr cmd, switch ((virMediatedDeviceModelType) mdevsrc->model) { case VIR_MDEV_MODEL_TYPE_VFIO_PCI: - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("VFIO PCI device assignment is not " - "supported by this version of QEMU")); - return -1; - } - - break; case VIR_MDEV_MODEL_TYPE_VFIO_CCW: - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_CCW)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("VFIO CCW device assignment is not " - "supported by this version of QEMU")); - return -1; - } - break; case VIR_MDEV_MODEL_TYPE_VFIO_AP: - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_AP)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("VFIO AP device assignment is not " - "supported by this version of QEMU")); - return -1; - } break; case VIR_MDEV_MODEL_TYPE_LAST: default: diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 8ba724841d860e128162578ca6864455d631a369..40a2e33658a27d9a83c7a8d2fe4ee081497d3ca5 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -6109,6 +6109,13 @@ qemuDomainMdevDefVFIOPCIValidate(const virDomainHostdevDef *hostdev, { const virDomainHostdevSubsysMediatedDev *dev; + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("VFIO PCI device assignment is not " + "supported by this version of QEMU")); + return -1; + } + /* VFIO-PCI does not support boot */ if (hostdev->info->bootIndex) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", @@ -6152,11 +6159,19 @@ qemuDomainMdevDefVFIOPCIValidate(const virDomainHostdevDef *hostdev, static int qemuDomainMdevDefVFIOAPValidate(const virDomainHostdevDef *hostdev, - const virDomainDef *def) + const virDomainDef *def, + virQEMUCapsPtr qemuCaps) { size_t i; bool vfioap_found = false; + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_AP)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("VFIO AP device assignment is not " + "supported by this version of QEMU")); + return -1; + } + /* VFIO-AP does not support boot */ if (hostdev->info->bootIndex) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", @@ -6198,8 +6213,14 @@ qemuDomainMdevDefValidate(const virDomainHostdevDef *hostdev, case VIR_MDEV_MODEL_TYPE_VFIO_PCI: return qemuDomainMdevDefVFIOPCIValidate(hostdev, def, qemuCaps); case VIR_MDEV_MODEL_TYPE_VFIO_AP: - return qemuDomainMdevDefVFIOAPValidate(hostdev, def); + return qemuDomainMdevDefVFIOAPValidate(hostdev, def, qemuCaps); case VIR_MDEV_MODEL_TYPE_VFIO_CCW: + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_CCW)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("VFIO CCW device assignment is not " + "supported by this version of QEMU")); + return -1; + } break; case VIR_MDEV_MODEL_TYPE_LAST: default: @@ -6217,6 +6238,8 @@ qemuDomainDeviceDefValidateHostdev(const virDomainHostdevDef *hostdev, const virDomainDef *def, virQEMUCapsPtr qemuCaps) { + int backend; + /* forbid capabilities mode hostdev in this kind of hypervisor */ if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, @@ -6229,9 +6252,22 @@ qemuDomainDeviceDefValidateHostdev(const virDomainHostdevDef *hostdev, if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) { switch ((virDomainHostdevSubsysType) hostdev->source.subsys.type) { case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: - case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: break; + + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: + backend = hostdev->source.subsys.u.pci.backend; + + if (backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) { + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("VFIO PCI device assignment is not " + "supported by this version of qemu")); + return -1; + } + } + break; + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: if (hostdev->info->bootIndex) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", diff --git a/tests/qemumemlocktest.c b/tests/qemumemlocktest.c index 986dfb77bd510fb84d7847071e9286951b071f62..c70a426c16ee3f1fcbe3cadfdcdd5038f1ed08fe 100644 --- a/tests/qemumemlocktest.c +++ b/tests/qemumemlocktest.c @@ -106,6 +106,18 @@ mymain(void) DO_TEST("pc-kvm", 0); DO_TEST("pc-tcg", 0); + if (!(qemuCaps = virQEMUCapsNew())) { + ret = -1; + goto cleanup; + } + + virQEMUCapsSet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI); + + if (qemuTestCapsCacheInsert(driver.qemuCapsCache, qemuCaps) < 0) { + ret = -1; + goto cleanup; + }; + DO_TEST("pc-hardlimit", 2147483648); DO_TEST("pc-locked", VIR_DOMAIN_MEMORY_PARAM_UNLIMITED); DO_TEST("pc-hostdev", 2147483648); @@ -116,10 +128,6 @@ mymain(void) DO_TEST("pc-locked+hostdev", VIR_DOMAIN_MEMORY_PARAM_UNLIMITED); qemuTestSetHostArch(&driver, VIR_ARCH_PPC64); - if (!(qemuCaps = virQEMUCapsNew())) { - ret = -1; - goto cleanup; - } virQEMUCapsSet(qemuCaps, QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE); if (qemuTestCapsCacheInsert(driver.qemuCapsCache, qemuCaps) < 0) { diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 855784e77a23759376560167abaec32a513c5995..daf5431baf0265e47331a9380ee1c19b5937c9dc 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1638,9 +1638,9 @@ mymain(void) QEMU_CAPS_DEVICE_VFIO_CCW); DO_TEST_CAPS_ARCH_LATEST("hostdev-subsys-mdev-vfio-ccw-boot", "s390x"); - DO_TEST_FAILURE("hostdev-subsys-mdev-vfio-ccw", - QEMU_CAPS_CCW, - QEMU_CAPS_CCW_CSSID_UNRESTRICTED); + DO_TEST_PARSE_ERROR("hostdev-subsys-mdev-vfio-ccw", + QEMU_CAPS_CCW, + QEMU_CAPS_CCW_CSSID_UNRESTRICTED); DO_TEST_PARSE_ERROR("hostdev-subsys-mdev-vfio-ccw-duplicate-address", QEMU_CAPS_CCW, QEMU_CAPS_CCW_CSSID_UNRESTRICTED, diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 5c526237703d59c5df96f35e04d525c0a5b84c8c..17519b865798f4da7836e29e183fb006b7726009 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -405,7 +405,7 @@ mymain(void) DO_TEST("net-virtio-rxtxqueuesize", NONE); DO_TEST("net-hostdev", NONE); DO_TEST("net-hostdev-bootorder", NONE); - DO_TEST("net-hostdev-vfio", NONE); + DO_TEST("net-hostdev-vfio", QEMU_CAPS_DEVICE_VFIO_PCI); DO_TEST("net-midonet", NONE); DO_TEST("net-openvswitch", NONE); DO_TEST("sound", NONE); @@ -432,9 +432,10 @@ mymain(void) DO_TEST("hostdev-usb-address", NONE); DO_TEST("hostdev-pci-address", NONE); - DO_TEST("hostdev-pci-multifunction", NONE); - DO_TEST("hostdev-vfio", NONE); + DO_TEST("hostdev-pci-multifunction", QEMU_CAPS_DEVICE_VFIO_PCI); + DO_TEST("hostdev-vfio", QEMU_CAPS_DEVICE_VFIO_PCI); DO_TEST("hostdev-vfio-zpci", + QEMU_CAPS_DEVICE_VFIO_PCI, QEMU_CAPS_DEVICE_ZPCI, QEMU_CAPS_CCW); DO_TEST("hostdev-vfio-zpci-multidomain-many", @@ -448,10 +449,11 @@ mymain(void) QEMU_CAPS_DEVICE_VFIO_PCI, QEMU_CAPS_DEVICE_PCI_BRIDGE, QEMU_CAPS_DEVICE_ZPCI); - DO_TEST("hostdev-mdev-precreated", NONE); + DO_TEST("hostdev-mdev-precreated", QEMU_CAPS_DEVICE_VFIO_PCI); DO_TEST("hostdev-mdev-display", QEMU_CAPS_DEVICE_QXL, - QEMU_CAPS_VFIO_PCI_DISPLAY); + QEMU_CAPS_VFIO_PCI_DISPLAY, + QEMU_CAPS_DEVICE_VFIO_PCI); DO_TEST("pci-rom", NONE); DO_TEST("pci-rom-disabled", NONE); DO_TEST("pci-rom-disabled-invalid", NONE);