On Core i5 650 guest fail to start with error [1] if guest cpu config is taken
from domcapabilities and check is set to partial.
The problem is in qemu caps fullCPU calculation in virQEMUCapsInitHostCPUModel.
It is supposed to include features emulated by qemu and missed on host. Some of
such features may be not included however.
For mentioned cpu host cpu is detected as Westmere and guest cpu as
SandyBridge. x2apic is missed on host and provided by installed qemu. The
feature is not mentioned in guest cpu features explicitly because SandyBridge
model include it. As a result fullCPU does not include x2apic too.
Solution is to expand guest cpu features before updating fullCPU features.
[1] error: the CPU is incompatible with host CPU: Host CPU does not
provide required features: x2apic, tsc-deadline
---
src/qemu/qemu_capabilities.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 9c1eeac..edba716 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -3475,6 +3475,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
virDomainVirtType type)
{
virCPUDefPtr cpu = NULL;
+ virCPUDefPtr cpuExpanded = NULL;
virCPUDefPtr migCPU = NULL;
virCPUDefPtr hostCPU = NULL;
virCPUDefPtr fullCPU = NULL;
@@ -3504,9 +3505,13 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
NULL, NULL)))
goto error;
- for (i = 0; i < cpu->nfeatures; i++) {
- if (cpu->features[i].policy == VIR_CPU_FEATURE_REQUIRE &&
- virCPUDefUpdateFeature(fullCPU, cpu->features[i].name,
+ if (!(cpuExpanded = virCPUDefCopy(cpu)) ||
+ virCPUExpandFeatures(qemuCaps->arch, cpuExpanded) < 0)
+ goto error;
+
+ for (i = 0; i < cpuExpanded->nfeatures; i++) {
+ if (cpuExpanded->features[i].policy == VIR_CPU_FEATURE_REQUIRE &&
+ virCPUDefUpdateFeature(fullCPU, cpuExpanded->features[i].name,
VIR_CPU_FEATURE_REQUIRE) < 0)
goto error;
}
@@ -3528,6 +3533,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
virQEMUCapsSetHostModel(qemuCaps, type, cpu, migCPU, fullCPU);
cleanup:
+ virCPUDefFree(cpuExpanded);
virCPUDefFree(hostCPU);
return;
--
1.8.3.1