mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-22 12:35:17 +00:00
qemu: Get host CPU model from QEMU on x86_64
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@redhat.com>
This commit is contained in:
parent
d7f054a512
commit
f013828992
@ -33,6 +33,7 @@
|
|||||||
#include "virprocess.h"
|
#include "virprocess.h"
|
||||||
#include "nodeinfo.h"
|
#include "nodeinfo.h"
|
||||||
#include "cpu/cpu.h"
|
#include "cpu/cpu.h"
|
||||||
|
#include "cpu/cpu_x86.h"
|
||||||
#include "domain_conf.h"
|
#include "domain_conf.h"
|
||||||
#include "vircommand.h"
|
#include "vircommand.h"
|
||||||
#include "virbitmap.h"
|
#include "virbitmap.h"
|
||||||
@ -3131,6 +3132,80 @@ virQEMUCapsInitCPUModelS390(virQEMUCapsPtr qemuCaps,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
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,
|
* 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 when the caller should fall back to using virCapsPtr->host.cpu,
|
||||||
@ -3145,6 +3220,8 @@ virQEMUCapsInitCPUModel(virQEMUCapsPtr qemuCaps,
|
|||||||
|
|
||||||
if (ARCH_IS_S390(qemuCaps->arch))
|
if (ARCH_IS_S390(qemuCaps->arch))
|
||||||
ret = virQEMUCapsInitCPUModelS390(qemuCaps, type, cpu);
|
ret = virQEMUCapsInitCPUModelS390(qemuCaps, type, cpu);
|
||||||
|
else if (ARCH_IS_X86(qemuCaps->arch))
|
||||||
|
ret = virQEMUCapsInitCPUModelX86(qemuCaps, type, cpu);
|
||||||
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
cpu->fallback = VIR_CPU_FALLBACK_FORBID;
|
cpu->fallback = VIR_CPU_FALLBACK_FORBID;
|
||||||
|
@ -21,7 +21,38 @@
|
|||||||
<cpu>
|
<cpu>
|
||||||
<mode name='host-passthrough' supported='no'/>
|
<mode name='host-passthrough' supported='no'/>
|
||||||
<mode name='host-model' supported='yes'>
|
<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>
|
||||||
<mode name='custom' supported='yes'>
|
<mode name='custom' supported='yes'>
|
||||||
<model usable='yes'>qemu64</model>
|
<model usable='yes'>qemu64</model>
|
||||||
|
@ -21,7 +21,16 @@
|
|||||||
<cpu>
|
<cpu>
|
||||||
<mode name='host-passthrough' supported='yes'/>
|
<mode name='host-passthrough' supported='yes'/>
|
||||||
<mode name='host-model' 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>
|
||||||
<mode name='custom' supported='yes'>
|
<mode name='custom' supported='yes'>
|
||||||
<model usable='yes'>qemu64</model>
|
<model usable='yes'>qemu64</model>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user