cpu: Avoid adding <vendor> to custom CPUs

Guest CPU definitions with mode='custom' and missing <vendor> are
expected to run on a host CPU from any vendor as long as the required
CPU model can be used as a guest CPU on the host. But even though no CPU
vendor was explicitly requested we would sometimes force it due to a bug
in virCPUUpdate and virCPUTranslate.

The bug would effectively forbid cross vendor migrations even if they
were previously working just fine.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
This commit is contained in:
Jiri Denemark 2016-11-10 10:26:03 +01:00
parent d73422c186
commit 98b7c37d37
10 changed files with 31 additions and 13 deletions

View File

@ -132,20 +132,42 @@ virCPUDefCopyModelFilter(virCPUDefPtr dst,
}
/**
* virCPUDefStealModel:
*
* Move CPU model related parts virCPUDef from @src to @dst. If @keepVendor
* is true, the function keeps the original vendor/vendor_id in @dst rather
* than overwriting it with the values from @src.
*/
void
virCPUDefStealModel(virCPUDefPtr dst,
virCPUDefPtr src)
virCPUDefPtr src,
bool keepVendor)
{
char *vendor;
char *vendor_id;
if (keepVendor) {
VIR_STEAL_PTR(vendor, dst->vendor);
VIR_STEAL_PTR(vendor_id, dst->vendor_id);
}
virCPUDefFreeModel(dst);
VIR_STEAL_PTR(dst->model, src->model);
VIR_STEAL_PTR(dst->vendor, src->vendor);
VIR_STEAL_PTR(dst->vendor_id, src->vendor_id);
VIR_STEAL_PTR(dst->features, src->features);
dst->nfeatures_max = src->nfeatures_max;
src->nfeatures_max = 0;
dst->nfeatures = src->nfeatures;
src->nfeatures = 0;
if (keepVendor) {
dst->vendor = vendor;
dst->vendor_id = vendor_id;
} else {
VIR_STEAL_PTR(dst->vendor, src->vendor);
VIR_STEAL_PTR(dst->vendor_id, src->vendor_id);
}
}

View File

@ -139,7 +139,8 @@ virCPUDefCopyModelFilter(virCPUDefPtr dst,
void
virCPUDefStealModel(virCPUDefPtr dst,
virCPUDefPtr src);
virCPUDefPtr src,
bool keepVendor);
virCPUDefPtr
virCPUDefCopy(const virCPUDef *cpu);

View File

@ -67,7 +67,7 @@ virCPUarmUpdate(virCPUDefPtr guest,
if (virCPUDefCopyModel(updated, host, true) < 0)
goto cleanup;
virCPUDefStealModel(guest, updated);
virCPUDefStealModel(guest, updated, false);
guest->mode = VIR_CPU_MODE_CUSTOM;
guest->match = VIR_CPU_MATCH_EXACT;
ret = 0;

View File

@ -2576,7 +2576,8 @@ x86UpdateHostModel(virCPUDefPtr guest,
goto cleanup;
}
virCPUDefStealModel(guest, updated);
virCPUDefStealModel(guest, updated,
guest->mode == VIR_CPU_MODE_CUSTOM);
guest->mode = VIR_CPU_MODE_CUSTOM;
guest->match = VIR_CPU_MATCH_EXACT;
ret = 0;
@ -2737,7 +2738,7 @@ virCPUx86Translate(virCPUDefPtr cpu,
goto cleanup;
}
virCPUDefStealModel(cpu, translated);
virCPUDefStealModel(cpu, translated, true);
ret = 0;
cleanup:

View File

@ -1,6 +1,5 @@
<cpu mode='custom' match='exact'>
<model fallback='allow'>486</model>
<vendor>Intel</vendor>
<topology sockets='2' cores='4' threads='1'/>
<feature policy='require' name='de'/>
<feature policy='require' name='tsc'/>

View File

@ -1,6 +1,5 @@
<cpu mode='custom' match='exact'>
<model fallback='allow'>Nehalem</model>
<vendor>Intel</vendor>
<topology sockets='2' cores='4' threads='1'/>
<feature policy='force' name='pbe'/>
<feature policy='force' name='monitor'/>

View File

@ -1,6 +1,5 @@
<cpu mode='custom' match='exact'>
<model fallback='allow'>Penryn</model>
<vendor>Intel</vendor>
<feature policy='require' name='dca'/>
<feature policy='require' name='xtpr'/>
<feature policy='require' name='tm2'/>

View File

@ -1,6 +1,5 @@
<cpu mode='custom' match='exact'>
<model fallback='allow'>Penryn</model>
<vendor>Intel</vendor>
<feature policy='require' name='dca'/>
<feature policy='require' name='xtpr'/>
<feature policy='require' name='tm2'/>

View File

@ -1,6 +1,5 @@
<cpu mode='custom' match='exact'>
<model fallback='allow'>Haswell</model>
<vendor>Intel</vendor>
<topology sockets='1' cores='2' threads='2'/>
<feature policy='disable' name='hle'/>
<feature policy='disable' name='rtm'/>

View File

@ -1,6 +1,5 @@
<cpu mode='custom' match='exact'>
<model fallback='allow'>Nehalem</model>
<vendor>Intel</vendor>
<feature policy='require' name='dca'/>
<feature policy='require' name='xtpr'/>
<feature policy='require' name='tm2'/>