While moving validations from qemu_command to qemu_domain,
it was suggested that we should instead move them to a new
file [1] because qemu_domain is already too crowded.
This patch introduces a new file to host such validations from
the QEMU driver. And to get things started, let's move
qemuDomainDefValidateFeatures() to this new file.
Signed-off-by: Daniel Henrique Barboza <danielhb413(a)gmail.com>
---
po/POTFILES.in | 1 +
src/qemu/Makefile.inc.am | 2 +
src/qemu/qemu_domain.c | 286 +-----------------------------------
src/qemu/qemu_validate.c | 310 +++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_validate.h | 29 ++++
5 files changed, 344 insertions(+), 284 deletions(-)
create mode 100644 src/qemu/qemu_validate.c
create mode 100644 src/qemu/qemu_validate.h
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 6103d4ca4a..c60f355f7f 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -170,6 +170,7 @@
@SRCDIR(a)/src/qemu/qemu_qapi.c
@SRCDIR(a)/src/qemu/qemu_slirp.c
@SRCDIR(a)/src/qemu/qemu_tpm.c
+@SRCDIR(a)/src/qemu/qemu_validate.c
@SRCDIR(a)/src/qemu/qemu_vhost_user.c
@SRCDIR(a)/src/qemu/qemu_vhost_user_gpu.c
@SRCDIR(a)/src/qemu/qemu_virtiofs.c
diff --git a/src/qemu/Makefile.inc.am b/src/qemu/Makefile.inc.am
index 51cd79879d..1291b07124 100644
--- a/src/qemu/Makefile.inc.am
+++ b/src/qemu/Makefile.inc.am
@@ -73,6 +73,8 @@ QEMU_DRIVER_SOURCES = \
qemu/qemu_checkpoint.h \
qemu/qemu_backup.c \
qemu/qemu_backup.h \
+ qemu/qemu_validate.c \
+ qemu/qemu_validate.h \
$(NULL)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 7d29f3f114..c4f36b000b 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -36,6 +36,7 @@
#include "qemu_extdevice.h"
#include "qemu_blockjob.h"
#include "qemu_checkpoint.h"
+#include "qemu_validate.h"
#include "viralloc.h"
#include "virlog.h"
#include "virerror.h"
@@ -5039,289 +5040,6 @@ qemuDomainDefGetVcpuHotplugGranularity(const virDomainDef *def)
#define QEMU_MAX_VCPUS_WITHOUT_EIM 255
-static int
-qemuDomainDefValidatePSeriesFeature(const virDomainDef *def,
- virQEMUCapsPtr qemuCaps,
- int feature)
-{
- const char *str;
-
- if (def->features[feature] != VIR_TRISTATE_SWITCH_ABSENT &&
- !qemuDomainIsPSeries(def)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("The '%s' feature is not supported for "
- "architecture '%s' or machine type
'%s'"),
- virDomainFeatureTypeToString(feature),
- virArchToString(def->os.arch),
- def->os.machine);
- return -1;
- }
-
- if (def->features[feature] == VIR_TRISTATE_SWITCH_ABSENT)
- return 0;
-
- switch (feature) {
- case VIR_DOMAIN_FEATURE_HPT:
- if (def->features[feature] != VIR_TRISTATE_SWITCH_ON)
- break;
-
- if (def->hpt_resizing != VIR_DOMAIN_HPT_RESIZING_NONE) {
- if (!virQEMUCapsGet(qemuCaps,
- QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("HTP resizing is not supported by this "
- "QEMU binary"));
- return -1;
- }
-
- str = virDomainHPTResizingTypeToString(def->hpt_resizing);
- if (!str) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("Invalid setting for HPT resizing"));
- return -1;
- }
- }
-
- if (def->hpt_maxpagesize > 0 &&
- !virQEMUCapsGet(qemuCaps,
- QEMU_CAPS_MACHINE_PSERIES_CAP_HPT_MAX_PAGE_SIZE)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("Configuring the page size for HPT guests "
- "is not supported by this QEMU binary"));
- return -1;
- }
- break;
-
- case VIR_DOMAIN_FEATURE_HTM:
- if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_PSERIES_CAP_HTM)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("HTM configuration is not supported by this "
- "QEMU binary"));
- return -1;
- }
-
- str = virTristateSwitchTypeToString(def->features[feature]);
- if (!str) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("Invalid setting for HTM state"));
- return -1;
- }
-
- break;
-
- case VIR_DOMAIN_FEATURE_NESTED_HV:
- if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("Nested HV configuration is not supported by "
- "this QEMU binary"));
- return -1;
- }
-
- str = virTristateSwitchTypeToString(def->features[feature]);
- if (!str) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("Invalid setting for nested HV state"));
- return -1;
- }
-
- break;
-
- case VIR_DOMAIN_FEATURE_CCF_ASSIST:
- if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("ccf-assist configuration is not supported by "
- "this QEMU binary"));
- return -1;
- }
-
- str = virTristateSwitchTypeToString(def->features[feature]);
- if (!str) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("Invalid setting for ccf-assist state"));
- return -1;
- }
-
- break;
- }
-
- return 0;
-}
-
-static int
-qemuDomainDefValidateFeatures(const virDomainDef *def,
- virQEMUCapsPtr qemuCaps)
-{
- size_t i;
-
- for (i = 0; i < VIR_DOMAIN_FEATURE_LAST; i++) {
- const char *featureName = virDomainFeatureTypeToString(i);
-
- switch ((virDomainFeature) i) {
- case VIR_DOMAIN_FEATURE_IOAPIC:
- if (def->features[i] != VIR_DOMAIN_IOAPIC_NONE) {
- if (!ARCH_IS_X86(def->os.arch)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("The '%s' feature is not supported for
"
- "architecture '%s' or machine type
'%s'"),
- featureName,
- virArchToString(def->os.arch),
- def->os.machine);
- return -1;
- }
-
- if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_KERNEL_IRQCHIP)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("I/O APIC tuning is not supported by "
- "this QEMU binary"));
- return -1;
- }
-
- switch ((virDomainIOAPIC) def->features[i]) {
- case VIR_DOMAIN_IOAPIC_QEMU:
- if (!virQEMUCapsGet(qemuCaps,
- QEMU_CAPS_MACHINE_KERNEL_IRQCHIP_SPLIT)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("split I/O APIC is not supported by this
"
- "QEMU binary"));
- return -1;
- }
- break;
- case VIR_DOMAIN_IOAPIC_KVM:
- case VIR_DOMAIN_IOAPIC_NONE:
- case VIR_DOMAIN_IOAPIC_LAST:
- break;
- }
- }
- break;
-
- case VIR_DOMAIN_FEATURE_HPT:
- case VIR_DOMAIN_FEATURE_HTM:
- case VIR_DOMAIN_FEATURE_NESTED_HV:
- case VIR_DOMAIN_FEATURE_CCF_ASSIST:
- if (qemuDomainDefValidatePSeriesFeature(def, qemuCaps, i) < 0)
- return -1;
- break;
-
- case VIR_DOMAIN_FEATURE_GIC:
- if (def->features[i] == VIR_TRISTATE_SWITCH_ON &&
- !qemuDomainIsARMVirt(def)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("The '%s' feature is not supported for
"
- "architecture '%s' or machine type
'%s'"),
- featureName,
- virArchToString(def->os.arch),
- def->os.machine);
- return -1;
- }
- break;
-
- case VIR_DOMAIN_FEATURE_SMM:
- if (def->features[i] != VIR_TRISTATE_SWITCH_ABSENT &&
- !virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_SMM_OPT)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("smm is not available with this QEMU
binary"));
- return -1;
- }
- break;
-
- case VIR_DOMAIN_FEATURE_KVM:
- if (def->kvm_features[VIR_DOMAIN_KVM_DEDICATED] == VIR_TRISTATE_SWITCH_ON
&&
- (!def->cpu || def->cpu->mode != VIR_CPU_MODE_HOST_PASSTHROUGH))
{
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("kvm-hint-dedicated=on is only applicable "
- "for cpu host-passthrough"));
- return -1;
- }
- break;
-
- case VIR_DOMAIN_FEATURE_VMPORT:
- if (def->features[i] != VIR_TRISTATE_SWITCH_ABSENT &&
- !virQEMUCapsSupportsVmport(qemuCaps, def)) {
-
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("vmport is not available "
- "with this QEMU binary"));
- return -1;
- }
- break;
-
- case VIR_DOMAIN_FEATURE_VMCOREINFO:
- if (def->features[i] == VIR_TRISTATE_SWITCH_ON &&
- !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VMCOREINFO)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("vmcoreinfo is not available "
- "with this QEMU binary"));
- return -1;
- }
- break;
-
- case VIR_DOMAIN_FEATURE_APIC:
- /* The kvm_pv_eoi feature is x86-only. */
- if (def->features[i] != VIR_TRISTATE_SWITCH_ABSENT &&
- def->apic_eoi != VIR_TRISTATE_SWITCH_ABSENT &&
- !ARCH_IS_X86(def->os.arch)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("The 'eoi' attribute of the '%s'
feature "
- "is not supported for architecture '%s' or
"
- "machine type '%s'"),
- featureName,
- virArchToString(def->os.arch),
- def->os.machine);
- return -1;
- }
- break;
-
- case VIR_DOMAIN_FEATURE_PVSPINLOCK:
- if (def->features[i] != VIR_TRISTATE_SWITCH_ABSENT &&
- !ARCH_IS_X86(def->os.arch)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("The '%s' feature is not supported for
"
- "architecture '%s' or machine type
'%s'"),
- featureName,
- virArchToString(def->os.arch),
- def->os.machine);
- return -1;
- }
- break;
-
- case VIR_DOMAIN_FEATURE_HYPERV:
- if (def->features[i] != VIR_TRISTATE_SWITCH_ABSENT &&
- !ARCH_IS_X86(def->os.arch) && !qemuDomainIsARMVirt(def)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("Hyperv features are not supported for "
- "architecture '%s' or machine type
'%s'"),
- virArchToString(def->os.arch),
- def->os.machine);
- return -1;
- }
- break;
-
- case VIR_DOMAIN_FEATURE_PMU:
- if (def->features[i] == VIR_TRISTATE_SWITCH_OFF &&
- ARCH_IS_PPC64(def->os.arch)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("PMU is always enabled for architecture
'%s'"),
- virArchToString(def->os.arch));
- return -1;
- }
- break;
-
- case VIR_DOMAIN_FEATURE_ACPI:
- case VIR_DOMAIN_FEATURE_PAE:
- case VIR_DOMAIN_FEATURE_HAP:
- case VIR_DOMAIN_FEATURE_VIRIDIAN:
- case VIR_DOMAIN_FEATURE_PRIVNET:
- case VIR_DOMAIN_FEATURE_CAPABILITIES:
- case VIR_DOMAIN_FEATURE_MSRS:
- case VIR_DOMAIN_FEATURE_LAST:
- break;
- }
- }
-
- return 0;
-}
-
-
static int
qemuDomainDefValidateMemory(const virDomainDef *def,
virQEMUCapsPtr qemuCaps)
@@ -6036,7 +5754,7 @@ qemuDomainDefValidate(const virDomainDef *def,
return -1;
}
- if (qemuDomainDefValidateFeatures(def, qemuCaps) < 0)
+ if (qemuValidateDomainDefFeatures(def, qemuCaps) < 0)
return -1;
if (qemuDomainDefValidateMemory(def, qemuCaps) < 0)
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
new file mode 100644
index 0000000000..8f4c5af582
--- /dev/null
+++ b/src/qemu/qemu_validate.c
@@ -0,0 +1,310 @@
+/*
+ * qemu_validate.c: QEMU general validation functions
+ *
+ * Copyright IBM Corp, 2020
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <
http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "qemu_validate.h"
+#include "qemu_domain.h"
+
+#define VIR_FROM_THIS VIR_FROM_QEMU
+
+
+static int
+qemuValidateDomainDefPSeriesFeature(const virDomainDef *def,
+ virQEMUCapsPtr qemuCaps,
+ int feature)
+{
+ const char *str;
+
+ if (def->features[feature] != VIR_TRISTATE_SWITCH_ABSENT &&
+ !qemuDomainIsPSeries(def)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("The '%s' feature is not supported for "
+ "architecture '%s' or machine type
'%s'"),
+ virDomainFeatureTypeToString(feature),
+ virArchToString(def->os.arch),
+ def->os.machine);
+ return -1;
+ }
+
+ if (def->features[feature] == VIR_TRISTATE_SWITCH_ABSENT)
+ return 0;
+
+ switch (feature) {
+ case VIR_DOMAIN_FEATURE_HPT:
+ if (def->features[feature] != VIR_TRISTATE_SWITCH_ON)
+ break;
+
+ if (def->hpt_resizing != VIR_DOMAIN_HPT_RESIZING_NONE) {
+ if (!virQEMUCapsGet(qemuCaps,
+ QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("HTP resizing is not supported by this "
+ "QEMU binary"));
+ return -1;
+ }
+
+ str = virDomainHPTResizingTypeToString(def->hpt_resizing);
+ if (!str) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Invalid setting for HPT resizing"));
+ return -1;
+ }
+ }
+
+ if (def->hpt_maxpagesize > 0 &&
+ !virQEMUCapsGet(qemuCaps,
+ QEMU_CAPS_MACHINE_PSERIES_CAP_HPT_MAX_PAGE_SIZE)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Configuring the page size for HPT guests "
+ "is not supported by this QEMU binary"));
+ return -1;
+ }
+ break;
+
+ case VIR_DOMAIN_FEATURE_HTM:
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_PSERIES_CAP_HTM)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("HTM configuration is not supported by this "
+ "QEMU binary"));
+ return -1;
+ }
+
+ str = virTristateSwitchTypeToString(def->features[feature]);
+ if (!str) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Invalid setting for HTM state"));
+ return -1;
+ }
+
+ break;
+
+ case VIR_DOMAIN_FEATURE_NESTED_HV:
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Nested HV configuration is not supported by "
+ "this QEMU binary"));
+ return -1;
+ }
+
+ str = virTristateSwitchTypeToString(def->features[feature]);
+ if (!str) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Invalid setting for nested HV state"));
+ return -1;
+ }
+
+ break;
+
+ case VIR_DOMAIN_FEATURE_CCF_ASSIST:
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("ccf-assist configuration is not supported by "
+ "this QEMU binary"));
+ return -1;
+ }
+
+ str = virTristateSwitchTypeToString(def->features[feature]);
+ if (!str) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Invalid setting for ccf-assist state"));
+ return -1;
+ }
+
+ break;
+ }
+
+ return 0;
+}
+
+
+int
+qemuValidateDomainDefFeatures(const virDomainDef *def,
+ virQEMUCapsPtr qemuCaps)
+{
+ size_t i;
+
+ for (i = 0; i < VIR_DOMAIN_FEATURE_LAST; i++) {
+ const char *featureName = virDomainFeatureTypeToString(i);
+
+ switch ((virDomainFeature) i) {
+ case VIR_DOMAIN_FEATURE_IOAPIC:
+ if (def->features[i] != VIR_DOMAIN_IOAPIC_NONE) {
+ if (!ARCH_IS_X86(def->os.arch)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("The '%s' feature is not supported for
"
+ "architecture '%s' or machine type
'%s'"),
+ featureName,
+ virArchToString(def->os.arch),
+ def->os.machine);
+ return -1;
+ }
+
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_KERNEL_IRQCHIP)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("I/O APIC tuning is not supported by "
+ "this QEMU binary"));
+ return -1;
+ }
+
+ switch ((virDomainIOAPIC) def->features[i]) {
+ case VIR_DOMAIN_IOAPIC_QEMU:
+ if (!virQEMUCapsGet(qemuCaps,
+ QEMU_CAPS_MACHINE_KERNEL_IRQCHIP_SPLIT)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("split I/O APIC is not supported by this
"
+ "QEMU binary"));
+ return -1;
+ }
+ break;
+ case VIR_DOMAIN_IOAPIC_KVM:
+ case VIR_DOMAIN_IOAPIC_NONE:
+ case VIR_DOMAIN_IOAPIC_LAST:
+ break;
+ }
+ }
+ break;
+
+ case VIR_DOMAIN_FEATURE_HPT:
+ case VIR_DOMAIN_FEATURE_HTM:
+ case VIR_DOMAIN_FEATURE_NESTED_HV:
+ case VIR_DOMAIN_FEATURE_CCF_ASSIST:
+ if (qemuValidateDomainDefPSeriesFeature(def, qemuCaps, i) < 0)
+ return -1;
+ break;
+
+ case VIR_DOMAIN_FEATURE_GIC:
+ if (def->features[i] == VIR_TRISTATE_SWITCH_ON &&
+ !qemuDomainIsARMVirt(def)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("The '%s' feature is not supported for
"
+ "architecture '%s' or machine type
'%s'"),
+ featureName,
+ virArchToString(def->os.arch),
+ def->os.machine);
+ return -1;
+ }
+ break;
+
+ case VIR_DOMAIN_FEATURE_SMM:
+ if (def->features[i] != VIR_TRISTATE_SWITCH_ABSENT &&
+ !virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_SMM_OPT)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("smm is not available with this QEMU
binary"));
+ return -1;
+ }
+ break;
+
+ case VIR_DOMAIN_FEATURE_KVM:
+ if (def->kvm_features[VIR_DOMAIN_KVM_DEDICATED] == VIR_TRISTATE_SWITCH_ON
&&
+ (!def->cpu || def->cpu->mode != VIR_CPU_MODE_HOST_PASSTHROUGH))
{
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("kvm-hint-dedicated=on is only applicable "
+ "for cpu host-passthrough"));
+ return -1;
+ }
+ break;
+
+ case VIR_DOMAIN_FEATURE_VMPORT:
+ if (def->features[i] != VIR_TRISTATE_SWITCH_ABSENT &&
+ !virQEMUCapsSupportsVmport(qemuCaps, def)) {
+
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("vmport is not available "
+ "with this QEMU binary"));
+ return -1;
+ }
+ break;
+
+ case VIR_DOMAIN_FEATURE_VMCOREINFO:
+ if (def->features[i] == VIR_TRISTATE_SWITCH_ON &&
+ !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VMCOREINFO)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("vmcoreinfo is not available "
+ "with this QEMU binary"));
+ return -1;
+ }
+ break;
+
+ case VIR_DOMAIN_FEATURE_APIC:
+ /* The kvm_pv_eoi feature is x86-only. */
+ if (def->features[i] != VIR_TRISTATE_SWITCH_ABSENT &&
+ def->apic_eoi != VIR_TRISTATE_SWITCH_ABSENT &&
+ !ARCH_IS_X86(def->os.arch)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("The 'eoi' attribute of the '%s'
feature "
+ "is not supported for architecture '%s' or
"
+ "machine type '%s'"),
+ featureName,
+ virArchToString(def->os.arch),
+ def->os.machine);
+ return -1;
+ }
+ break;
+
+ case VIR_DOMAIN_FEATURE_PVSPINLOCK:
+ if (def->features[i] != VIR_TRISTATE_SWITCH_ABSENT &&
+ !ARCH_IS_X86(def->os.arch)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("The '%s' feature is not supported for
"
+ "architecture '%s' or machine type
'%s'"),
+ featureName,
+ virArchToString(def->os.arch),
+ def->os.machine);
+ return -1;
+ }
+ break;
+
+ case VIR_DOMAIN_FEATURE_HYPERV:
+ if (def->features[i] != VIR_TRISTATE_SWITCH_ABSENT &&
+ !ARCH_IS_X86(def->os.arch) && !qemuDomainIsARMVirt(def)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Hyperv features are not supported for "
+ "architecture '%s' or machine type
'%s'"),
+ virArchToString(def->os.arch),
+ def->os.machine);
+ return -1;
+ }
+ break;
+
+ case VIR_DOMAIN_FEATURE_PMU:
+ if (def->features[i] == VIR_TRISTATE_SWITCH_OFF &&
+ ARCH_IS_PPC64(def->os.arch)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("PMU is always enabled for architecture
'%s'"),
+ virArchToString(def->os.arch));
+ return -1;
+ }
+ break;
+
+ case VIR_DOMAIN_FEATURE_ACPI:
+ case VIR_DOMAIN_FEATURE_PAE:
+ case VIR_DOMAIN_FEATURE_HAP:
+ case VIR_DOMAIN_FEATURE_VIRIDIAN:
+ case VIR_DOMAIN_FEATURE_PRIVNET:
+ case VIR_DOMAIN_FEATURE_CAPABILITIES:
+ case VIR_DOMAIN_FEATURE_MSRS:
+ case VIR_DOMAIN_FEATURE_LAST:
+ break;
+ }
+ }
+
+ return 0;
+}
diff --git a/src/qemu/qemu_validate.h b/src/qemu/qemu_validate.h
new file mode 100644
index 0000000000..ed269f29e4
--- /dev/null
+++ b/src/qemu/qemu_validate.h
@@ -0,0 +1,29 @@
+/*
+ * qemu_validate.h: QEMU general validation functions
+ *
+ * Copyright IBM Corp, 2020
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <
http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <glib-object.h>
+
+#include "domain_conf.h"
+#include "qemu_capabilities.h"
+
+int qemuValidateDomainDefFeatures(const virDomainDef *def,
+ virQEMUCapsPtr qemuCaps);
--
2.25.1