The qemuDomainDefCPUPostParse() does a bit more than filling in missing info. It also validates CPU cache configuration. Move that code into qemuValidateDomainDefCpu() where the code fits better. And since I need to fix indentation of existing code in qemuValidateDomainDefCpu(), I'm taking this opportunity and move error messages onto single line. Interestingly, this uncovers a bug we have in sc_prohibit_diagnostic_without_format syntax-check rule, because previously a virReportError() with a message spawned over three lines was not caught but not it is. But trying to understand that regex is a job for another time. Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- src/qemu/qemu_domain.c | 56 ----------------- src/qemu/qemu_validate.c | 129 +++++++++++++++++++++++++++------------ 2 files changed, 89 insertions(+), 96 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index a53c25f36e..61a7297599 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4373,62 +4373,6 @@ qemuDomainDefCPUPostParse(virDomainDef *def, if (!def->cpu) return 0; - if (def->cpu->cache) { - virCPUCacheDef *cache = def->cpu->cache; - - if (!ARCH_IS_X86(def->os.arch)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("CPU cache specification is not supported " - "for '%s' architecture"), - virArchToString(def->os.arch)); - return -1; - } - - switch (cache->mode) { - case VIR_CPU_CACHE_MODE_EMULATE: - if (cache->level != 3) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("CPU cache mode '%s' can only be used with " - "level='3'"), - virCPUCacheModeTypeToString(cache->mode)); - return -1; - } - break; - - case VIR_CPU_CACHE_MODE_PASSTHROUGH: - if (def->cpu->mode != VIR_CPU_MODE_HOST_PASSTHROUGH && - def->cpu->mode != VIR_CPU_MODE_MAXIMUM) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("CPU cache mode '%s' can only be used with " - "'%s' / '%s' CPUs"), - virCPUCacheModeTypeToString(cache->mode), - virCPUModeTypeToString(VIR_CPU_MODE_HOST_PASSTHROUGH), - virCPUModeTypeToString(VIR_CPU_MODE_MAXIMUM)); - return -1; - } - - if (cache->level != -1) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unsupported CPU cache level for mode '%s'"), - virCPUCacheModeTypeToString(cache->mode)); - return -1; - } - break; - - case VIR_CPU_CACHE_MODE_DISABLE: - if (cache->level != -1) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unsupported CPU cache level for mode '%s'"), - virCPUCacheModeTypeToString(cache->mode)); - return -1; - } - break; - - case VIR_CPU_CACHE_MODE_LAST: - break; - } - } - for (i = 0; i < def->cpu->nfeatures; i++) { virCPUFeatureDef *feature = &def->cpu->features[i]; diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 48bd40db9f..7fa899e411 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -332,52 +332,101 @@ qemuValidateDomainDefCpu(virQEMUDriver *driver, if (!cpu) return 0; - if (!cpu->model && cpu->mode == VIR_CPU_MODE_CUSTOM) - return 0; - - switch ((virCPUMode) cpu->mode) { - case VIR_CPU_MODE_HOST_PASSTHROUGH: - if (def->os.arch == VIR_ARCH_ARMV7L && - driver->hostarch == VIR_ARCH_AARCH64) { - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_AARCH64_OFF)) { + if (def->cpu->cache) { + virCPUCacheDef *cache = def->cpu->cache; + + if (!ARCH_IS_X86(def->os.arch)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("CPU cache specification is not supported for '%s' architecture"), + virArchToString(def->os.arch)); + return -1; + } + + switch (cache->mode) { + case VIR_CPU_CACHE_MODE_EMULATE: + if (cache->level != 3) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("QEMU binary does not support CPU " - "host-passthrough for armv7l on " - "aarch64 host")); + _("CPU cache mode '%s' can only be used with level='3'"), + virCPUCacheModeTypeToString(cache->mode)); return -1; } - } + break; - if (cpu->migratable && - cpu->migratable != VIR_TRISTATE_SWITCH_OFF && - !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_MIGRATABLE)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("Migratable attribute for host-passthrough " - "CPU is not supported by this QEMU binary")); - return -1; - } - break; - - case VIR_CPU_MODE_HOST_MODEL: - /* qemu_command.c will error out if cpu->mode is HOST_MODEL for - * every arch but PPC64. However, we can't move this validation - * here because non-PPC64 archs will translate HOST_MODEL to - * something else during domain start, changing cpu->mode to - * CUSTOM. - */ - break; - - case VIR_CPU_MODE_MAXIMUM: - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_MAX)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("maximum CPU is not supported by QEMU binary")); - return -1; + case VIR_CPU_CACHE_MODE_PASSTHROUGH: + if (def->cpu->mode != VIR_CPU_MODE_HOST_PASSTHROUGH && + def->cpu->mode != VIR_CPU_MODE_MAXIMUM) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("CPU cache mode '%s' can only be used with '%s' / '%s' CPUs"), + virCPUCacheModeTypeToString(cache->mode), + virCPUModeTypeToString(VIR_CPU_MODE_HOST_PASSTHROUGH), + virCPUModeTypeToString(VIR_CPU_MODE_MAXIMUM)); + return -1; + } + + if (cache->level != -1) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unsupported CPU cache level for mode '%s'"), + virCPUCacheModeTypeToString(cache->mode)); + return -1; + } + break; + + case VIR_CPU_CACHE_MODE_DISABLE: + if (cache->level != -1) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unsupported CPU cache level for mode '%s'"), + virCPUCacheModeTypeToString(cache->mode)); + return -1; + } + break; + + case VIR_CPU_CACHE_MODE_LAST: + break; } - break; + } + + if (cpu->model || cpu->mode != VIR_CPU_MODE_CUSTOM) { + switch ((virCPUMode) cpu->mode) { + case VIR_CPU_MODE_HOST_PASSTHROUGH: + if (def->os.arch == VIR_ARCH_ARMV7L && + driver->hostarch == VIR_ARCH_AARCH64) { + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_AARCH64_OFF)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("QEMU binary does not support CPU host-passthrough for armv7l on aarch64 host")); + return -1; + } + } - case VIR_CPU_MODE_CUSTOM: - case VIR_CPU_MODE_LAST: - break; + if (cpu->migratable && + cpu->migratable != VIR_TRISTATE_SWITCH_OFF && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_MIGRATABLE)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Migratable attribute for host-passthrough CPU is not supported by this QEMU binary")); + return -1; + } + break; + + case VIR_CPU_MODE_HOST_MODEL: + /* qemu_command.c will error out if cpu->mode is HOST_MODEL for + * every arch but PPC64. However, we can't move this validation + * here because non-PPC64 archs will translate HOST_MODEL to + * something else during domain start, changing cpu->mode to + * CUSTOM. + */ + break; + + case VIR_CPU_MODE_MAXIMUM: + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_MAX)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("maximum CPU is not supported by QEMU binary")); + return -1; + } + break; + + case VIR_CPU_MODE_CUSTOM: + case VIR_CPU_MODE_LAST: + break; + } } return 0; -- 2.35.1