From a7a78c273e04103e10ab9f7d3e555d06b6dc3ce5 Mon Sep 17 00:00:00 2001 From: Andrea Bolognani Date: Fri, 17 May 2019 13:37:35 +0200 Subject: [PATCH] qemu: Introduce qemuDomainDeviceDefValidateIOMMU() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Device validation should not have to wait until command line generation time. Moving the code to a separate function also allows us to avoid some unnecessary repetition. Signed-off-by: Andrea Bolognani Reviewed-by: Ján Tomko --- src/qemu/qemu_command.c | 56 ---------------------------------- src/qemu/qemu_domain.c | 66 +++++++++++++++++++++++++++++++++++++++- tests/qemuxml2argvtest.c | 2 +- 3 files changed, 66 insertions(+), 58 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index aae2f43044..e16c748d31 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6935,60 +6935,11 @@ qemuBuildIOMMUCommandLine(virCommandPtr cmd, if (!iommu) return 0; - switch (iommu->model) { - case VIR_DOMAIN_IOMMU_MODEL_INTEL: - if (iommu->intremap != VIR_TRISTATE_SWITCH_ABSENT && - !virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_INTREMAP)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("iommu: interrupt remapping is not supported " - "with this QEMU binary")); - return -1; - } - if (iommu->caching_mode != VIR_TRISTATE_SWITCH_ABSENT && - !virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_CACHING_MODE)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("iommu: caching mode is not supported " - "with this QEMU binary")); - return -1; - } - if (iommu->eim != VIR_TRISTATE_SWITCH_ABSENT && - !virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_EIM)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("iommu: eim is not supported " - "with this QEMU binary")); - return -1; - } - if (iommu->iotlb != VIR_TRISTATE_SWITCH_ABSENT && - !virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_DEVICE_IOTLB)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("iommu: device IOTLB is not supported " - "with this QEMU binary")); - return -1; - } - break; - case VIR_DOMAIN_IOMMU_MODEL_LAST: - break; - } - if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_IOMMU)) return 0; /* Already handled via -machine */ switch (iommu->model) { case VIR_DOMAIN_IOMMU_MODEL_INTEL: - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_INTEL_IOMMU)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("IOMMU device: '%s' is not supported with " - "this QEMU binary"), - virDomainIOMMUModelTypeToString(iommu->model)); - return -1; - } - if (!qemuDomainIsQ35(def)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("IOMMU device: '%s' is only supported with " - "Q35 machines"), - virDomainIOMMUModelTypeToString(iommu->model)); - return -1; - } virBufferAddLit(&opts, "intel-iommu"); if (iommu->intremap != VIR_TRISTATE_SWITCH_ABSENT) { virBufferAsprintf(&opts, ",intremap=%s", @@ -7648,13 +7599,6 @@ qemuBuildMachineCommandLine(virCommandPtr cmd, virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_IOMMU)) { switch (def->iommu->model) { case VIR_DOMAIN_IOMMU_MODEL_INTEL: - if (!qemuDomainIsQ35(def)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("IOMMU device: '%s' is only supported with " - "Q35 machines"), - virDomainIOMMUModelTypeToString(def->iommu->model)); - return -1; - } virBufferAddLit(&buf, ",iommu=on"); break; case VIR_DOMAIN_IOMMU_MODEL_LAST: diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 3290c5d490..e50e84a3b2 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -6083,6 +6083,67 @@ qemuDomainDeviceDefValidateMemballoon(const virDomainMemballoonDef *memballoon, } +static int +qemuDomainDeviceDefValidateIOMMU(const virDomainIOMMUDef *iommu, + const virDomainDef *def, + virQEMUCapsPtr qemuCaps) +{ + switch (iommu->model) { + case VIR_DOMAIN_IOMMU_MODEL_INTEL: + if (!qemuDomainIsQ35(def)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("IOMMU device: '%s' is only supported with " + "Q35 machines"), + virDomainIOMMUModelTypeToString(iommu->model)); + return -1; + } + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_INTEL_IOMMU) && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_IOMMU)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("IOMMU device: '%s' is not supported with " + "this QEMU binary"), + virDomainIOMMUModelTypeToString(iommu->model)); + return -1; + } + if (iommu->intremap != VIR_TRISTATE_SWITCH_ABSENT && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_INTREMAP)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("iommu: interrupt remapping is not supported " + "with this QEMU binary")); + return -1; + } + if (iommu->caching_mode != VIR_TRISTATE_SWITCH_ABSENT && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_CACHING_MODE)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("iommu: caching mode is not supported " + "with this QEMU binary")); + return -1; + } + if (iommu->eim != VIR_TRISTATE_SWITCH_ABSENT && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_EIM)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("iommu: eim is not supported " + "with this QEMU binary")); + return -1; + } + if (iommu->iotlb != VIR_TRISTATE_SWITCH_ABSENT && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_DEVICE_IOTLB)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("iommu: device IOTLB is not supported " + "with this QEMU binary")); + return -1; + } + break; + + case VIR_DOMAIN_IOMMU_MODEL_LAST: + default: + virReportEnumRangeError(virDomainIOMMUModel, iommu->model); + } + + return 0; +} + + static int qemuDomainDeviceDefValidateZPCIAddress(virDomainDeviceInfoPtr info, virQEMUCapsPtr qemuCaps) @@ -6195,6 +6256,10 @@ qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev, ret = qemuDomainDeviceDefValidateMemballoon(dev->data.memballoon, qemuCaps); break; + case VIR_DOMAIN_DEVICE_IOMMU: + ret = qemuDomainDeviceDefValidateIOMMU(dev->data.iommu, def, qemuCaps); + break; + case VIR_DOMAIN_DEVICE_LEASE: case VIR_DOMAIN_DEVICE_FS: case VIR_DOMAIN_DEVICE_SOUND: @@ -6203,7 +6268,6 @@ qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev, case VIR_DOMAIN_DEVICE_SHMEM: case VIR_DOMAIN_DEVICE_MEMORY: case VIR_DOMAIN_DEVICE_PANIC: - case VIR_DOMAIN_DEVICE_IOMMU: case VIR_DOMAIN_DEVICE_NONE: case VIR_DOMAIN_DEVICE_LAST: break; diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index de74aa91fe..ec58074798 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -2812,7 +2812,7 @@ mymain(void) DO_TEST_CAPS_LATEST("intel-iommu-caching-mode"); DO_TEST_CAPS_LATEST("intel-iommu-eim"); DO_TEST_CAPS_LATEST("intel-iommu-device-iotlb"); - DO_TEST_FAILURE("intel-iommu-wrong-machine", NONE); + DO_TEST_PARSE_ERROR("intel-iommu-wrong-machine", NONE); DO_TEST("cpu-hotplug-startup", QEMU_CAPS_QUERY_HOTPLUGGABLE_CPUS); DO_TEST_PARSE_ERROR("cpu-hotplug-granularity",