[libvirt] [PATCH v2 22/33] qemu: Get host CPU model from QEMU on x86_64

John Ferlan jferlan at redhat.com
Wed Feb 22 03:28:25 UTC 2017



On 02/15/2017 11:44 AM, Jiri Denemark wrote:
> 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 at redhat.com>
> ---
> 
> Notes:
>     Version 2:
>     - no change
> 
>  src/qemu/qemu_capabilities.c                       | 73 ++++++++++++++++++++++
>  .../domaincapsschemadata/qemu_2.9.0-tcg.x86_64.xml | 33 +++++++++-
>  tests/domaincapsschemadata/qemu_2.9.0.x86_64.xml   | 11 +++-
>  3 files changed, 115 insertions(+), 2 deletions(-)
> 
> diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
> index f115f1e23..bcfb6b694 100644
> --- a/src/qemu/qemu_capabilities.c
> +++ b/src/qemu/qemu_capabilities.c
> @@ -3128,6 +3128,77 @@ 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;

Use virQEMUCapsGetHostModel  (there's probably a couple of these)...

ACK w/ that.

John
> +
> +    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_ULL:
> +            if (STREQ(prop->name, "family"))
> +                sigFamily = prop->value.ull;
> +            else if (STREQ(prop->name, "model"))
> +                sigModel = prop->value.ull;
> +            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)
> @@ -3136,6 +3207,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>
> 




More information about the libvir-list mailing list