This will allow to move qemuDomainDeviceDefValidate() itself in the next patch in a cleaner way. Signed-off-by: Daniel Henrique Barboza <danielhb413@xxxxxxxxx> --- src/qemu/qemu_domain.c | 392 +-------------------------------------- src/qemu/qemu_validate.c | 376 +++++++++++++++++++++++++++++++++++++ src/qemu/qemu_validate.h | 21 +++ 3 files changed, 405 insertions(+), 384 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index ddcc0551db..3ab2bfe879 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -5007,75 +5007,6 @@ qemuDomainDefPostParse(virDomainDefPtr def, } -static int -qemuDomainDeviceDefValidateNVRAM(virDomainNVRAMDefPtr nvram, - const virDomainDef *def, - virQEMUCapsPtr qemuCaps) -{ - if (!nvram) - return 0; - - if (qemuDomainIsPSeries(def)) { - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_NVRAM)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("nvram device is not supported by " - "this QEMU binary")); - return -1; - } - } else { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("nvram device is only supported for PPC64")); - return -1; - } - - if (!(nvram->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO && - nvram->info.addr.spaprvio.has_reg)) { - - virReportError(VIR_ERR_XML_ERROR, "%s", - _("nvram address type must be spaprvio")); - return -1; - } - - return 0; -} - - -static int -qemuDomainDeviceDefValidateHub(virDomainHubDefPtr hub, - virQEMUCapsPtr qemuCaps) -{ - if (hub->type != VIR_DOMAIN_HUB_TYPE_USB) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("hub type %s not supported"), - virDomainHubTypeToString(hub->type)); - return -1; - } - - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_HUB)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("usb-hub not supported by QEMU binary")); - return -1; - } - - return 0; -} - - -static int -qemuDomainDeviceDefValidateMemory(virDomainMemoryDefPtr mem, - virQEMUCapsPtr qemuCaps) -{ - if (mem->model == VIR_DOMAIN_MEMORY_MODEL_NVDIMM && - !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_NVDIMM)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("nvdimm isn't supported by this QEMU binary")); - return -1; - } - - return 0; -} - - int qemuDomainValidateActualNetDef(const virDomainNetDef *net, virQEMUCapsPtr qemuCaps) @@ -5347,313 +5278,6 @@ qemuDomainValidateStorageSource(virStorageSourcePtr src, } -static int -qemuDomainDeviceDefValidateVsock(const virDomainVsockDef *vsock, - const virDomainDef *def, - virQEMUCapsPtr qemuCaps) -{ - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VHOST_VSOCK)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("vsock device is not supported " - "with this QEMU binary")); - return -1; - } - - if (!qemuDomainCheckCCWS390AddressSupport(def, &vsock->info, qemuCaps, - "vsock")) - return -1; - - return 0; -} - - -static int -qemuDomainDeviceDefValidateTPM(virDomainTPMDef *tpm, - const virDomainDef *def, - virQEMUCapsPtr qemuCaps) -{ - virQEMUCapsFlags flag; - - /* TPM 1.2 and 2 are not compatible, so we choose a specific version here */ - if (tpm->version == VIR_DOMAIN_TPM_VERSION_DEFAULT) - tpm->version = VIR_DOMAIN_TPM_VERSION_1_2; - - switch (tpm->version) { - case VIR_DOMAIN_TPM_VERSION_1_2: - /* TPM 1.2 + CRB do not work */ - if (tpm->type == VIR_DOMAIN_TPM_TYPE_EMULATOR && - tpm->model == VIR_DOMAIN_TPM_MODEL_CRB) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Unsupported interface %s for TPM 1.2"), - virDomainTPMModelTypeToString(tpm->model)); - return -1; - } - break; - case VIR_DOMAIN_TPM_VERSION_2_0: - case VIR_DOMAIN_TPM_VERSION_DEFAULT: - case VIR_DOMAIN_TPM_VERSION_LAST: - break; - } - - switch (tpm->type) { - case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH: - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_TPM_PASSTHROUGH)) - goto no_support; - break; - - case VIR_DOMAIN_TPM_TYPE_EMULATOR: - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_TPM_EMULATOR)) - goto no_support; - - break; - case VIR_DOMAIN_TPM_TYPE_LAST: - break; - } - - switch (tpm->model) { - case VIR_DOMAIN_TPM_MODEL_TIS: - flag = QEMU_CAPS_DEVICE_TPM_TIS; - break; - case VIR_DOMAIN_TPM_MODEL_CRB: - flag = QEMU_CAPS_DEVICE_TPM_CRB; - break; - case VIR_DOMAIN_TPM_MODEL_SPAPR: - flag = QEMU_CAPS_DEVICE_TPM_SPAPR; - break; - case VIR_DOMAIN_TPM_MODEL_LAST: - default: - virReportEnumRangeError(virDomainTPMModel, tpm->model); - return -1; - } - - if (!virQEMUCapsGet(qemuCaps, flag)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("The QEMU executable %s does not support TPM " - "model %s"), - def->emulator, - virDomainTPMModelTypeToString(tpm->model)); - return -1; - } - - return 0; - - no_support: - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("The QEMU executable %s does not support TPM " - "backend type %s"), - def->emulator, - virDomainTPMBackendTypeToString(tpm->type)); - return -1; -} - - -static int -qemuDomainDeviceDefValidateInput(const virDomainInputDef *input, - const virDomainDef *def, - virQEMUCapsPtr qemuCaps) -{ - const char *baseName; - int cap; - int ccwCap; - - if (input->bus == VIR_DOMAIN_INPUT_BUS_PS2 && !ARCH_IS_X86(def->os.arch) && - !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_I8042)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("%s is not supported by this QEMU binary"), - virDomainInputBusTypeToString(input->bus)); - return -1; - } - - if (input->bus != VIR_DOMAIN_INPUT_BUS_VIRTIO) - return 0; - - /* Only type=passthrough supports model=virtio-(non-)transitional */ - switch ((virDomainInputModel)input->model) { - case VIR_DOMAIN_INPUT_MODEL_VIRTIO_TRANSITIONAL: - case VIR_DOMAIN_INPUT_MODEL_VIRTIO_NON_TRANSITIONAL: - switch ((virDomainInputType)input->type) { - case VIR_DOMAIN_INPUT_TYPE_MOUSE: - case VIR_DOMAIN_INPUT_TYPE_TABLET: - case VIR_DOMAIN_INPUT_TYPE_KBD: - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("virtio (non-)transitional models are not " - "supported for input type=%s"), - virDomainInputTypeToString(input->type)); - return -1; - case VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH: - break; - case VIR_DOMAIN_INPUT_TYPE_LAST: - default: - virReportEnumRangeError(virDomainInputType, - input->type); - return -1; - } - break; - case VIR_DOMAIN_INPUT_MODEL_VIRTIO: - case VIR_DOMAIN_INPUT_MODEL_DEFAULT: - break; - case VIR_DOMAIN_INPUT_MODEL_LAST: - default: - virReportEnumRangeError(virDomainInputModel, - input->model); - return -1; - } - - switch ((virDomainInputType)input->type) { - case VIR_DOMAIN_INPUT_TYPE_MOUSE: - baseName = "virtio-mouse"; - cap = QEMU_CAPS_VIRTIO_MOUSE; - ccwCap = QEMU_CAPS_DEVICE_VIRTIO_MOUSE_CCW; - break; - case VIR_DOMAIN_INPUT_TYPE_TABLET: - baseName = "virtio-tablet"; - cap = QEMU_CAPS_VIRTIO_TABLET; - ccwCap = QEMU_CAPS_DEVICE_VIRTIO_TABLET_CCW; - break; - case VIR_DOMAIN_INPUT_TYPE_KBD: - baseName = "virtio-keyboard"; - cap = QEMU_CAPS_VIRTIO_KEYBOARD; - ccwCap = QEMU_CAPS_DEVICE_VIRTIO_KEYBOARD_CCW; - break; - case VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH: - baseName = "virtio-input-host"; - cap = QEMU_CAPS_VIRTIO_INPUT_HOST; - ccwCap = QEMU_CAPS_LAST; - break; - case VIR_DOMAIN_INPUT_TYPE_LAST: - default: - virReportEnumRangeError(virDomainInputType, - input->type); - return -1; - } - - if (!virQEMUCapsGet(qemuCaps, cap) || - (input->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW && - !virQEMUCapsGet(qemuCaps, ccwCap))) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("%s is not supported by this QEMU binary"), - baseName); - return -1; - } - - return 0; -} - - -static int -qemuDomainDeviceDefValidateMemballoon(const virDomainMemballoonDef *memballoon, - virQEMUCapsPtr qemuCaps) -{ - if (!memballoon || - memballoon->model == VIR_DOMAIN_MEMBALLOON_MODEL_NONE) { - return 0; - } - - if (memballoon->model != VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO && - memballoon->model != VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO_TRANSITIONAL && - memballoon->model != VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO_NON_TRANSITIONAL) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Memory balloon device type '%s' is not supported by this version of qemu"), - virDomainMemballoonModelTypeToString(memballoon->model)); - return -1; - } - - if (memballoon->autodeflate != VIR_TRISTATE_SWITCH_ABSENT && - !virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_BALLOON_AUTODEFLATE)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("deflate-on-oom is not supported by this QEMU binary")); - return -1; - } - - return 0; -} - - -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; - } - break; - - case VIR_DOMAIN_IOMMU_MODEL_SMMUV3: - if (!qemuDomainIsARMVirt(def)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("IOMMU device: '%s' is only supported with " - "ARM Virt machines"), - virDomainIOMMUModelTypeToString(iommu->model)); - return -1; - } - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_VIRT_IOMMU)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("IOMMU device: '%s' is not supported with " - "this QEMU binary"), - virDomainIOMMUModelTypeToString(iommu->model)); - return -1; - } - break; - - case VIR_DOMAIN_IOMMU_MODEL_LAST: - default: - virReportEnumRangeError(virDomainIOMMUModel, iommu->model); - return -1; - } - - /* These capability checks ensure we're not trying to use features - * of Intel IOMMU that the QEMU binary does not support, but they - * also make sure we report an error when trying to use features - * that are not implemented by SMMUv3 */ - - 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; - } - - return 0; -} - - static int qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev, const virDomainDef *def, @@ -5724,11 +5348,11 @@ qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev, break; case VIR_DOMAIN_DEVICE_VSOCK: - ret = qemuDomainDeviceDefValidateVsock(dev->data.vsock, def, qemuCaps); + ret = qemuValidateDomainDeviceDefVsock(dev->data.vsock, def, qemuCaps); break; case VIR_DOMAIN_DEVICE_TPM: - ret = qemuDomainDeviceDefValidateTPM(dev->data.tpm, def, qemuCaps); + ret = qemuValidateDomainDeviceDefTPM(dev->data.tpm, def, qemuCaps); break; case VIR_DOMAIN_DEVICE_GRAPHICS: @@ -5737,15 +5361,15 @@ qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev, break; case VIR_DOMAIN_DEVICE_INPUT: - ret = qemuDomainDeviceDefValidateInput(dev->data.input, def, qemuCaps); + ret = qemuValidateDomainDeviceDefInput(dev->data.input, def, qemuCaps); break; case VIR_DOMAIN_DEVICE_MEMBALLOON: - ret = qemuDomainDeviceDefValidateMemballoon(dev->data.memballoon, qemuCaps); + ret = qemuValidateDomainDeviceDefMemballoon(dev->data.memballoon, qemuCaps); break; case VIR_DOMAIN_DEVICE_IOMMU: - ret = qemuDomainDeviceDefValidateIOMMU(dev->data.iommu, def, qemuCaps); + ret = qemuValidateDomainDeviceDefIOMMU(dev->data.iommu, def, qemuCaps); break; case VIR_DOMAIN_DEVICE_FS: @@ -5753,11 +5377,11 @@ qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev, break; case VIR_DOMAIN_DEVICE_NVRAM: - ret = qemuDomainDeviceDefValidateNVRAM(dev->data.nvram, def, qemuCaps); + ret = qemuValidateDomainDeviceDefNVRAM(dev->data.nvram, def, qemuCaps); break; case VIR_DOMAIN_DEVICE_HUB: - ret = qemuDomainDeviceDefValidateHub(dev->data.hub, qemuCaps); + ret = qemuValidateDomainDeviceDefHub(dev->data.hub, qemuCaps); break; case VIR_DOMAIN_DEVICE_SOUND: @@ -5765,7 +5389,7 @@ qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev, break; case VIR_DOMAIN_DEVICE_MEMORY: - ret = qemuDomainDeviceDefValidateMemory(dev->data.memory, qemuCaps); + ret = qemuValidateDomainDeviceDefMemory(dev->data.memory, qemuCaps); break; case VIR_DOMAIN_DEVICE_LEASE: diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 58ed2512d4..6c772093de 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -3088,3 +3088,379 @@ qemuValidateDomainDeviceDefSound(virDomainSoundDefPtr sound, return 0; } + + +int +qemuValidateDomainDeviceDefVsock(const virDomainVsockDef *vsock, + const virDomainDef *def, + virQEMUCapsPtr qemuCaps) +{ + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VHOST_VSOCK)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("vsock device is not supported " + "with this QEMU binary")); + return -1; + } + + if (!qemuDomainCheckCCWS390AddressSupport(def, &vsock->info, qemuCaps, + "vsock")) + return -1; + + return 0; +} + + +int +qemuValidateDomainDeviceDefTPM(virDomainTPMDef *tpm, + const virDomainDef *def, + virQEMUCapsPtr qemuCaps) +{ + virQEMUCapsFlags flag; + + /* TPM 1.2 and 2 are not compatible, so we choose a specific version here */ + if (tpm->version == VIR_DOMAIN_TPM_VERSION_DEFAULT) + tpm->version = VIR_DOMAIN_TPM_VERSION_1_2; + + switch (tpm->version) { + case VIR_DOMAIN_TPM_VERSION_1_2: + /* TPM 1.2 + CRB do not work */ + if (tpm->type == VIR_DOMAIN_TPM_TYPE_EMULATOR && + tpm->model == VIR_DOMAIN_TPM_MODEL_CRB) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Unsupported interface %s for TPM 1.2"), + virDomainTPMModelTypeToString(tpm->model)); + return -1; + } + break; + case VIR_DOMAIN_TPM_VERSION_2_0: + case VIR_DOMAIN_TPM_VERSION_DEFAULT: + case VIR_DOMAIN_TPM_VERSION_LAST: + break; + } + + switch (tpm->type) { + case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH: + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_TPM_PASSTHROUGH)) + goto no_support; + break; + + case VIR_DOMAIN_TPM_TYPE_EMULATOR: + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_TPM_EMULATOR)) + goto no_support; + + break; + case VIR_DOMAIN_TPM_TYPE_LAST: + break; + } + + switch (tpm->model) { + case VIR_DOMAIN_TPM_MODEL_TIS: + flag = QEMU_CAPS_DEVICE_TPM_TIS; + break; + case VIR_DOMAIN_TPM_MODEL_CRB: + flag = QEMU_CAPS_DEVICE_TPM_CRB; + break; + case VIR_DOMAIN_TPM_MODEL_SPAPR: + flag = QEMU_CAPS_DEVICE_TPM_SPAPR; + break; + case VIR_DOMAIN_TPM_MODEL_LAST: + default: + virReportEnumRangeError(virDomainTPMModel, tpm->model); + return -1; + } + + if (!virQEMUCapsGet(qemuCaps, flag)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("The QEMU executable %s does not support TPM " + "model %s"), + def->emulator, + virDomainTPMModelTypeToString(tpm->model)); + return -1; + } + + return 0; + + no_support: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("The QEMU executable %s does not support TPM " + "backend type %s"), + def->emulator, + virDomainTPMBackendTypeToString(tpm->type)); + return -1; +} + + +int +qemuValidateDomainDeviceDefInput(const virDomainInputDef *input, + const virDomainDef *def, + virQEMUCapsPtr qemuCaps) +{ + const char *baseName; + int cap; + int ccwCap; + + if (input->bus == VIR_DOMAIN_INPUT_BUS_PS2 && !ARCH_IS_X86(def->os.arch) && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_I8042)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("%s is not supported by this QEMU binary"), + virDomainInputBusTypeToString(input->bus)); + return -1; + } + + if (input->bus != VIR_DOMAIN_INPUT_BUS_VIRTIO) + return 0; + + /* Only type=passthrough supports model=virtio-(non-)transitional */ + switch ((virDomainInputModel)input->model) { + case VIR_DOMAIN_INPUT_MODEL_VIRTIO_TRANSITIONAL: + case VIR_DOMAIN_INPUT_MODEL_VIRTIO_NON_TRANSITIONAL: + switch ((virDomainInputType)input->type) { + case VIR_DOMAIN_INPUT_TYPE_MOUSE: + case VIR_DOMAIN_INPUT_TYPE_TABLET: + case VIR_DOMAIN_INPUT_TYPE_KBD: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("virtio (non-)transitional models are not " + "supported for input type=%s"), + virDomainInputTypeToString(input->type)); + return -1; + case VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH: + break; + case VIR_DOMAIN_INPUT_TYPE_LAST: + default: + virReportEnumRangeError(virDomainInputType, + input->type); + return -1; + } + break; + case VIR_DOMAIN_INPUT_MODEL_VIRTIO: + case VIR_DOMAIN_INPUT_MODEL_DEFAULT: + break; + case VIR_DOMAIN_INPUT_MODEL_LAST: + default: + virReportEnumRangeError(virDomainInputModel, + input->model); + return -1; + } + + switch ((virDomainInputType)input->type) { + case VIR_DOMAIN_INPUT_TYPE_MOUSE: + baseName = "virtio-mouse"; + cap = QEMU_CAPS_VIRTIO_MOUSE; + ccwCap = QEMU_CAPS_DEVICE_VIRTIO_MOUSE_CCW; + break; + case VIR_DOMAIN_INPUT_TYPE_TABLET: + baseName = "virtio-tablet"; + cap = QEMU_CAPS_VIRTIO_TABLET; + ccwCap = QEMU_CAPS_DEVICE_VIRTIO_TABLET_CCW; + break; + case VIR_DOMAIN_INPUT_TYPE_KBD: + baseName = "virtio-keyboard"; + cap = QEMU_CAPS_VIRTIO_KEYBOARD; + ccwCap = QEMU_CAPS_DEVICE_VIRTIO_KEYBOARD_CCW; + break; + case VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH: + baseName = "virtio-input-host"; + cap = QEMU_CAPS_VIRTIO_INPUT_HOST; + ccwCap = QEMU_CAPS_LAST; + break; + case VIR_DOMAIN_INPUT_TYPE_LAST: + default: + virReportEnumRangeError(virDomainInputType, + input->type); + return -1; + } + + if (!virQEMUCapsGet(qemuCaps, cap) || + (input->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW && + !virQEMUCapsGet(qemuCaps, ccwCap))) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("%s is not supported by this QEMU binary"), + baseName); + return -1; + } + + return 0; +} + + +int +qemuValidateDomainDeviceDefMemballoon(const virDomainMemballoonDef *memballoon, + virQEMUCapsPtr qemuCaps) +{ + if (!memballoon || + memballoon->model == VIR_DOMAIN_MEMBALLOON_MODEL_NONE) { + return 0; + } + + if (memballoon->model != VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO && + memballoon->model != VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO_TRANSITIONAL && + memballoon->model != VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO_NON_TRANSITIONAL) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Memory balloon device type '%s' is not supported by this version of qemu"), + virDomainMemballoonModelTypeToString(memballoon->model)); + return -1; + } + + if (memballoon->autodeflate != VIR_TRISTATE_SWITCH_ABSENT && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_BALLOON_AUTODEFLATE)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("deflate-on-oom is not supported by this QEMU binary")); + return -1; + } + + return 0; +} + + +int +qemuValidateDomainDeviceDefIOMMU(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; + } + break; + + case VIR_DOMAIN_IOMMU_MODEL_SMMUV3: + if (!qemuDomainIsARMVirt(def)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("IOMMU device: '%s' is only supported with " + "ARM Virt machines"), + virDomainIOMMUModelTypeToString(iommu->model)); + return -1; + } + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_VIRT_IOMMU)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("IOMMU device: '%s' is not supported with " + "this QEMU binary"), + virDomainIOMMUModelTypeToString(iommu->model)); + return -1; + } + break; + + case VIR_DOMAIN_IOMMU_MODEL_LAST: + default: + virReportEnumRangeError(virDomainIOMMUModel, iommu->model); + return -1; + } + + /* These capability checks ensure we're not trying to use features + * of Intel IOMMU that the QEMU binary does not support, but they + * also make sure we report an error when trying to use features + * that are not implemented by SMMUv3 */ + + 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; + } + + return 0; +} + + +int +qemuValidateDomainDeviceDefNVRAM(virDomainNVRAMDefPtr nvram, + const virDomainDef *def, + virQEMUCapsPtr qemuCaps) +{ + if (!nvram) + return 0; + + if (qemuDomainIsPSeries(def)) { + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_NVRAM)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("nvram device is not supported by " + "this QEMU binary")); + return -1; + } + } else { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("nvram device is only supported for PPC64")); + return -1; + } + + if (!(nvram->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO && + nvram->info.addr.spaprvio.has_reg)) { + + virReportError(VIR_ERR_XML_ERROR, "%s", + _("nvram address type must be spaprvio")); + return -1; + } + + return 0; +} + + +int +qemuValidateDomainDeviceDefHub(virDomainHubDefPtr hub, + virQEMUCapsPtr qemuCaps) +{ + if (hub->type != VIR_DOMAIN_HUB_TYPE_USB) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("hub type %s not supported"), + virDomainHubTypeToString(hub->type)); + return -1; + } + + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_HUB)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("usb-hub not supported by QEMU binary")); + return -1; + } + + return 0; +} + + +int +qemuValidateDomainDeviceDefMemory(virDomainMemoryDefPtr mem, + virQEMUCapsPtr qemuCaps) +{ + if (mem->model == VIR_DOMAIN_MEMORY_MODEL_NVDIMM && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_NVDIMM)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("nvdimm isn't supported by this QEMU binary")); + return -1; + } + + return 0; +} diff --git a/src/qemu/qemu_validate.h b/src/qemu/qemu_validate.h index e61a932809..ac4eb9b772 100644 --- a/src/qemu/qemu_validate.h +++ b/src/qemu/qemu_validate.h @@ -62,3 +62,24 @@ int qemuValidateDomainDeviceDefFS(virDomainFSDefPtr fs, virQEMUCapsPtr qemuCaps); int qemuValidateDomainDeviceDefSound(virDomainSoundDefPtr sound, virQEMUCapsPtr qemuCaps); +int qemuValidateDomainDeviceDefVsock(const virDomainVsockDef *vsock, + const virDomainDef *def, + virQEMUCapsPtr qemuCaps); +int qemuValidateDomainDeviceDefTPM(virDomainTPMDef *tpm, + const virDomainDef *def, + virQEMUCapsPtr qemuCaps); +int qemuValidateDomainDeviceDefInput(const virDomainInputDef *input, + const virDomainDef *def, + virQEMUCapsPtr qemuCaps); +int qemuValidateDomainDeviceDefMemballoon(const virDomainMemballoonDef *memballoon, + virQEMUCapsPtr qemuCaps); +int qemuValidateDomainDeviceDefIOMMU(const virDomainIOMMUDef *iommu, + const virDomainDef *def, + virQEMUCapsPtr qemuCaps); +int qemuValidateDomainDeviceDefMemory(virDomainMemoryDefPtr mem, + virQEMUCapsPtr qemuCaps); +int qemuValidateDomainDeviceDefHub(virDomainHubDefPtr hub, + virQEMUCapsPtr qemuCaps); +int qemuValidateDomainDeviceDefNVRAM(virDomainNVRAMDefPtr nvram, + const virDomainDef *def, + virQEMUCapsPtr qemuCaps); -- 2.25.1