qemu: Move CPU validation out of PostParse

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@redhat.com>
Reviewed-by: Erik Skultety <eskultet@redhat.com>
This commit is contained in:
Michal Privoznik 2022-08-01 16:56:25 +02:00
parent 469f2ab31c
commit 49065e6a93
2 changed files with 88 additions and 95 deletions

View File

@ -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];

View File

@ -332,52 +332,101 @@ qemuValidateDomainDefCpu(virQEMUDriver *driver,
if (!cpu)
return 0;
if (!cpu->model && cpu->mode == VIR_CPU_MODE_CUSTOM)
return 0;
if (def->cpu->cache) {
virCPUCacheDef *cache = def->cpu->cache;
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 (!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;
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;
}
}
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;
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;
}
}
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;
}
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;