Until now host-model CPU mode tried to enable all CPU features supported by the host CPU even if QEMU/KVM did not support them. This caused a number of issues and made host-model quite unreliable. Asking QEMU for the CPU it can provide and the current host makes host-model much more robust. This commit fixes the following bugs: https://bugzilla.redhat.com/show_bug.cgi?id=1018251 https://bugzilla.redhat.com/show_bug.cgi?id=1371617 https://bugzilla.redhat.com/show_bug.cgi?id=1372581 https://bugzilla.redhat.com/show_bug.cgi?id=1404627 https://bugzilla.redhat.com/show_bug.cgi?id=870071 In addition to that, the following bug should be mostly limited to cases when an unsupported feature is explicitly requested: https://bugzilla.redhat.com/show_bug.cgi?id=1335534 Signed-off-by: Jiri Denemark <jdenemar@xxxxxxxxxx> --- Notes: Version 3: - added #include "cpu/cpu_x86.h" removed in an earlier patch - adapted to changes to qemuMonitorCPUModelProperty Version 2: - no change src/qemu/qemu_capabilities.c | 77 ++++++++++++++++++++++ .../domaincapsschemadata/qemu_2.9.0-tcg.x86_64.xml | 33 +++++++++- tests/domaincapsschemadata/qemu_2.9.0.x86_64.xml | 11 +++- 3 files changed, 119 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 5c0353159..adfe84bff 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -33,6 +33,7 @@ #include "virprocess.h" #include "nodeinfo.h" #include "cpu/cpu.h" +#include "cpu/cpu_x86.h" #include "domain_conf.h" #include "vircommand.h" #include "virbitmap.h" @@ -3129,6 +3130,80 @@ virQEMUCapsInitCPUModelS390(virQEMUCapsPtr qemuCaps, * -1 on error. */ static int +virQEMUCapsInitCPUModelX86(virQEMUCapsPtr qemuCaps, + virDomainVirtType type, + virCPUDefPtr cpu) +{ + qemuMonitorCPUModelInfoPtr model; + virCPUDataPtr data = NULL; + unsigned long long sigFamily = 0; + unsigned long long sigModel = 0; + size_t nmodels = 0; + char **models = NULL; + int ret = -1; + size_t i; + + if (type == VIR_DOMAIN_VIRT_KVM) + model = qemuCaps->kvmCPUModelInfo; + else + model = qemuCaps->tcgCPUModelInfo; + + if (!model) + return 1; + + if (!(data = virCPUDataNew(VIR_ARCH_X86_64))) + goto cleanup; + + for (i = 0; i < model->nprops; i++) { + qemuMonitorCPUPropertyPtr prop = model->props + i; + + switch (prop->type) { + case QEMU_MONITOR_CPU_PROPERTY_BOOLEAN: + if (prop->value.boolean && + virCPUx86DataAddFeature(data, prop->name) < 0) + goto cleanup; + break; + + case QEMU_MONITOR_CPU_PROPERTY_STRING: + if (STREQ(prop->name, "vendor") && + virCPUx86DataSetVendor(data, prop->value.string) < 0) + goto cleanup; + break; + + case QEMU_MONITOR_CPU_PROPERTY_NUMBER: + if (STREQ(prop->name, "family")) + sigFamily = prop->value.number; + else if (STREQ(prop->name, "model")) + sigModel = prop->value.number; + break; + + case QEMU_MONITOR_CPU_PROPERTY_LAST: + break; + } + } + + if (virCPUx86DataSetSignature(data, sigFamily, sigModel) < 0) + goto cleanup; + + if (virQEMUCapsGetCPUDefinitions(qemuCaps, type, &models, &nmodels) < 0 || + cpuDecode(cpu, data, (const char **) models, nmodels, NULL) < 0) + goto cleanup; + + ret = 0; + + cleanup: + virCPUDataFree(data); + virStringListFreeCount(models, nmodels); + return ret; +} + + +/** + * Returns 0 when host CPU model provided by QEMU was filled in qemuCaps, + * 1 when the caller should fall back to using virCapsPtr->host.cpu, + * -1 on error. + */ +static int virQEMUCapsInitCPUModel(virQEMUCapsPtr qemuCaps, virDomainVirtType type, virCPUDefPtr cpu) @@ -3137,6 +3212,8 @@ virQEMUCapsInitCPUModel(virQEMUCapsPtr qemuCaps, if (ARCH_IS_S390(qemuCaps->arch)) ret = virQEMUCapsInitCPUModelS390(qemuCaps, type, cpu); + else if (ARCH_IS_X86(qemuCaps->arch)) + ret = virQEMUCapsInitCPUModelX86(qemuCaps, type, cpu); if (ret == 0) cpu->fallback = VIR_CPU_FALLBACK_FORBID; diff --git a/tests/domaincapsschemadata/qemu_2.9.0-tcg.x86_64.xml b/tests/domaincapsschemadata/qemu_2.9.0-tcg.x86_64.xml index 9b9dfec09..1827b1d6f 100644 --- a/tests/domaincapsschemadata/qemu_2.9.0-tcg.x86_64.xml +++ b/tests/domaincapsschemadata/qemu_2.9.0-tcg.x86_64.xml @@ -21,7 +21,38 @@ <cpu> <mode name='host-passthrough' supported='no'/> <mode name='host-model' supported='yes'> - <model fallback='allow'>Broadwell</model> + <model fallback='forbid'>Opteron_G4</model> + <vendor>AMD</vendor> + <feature policy='require' name='acpi'/> + <feature policy='require' name='ss'/> + <feature policy='require' name='monitor'/> + <feature policy='require' name='movbe'/> + <feature policy='require' name='hypervisor'/> + <feature policy='require' name='arat'/> + <feature policy='require' name='fsgsbase'/> + <feature policy='require' name='bmi1'/> + <feature policy='require' name='smep'/> + <feature policy='require' name='bmi2'/> + <feature policy='require' name='erms'/> + <feature policy='require' name='mpx'/> + <feature policy='require' name='adx'/> + <feature policy='require' name='smap'/> + <feature policy='require' name='clflushopt'/> + <feature policy='require' name='pku'/> + <feature policy='require' name='ospke'/> + <feature policy='require' name='xsaveopt'/> + <feature policy='require' name='xgetbv1'/> + <feature policy='require' name='mmxext'/> + <feature policy='require' name='3dnowext'/> + <feature policy='require' name='3dnow'/> + <feature policy='require' name='cr8legacy'/> + <feature policy='disable' name='pclmuldq'/> + <feature policy='disable' name='avx'/> + <feature policy='disable' name='lahf_lm'/> + <feature policy='disable' name='misalignsse'/> + <feature policy='disable' name='3dnowprefetch'/> + <feature policy='disable' name='xop'/> + <feature policy='disable' name='fma4'/> </mode> <mode name='custom' supported='yes'> <model usable='yes'>qemu64</model> diff --git a/tests/domaincapsschemadata/qemu_2.9.0.x86_64.xml b/tests/domaincapsschemadata/qemu_2.9.0.x86_64.xml index 49722f91f..a7a2ecdea 100644 --- a/tests/domaincapsschemadata/qemu_2.9.0.x86_64.xml +++ b/tests/domaincapsschemadata/qemu_2.9.0.x86_64.xml @@ -21,7 +21,16 @@ <cpu> <mode name='host-passthrough' supported='yes'/> <mode name='host-model' supported='yes'> - <model fallback='allow'>Broadwell</model> + <model fallback='forbid'>Skylake-Client</model> + <vendor>Intel</vendor> + <feature policy='require' name='ss'/> + <feature policy='require' name='vmx'/> + <feature policy='require' name='hypervisor'/> + <feature policy='require' name='clflushopt'/> + <feature policy='require' name='xsaves'/> + <feature policy='require' name='pdpe1gb'/> + <feature policy='disable' name='pclmuldq'/> + <feature policy='disable' name='lahf_lm'/> </mode> <mode name='custom' supported='yes'> <model usable='yes'>qemu64</model> -- 2.11.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list