mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-03 15:43:51 +00:00
Don't include non-migratable features in host-model
Commit fba6bc4 introduced support for the 'invtsc' feature, which blocks migration. We should not include it in the host-model CPU by default, because it's intended to be used with migration. https://bugzilla.redhat.com/show_bug.cgi?id=1138221
This commit is contained in:
parent
36cc189a46
commit
de0aeafe9c
@ -328,7 +328,7 @@
|
|||||||
</feature>
|
</feature>
|
||||||
|
|
||||||
<!-- Advanced Power Management edx features -->
|
<!-- Advanced Power Management edx features -->
|
||||||
<feature name='invtsc'>
|
<feature name='invtsc' migratable='no'>
|
||||||
<cpuid function='0x80000007' edx='0x00000100'/>
|
<cpuid function='0x80000007' edx='0x00000100'/>
|
||||||
</feature>
|
</feature>
|
||||||
|
|
||||||
|
@ -89,6 +89,7 @@ struct x86_map {
|
|||||||
struct x86_vendor *vendors;
|
struct x86_vendor *vendors;
|
||||||
struct x86_feature *features;
|
struct x86_feature *features;
|
||||||
struct x86_model *models;
|
struct x86_model *models;
|
||||||
|
struct x86_feature *migrate_blockers;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct x86_map* virCPUx86Map = NULL;
|
static struct x86_map* virCPUx86Map = NULL;
|
||||||
@ -591,6 +592,28 @@ x86FeatureFree(struct x86_feature *feature)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct x86_feature *
|
||||||
|
x86FeatureCopy(const struct x86_feature *src)
|
||||||
|
{
|
||||||
|
struct x86_feature *feature;
|
||||||
|
|
||||||
|
if (VIR_ALLOC(feature) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (VIR_STRDUP(feature->name, src->name) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if ((feature->data = x86DataCopy(src->data)) == NULL)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
return feature;
|
||||||
|
|
||||||
|
error:
|
||||||
|
x86FeatureFree(feature);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct x86_feature *
|
static struct x86_feature *
|
||||||
x86FeatureFind(const struct x86_map *map,
|
x86FeatureFind(const struct x86_map *map,
|
||||||
const char *name)
|
const char *name)
|
||||||
@ -677,6 +700,9 @@ x86FeatureLoad(xmlXPathContextPtr ctxt,
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
size_t i;
|
size_t i;
|
||||||
int n;
|
int n;
|
||||||
|
char *str = NULL;
|
||||||
|
bool migratable = true;
|
||||||
|
struct x86_feature *migrate_blocker = NULL;
|
||||||
|
|
||||||
if (!(feature = x86FeatureNew()))
|
if (!(feature = x86FeatureNew()))
|
||||||
goto error;
|
goto error;
|
||||||
@ -694,6 +720,10 @@ x86FeatureLoad(xmlXPathContextPtr ctxt,
|
|||||||
goto ignore;
|
goto ignore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
str = virXPathString("string(@migratable)", ctxt);
|
||||||
|
if (STREQ_NULLABLE(str, "no"))
|
||||||
|
migratable = false;
|
||||||
|
|
||||||
n = virXPathNodeSet("./cpuid", ctxt, &nodes);
|
n = virXPathNodeSet("./cpuid", ctxt, &nodes);
|
||||||
if (n < 0)
|
if (n < 0)
|
||||||
goto ignore;
|
goto ignore;
|
||||||
@ -710,6 +740,14 @@ x86FeatureLoad(xmlXPathContextPtr ctxt,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!migratable) {
|
||||||
|
if ((migrate_blocker = x86FeatureCopy(feature)) == NULL)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
migrate_blocker->next = map->migrate_blockers;
|
||||||
|
map->migrate_blockers = migrate_blocker;
|
||||||
|
}
|
||||||
|
|
||||||
if (map->features == NULL) {
|
if (map->features == NULL) {
|
||||||
map->features = feature;
|
map->features = feature;
|
||||||
} else {
|
} else {
|
||||||
@ -720,6 +758,7 @@ x86FeatureLoad(xmlXPathContextPtr ctxt,
|
|||||||
out:
|
out:
|
||||||
ctxt->node = ctxt_node;
|
ctxt->node = ctxt_node;
|
||||||
VIR_FREE(nodes);
|
VIR_FREE(nodes);
|
||||||
|
VIR_FREE(str);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -728,6 +767,7 @@ x86FeatureLoad(xmlXPathContextPtr ctxt,
|
|||||||
|
|
||||||
ignore:
|
ignore:
|
||||||
x86FeatureFree(feature);
|
x86FeatureFree(feature);
|
||||||
|
x86FeatureFree(migrate_blocker);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1093,6 +1133,12 @@ x86MapFree(struct x86_map *map)
|
|||||||
x86VendorFree(vendor);
|
x86VendorFree(vendor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (map->migrate_blockers != NULL) {
|
||||||
|
struct x86_feature *migrate_blocker = map->migrate_blockers;
|
||||||
|
map->migrate_blockers = migrate_blocker->next;
|
||||||
|
x86FeatureFree(migrate_blocker);
|
||||||
|
}
|
||||||
|
|
||||||
VIR_FREE(map);
|
VIR_FREE(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2025,16 +2071,15 @@ x86UpdateHostModel(virCPUDefPtr guest,
|
|||||||
const virCPUDef *host)
|
const virCPUDef *host)
|
||||||
{
|
{
|
||||||
virCPUDefPtr oldguest = NULL;
|
virCPUDefPtr oldguest = NULL;
|
||||||
|
const struct x86_map *map;
|
||||||
|
const struct x86_feature *feat;
|
||||||
size_t i;
|
size_t i;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
guest->match = VIR_CPU_MATCH_EXACT;
|
guest->match = VIR_CPU_MATCH_EXACT;
|
||||||
|
|
||||||
/* no updates are required */
|
if (!(map = virCPUx86GetMap()))
|
||||||
if (guest->nfeatures == 0) {
|
goto cleanup;
|
||||||
virCPUDefFreeModel(guest);
|
|
||||||
return virCPUDefCopyModel(guest, host, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* update the host model according to the desired configuration */
|
/* update the host model according to the desired configuration */
|
||||||
if (!(oldguest = virCPUDefCopy(guest)))
|
if (!(oldguest = virCPUDefCopy(guest)))
|
||||||
@ -2044,6 +2089,16 @@ x86UpdateHostModel(virCPUDefPtr guest,
|
|||||||
if (virCPUDefCopyModel(guest, host, true) < 0)
|
if (virCPUDefCopyModel(guest, host, true) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
/* Remove non-migratable features by default
|
||||||
|
* Note: this only works as long as no CPU model contains non-migratable
|
||||||
|
* features directly */
|
||||||
|
for (i = 0; i < guest->nfeatures; i++) {
|
||||||
|
for (feat = map->migrate_blockers; feat; feat = feat->next) {
|
||||||
|
if (STREQ(feat->name, guest->features[i].name))
|
||||||
|
VIR_DELETE_ELEMENT_INPLACE(guest->features, i, guest->nfeatures);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < oldguest->nfeatures; i++) {
|
for (i = 0; i < oldguest->nfeatures; i++) {
|
||||||
if (virCPUDefUpdateFeature(guest,
|
if (virCPUDefUpdateFeature(guest,
|
||||||
oldguest->features[i].name,
|
oldguest->features[i].name,
|
||||||
|
@ -599,6 +599,7 @@ mymain(void)
|
|||||||
DO_TEST_UPDATE("x86", "host", "host-model", VIR_CPU_COMPARE_IDENTICAL);
|
DO_TEST_UPDATE("x86", "host", "host-model", VIR_CPU_COMPARE_IDENTICAL);
|
||||||
DO_TEST_UPDATE("x86", "host", "host-model-nofallback", VIR_CPU_COMPARE_IDENTICAL);
|
DO_TEST_UPDATE("x86", "host", "host-model-nofallback", VIR_CPU_COMPARE_IDENTICAL);
|
||||||
DO_TEST_UPDATE("x86", "host", "host-passthrough", VIR_CPU_COMPARE_IDENTICAL);
|
DO_TEST_UPDATE("x86", "host", "host-passthrough", VIR_CPU_COMPARE_IDENTICAL);
|
||||||
|
DO_TEST_UPDATE("x86", "host-invtsc", "host-model", VIR_CPU_COMPARE_SUPERSET);
|
||||||
|
|
||||||
/* computing baseline CPUs */
|
/* computing baseline CPUs */
|
||||||
DO_TEST_BASELINE("x86", "incompatible-vendors", 0, -1);
|
DO_TEST_BASELINE("x86", "incompatible-vendors", 0, -1);
|
||||||
|
22
tests/cputestdata/x86-host-invtsc+host-model.xml
Normal file
22
tests/cputestdata/x86-host-invtsc+host-model.xml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<cpu mode='host-model' match='exact'>
|
||||||
|
<model fallback='allow'>SandyBridge</model>
|
||||||
|
<vendor>Intel</vendor>
|
||||||
|
<feature policy='require' name='osxsave'/>
|
||||||
|
<feature policy='require' name='pcid'/>
|
||||||
|
<feature policy='require' name='pdcm'/>
|
||||||
|
<feature policy='require' name='xtpr'/>
|
||||||
|
<feature policy='require' name='tm2'/>
|
||||||
|
<feature policy='require' name='est'/>
|
||||||
|
<feature policy='require' name='smx'/>
|
||||||
|
<feature policy='require' name='vmx'/>
|
||||||
|
<feature policy='require' name='ds_cpl'/>
|
||||||
|
<feature policy='require' name='monitor'/>
|
||||||
|
<feature policy='require' name='dtes64'/>
|
||||||
|
<feature policy='require' name='pbe'/>
|
||||||
|
<feature policy='require' name='tm'/>
|
||||||
|
<feature policy='require' name='ht'/>
|
||||||
|
<feature policy='require' name='ss'/>
|
||||||
|
<feature policy='require' name='acpi'/>
|
||||||
|
<feature policy='require' name='ds'/>
|
||||||
|
<feature policy='require' name='vme'/>
|
||||||
|
</cpu>
|
27
tests/cputestdata/x86-host-invtsc.xml
Normal file
27
tests/cputestdata/x86-host-invtsc.xml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<cpu>
|
||||||
|
<arch>x86_64</arch>
|
||||||
|
<model>SandyBridge</model>
|
||||||
|
<vendor>Intel</vendor>
|
||||||
|
<topology sockets='1' cores='2' threads='2'/>
|
||||||
|
<feature name='invtsc'/>
|
||||||
|
<feature name='osxsave'/>
|
||||||
|
<feature name='pcid'/>
|
||||||
|
<feature name='pdcm'/>
|
||||||
|
<feature name='xtpr'/>
|
||||||
|
<feature name='tm2'/>
|
||||||
|
<feature name='est'/>
|
||||||
|
<feature name='smx'/>
|
||||||
|
<feature name='vmx'/>
|
||||||
|
<feature name='ds_cpl'/>
|
||||||
|
<feature name='monitor'/>
|
||||||
|
<feature name='dtes64'/>
|
||||||
|
<feature name='pbe'/>
|
||||||
|
<feature name='tm'/>
|
||||||
|
<feature name='ht'/>
|
||||||
|
<feature name='ss'/>
|
||||||
|
<feature name='acpi'/>
|
||||||
|
<feature name='ds'/>
|
||||||
|
<feature name='vme'/>
|
||||||
|
<pages unit='KiB' size='4'/>
|
||||||
|
<pages unit='KiB' size='2048'/>
|
||||||
|
</cpu>
|
Loading…
x
Reference in New Issue
Block a user