render / rpms / libvirt

Forked from rpms/libvirt 10 months ago
Clone
9119d9
From 038e97c940dd3eba1faf114b3559f32129110f72 Mon Sep 17 00:00:00 2001
9119d9
Message-Id: <038e97c940dd3eba1faf114b3559f32129110f72@dist-git>
898951
From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
9119d9
Date: Fri, 5 Sep 2014 14:41:25 +0200
898951
Subject: [PATCH] Don't include non-migratable features in host-model
898951
898951
Commit fba6bc4 introduced support for the 'invtsc' feature,
898951
which blocks migration. We should not include it in the
898951
host-model CPU by default, because it's intended to be used
898951
with migration.
898951
898951
https://bugzilla.redhat.com/show_bug.cgi?id=1138221
898951
(cherry picked from commit de0aeafe9ce3eb414c8b5d3aa8995d776a2952de)
898951
898951
Conflicts:
9119d9
	src/cpu/cpu_x86.c - braces cleanup
9119d9
9119d9
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
898951
---
898951
 src/cpu/cpu_map.xml                              |  2 +-
9119d9
 src/cpu/cpu_x86.c                                | 69 +++++++++++++++++++++---
898951
 tests/cputest.c                                  |  1 +
898951
 tests/cputestdata/x86-host-invtsc+host-model.xml | 22 ++++++++
898951
 tests/cputestdata/x86-host-invtsc.xml            | 27 ++++++++++
9119d9
 5 files changed, 113 insertions(+), 8 deletions(-)
898951
 create mode 100644 tests/cputestdata/x86-host-invtsc+host-model.xml
898951
 create mode 100644 tests/cputestdata/x86-host-invtsc.xml
898951
898951
diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml
9119d9
index 12987a0..18c7b0d 100644
898951
--- a/src/cpu/cpu_map.xml
898951
+++ b/src/cpu/cpu_map.xml
898951
@@ -328,7 +328,7 @@
898951
     </feature>
898951
 
898951
     
898951
-    <feature name='invtsc'>
898951
+    <feature name='invtsc' migratable='no'>
898951
       <cpuid function='0x80000007' edx='0x00000100'/>
898951
     </feature>
898951
 
898951
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
9119d9
index b460e8d..affc882 100644
898951
--- a/src/cpu/cpu_x86.c
898951
+++ b/src/cpu/cpu_x86.c
9119d9
@@ -89,6 +89,7 @@ struct x86_map {
898951
     struct x86_vendor *vendors;
898951
     struct x86_feature *features;
898951
     struct x86_model *models;
898951
+    struct x86_feature *migrate_blockers;
898951
 };
898951
 
898951
 static struct x86_map* virCPUx86Map = NULL;
9119d9
@@ -592,6 +593,28 @@ x86FeatureFree(struct x86_feature *feature)
898951
 
898951
 
898951
 static struct x86_feature *
898951
+x86FeatureCopy(const struct x86_feature *src)
898951
+{
898951
+    struct x86_feature *feature;
898951
+
898951
+    if (VIR_ALLOC(feature) < 0)
898951
+        return NULL;
898951
+
898951
+    if (VIR_STRDUP(feature->name, src->name) < 0)
898951
+        goto error;
898951
+
898951
+    if ((feature->data = x86DataCopy(src->data)) == NULL)
898951
+        goto error;
898951
+
898951
+    return feature;
898951
+
898951
+ error:
898951
+    x86FeatureFree(feature);
898951
+    return NULL;
898951
+}
898951
+
898951
+
898951
+static struct x86_feature *
898951
 x86FeatureFind(const struct x86_map *map,
898951
                const char *name)
898951
 {
9119d9
@@ -677,6 +700,9 @@ x86FeatureLoad(xmlXPathContextPtr ctxt,
898951
     int ret = 0;
898951
     size_t i;
898951
     int n;
898951
+    char *str = NULL;
898951
+    bool migratable = true;
898951
+    struct x86_feature *migrate_blocker = NULL;
898951
 
898951
     if (!(feature = x86FeatureNew()))
898951
         goto error;
9119d9
@@ -694,6 +720,10 @@ x86FeatureLoad(xmlXPathContextPtr ctxt,
898951
         goto ignore;
898951
     }
898951
 
898951
+    str = virXPathString("string(@migratable)", ctxt);
898951
+    if (STREQ_NULLABLE(str, "no"))
898951
+        migratable = false;
898951
+
898951
     n = virXPathNodeSet("./cpuid", ctxt, &nodes);
898951
     if (n < 0)
898951
         goto ignore;
9119d9
@@ -710,9 +740,17 @@ x86FeatureLoad(xmlXPathContextPtr ctxt,
898951
             goto error;
898951
     }
898951
 
9119d9
-    if (map->features == NULL)
898951
+    if (!migratable) {
898951
+        if ((migrate_blocker = x86FeatureCopy(feature)) == NULL)
898951
+            goto error;
898951
+
898951
+        migrate_blocker->next = map->migrate_blockers;
898951
+        map->migrate_blockers = migrate_blocker;
898951
+    }
898951
+
9119d9
+    if (map->features == NULL) {
898951
         map->features = feature;
9119d9
-    else {
9119d9
+    } else {
9119d9
         feature->next = map->features;
9119d9
         map->features = feature;
9119d9
     }
9119d9
@@ -720,6 +758,7 @@ x86FeatureLoad(xmlXPathContextPtr ctxt,
9119d9
  out:
898951
     ctxt->node = ctxt_node;
898951
     VIR_FREE(nodes);
898951
+    VIR_FREE(str);
898951
 
898951
     return ret;
898951
 
9119d9
@@ -728,6 +767,7 @@ x86FeatureLoad(xmlXPathContextPtr ctxt,
898951
 
9119d9
  ignore:
898951
     x86FeatureFree(feature);
898951
+    x86FeatureFree(migrate_blocker);
898951
     goto out;
898951
 }
898951
 
9119d9
@@ -1093,6 +1133,12 @@ x86MapFree(struct x86_map *map)
898951
         x86VendorFree(vendor);
898951
     }
898951
 
898951
+    while (map->migrate_blockers != NULL) {
898951
+        struct x86_feature *migrate_blocker = map->migrate_blockers;
898951
+        map->migrate_blockers = migrate_blocker->next;
898951
+        x86FeatureFree(migrate_blocker);
898951
+    }
898951
+
898951
     VIR_FREE(map);
898951
 }
898951
 
9119d9
@@ -2025,16 +2071,15 @@ x86UpdateHostModel(virCPUDefPtr guest,
9119d9
                    const virCPUDef *host)
898951
 {
898951
     virCPUDefPtr oldguest = NULL;
898951
+    const struct x86_map *map;
898951
+    const struct x86_feature *feat;
898951
     size_t i;
898951
     int ret = -1;
898951
 
898951
     guest->match = VIR_CPU_MATCH_EXACT;
898951
 
898951
-    /* no updates are required */
898951
-    if (guest->nfeatures == 0) {
898951
-        virCPUDefFreeModel(guest);
898951
-        return virCPUDefCopyModel(guest, host, true);
898951
-    }
898951
+    if (!(map = virCPUx86GetMap()))
898951
+        goto cleanup;
898951
 
898951
     /* update the host model according to the desired configuration */
898951
     if (!(oldguest = virCPUDefCopy(guest)))
9119d9
@@ -2044,6 +2089,16 @@ x86UpdateHostModel(virCPUDefPtr guest,
898951
     if (virCPUDefCopyModel(guest, host, true) < 0)
898951
         goto cleanup;
898951
 
898951
+    /* Remove non-migratable features by default
898951
+     * Note: this only works as long as no CPU model contains non-migratable
898951
+     * features directly */
898951
+    for (i = 0; i < guest->nfeatures; i++) {
898951
+        for (feat = map->migrate_blockers; feat; feat = feat->next) {
898951
+            if (STREQ(feat->name, guest->features[i].name))
898951
+                VIR_DELETE_ELEMENT_INPLACE(guest->features, i, guest->nfeatures);
898951
+        }
898951
+    }
898951
+
898951
     for (i = 0; i < oldguest->nfeatures; i++) {
898951
         if (virCPUDefUpdateFeature(guest,
898951
                                    oldguest->features[i].name,
898951
diff --git a/tests/cputest.c b/tests/cputest.c
9119d9
index 38cd71e..0ddf82a 100644
898951
--- a/tests/cputest.c
898951
+++ b/tests/cputest.c
9119d9
@@ -599,6 +599,7 @@ mymain(void)
898951
     DO_TEST_UPDATE("x86", "host", "host-model", VIR_CPU_COMPARE_IDENTICAL);
898951
     DO_TEST_UPDATE("x86", "host", "host-model-nofallback", VIR_CPU_COMPARE_IDENTICAL);
898951
     DO_TEST_UPDATE("x86", "host", "host-passthrough", VIR_CPU_COMPARE_IDENTICAL);
898951
+    DO_TEST_UPDATE("x86", "host-invtsc", "host-model", VIR_CPU_COMPARE_SUPERSET);
898951
 
898951
     /* computing baseline CPUs */
9119d9
     DO_TEST_BASELINE("x86", "incompatible-vendors", 0, -1);
898951
diff --git a/tests/cputestdata/x86-host-invtsc+host-model.xml b/tests/cputestdata/x86-host-invtsc+host-model.xml
898951
new file mode 100644
898951
index 0000000..ad1bbf8
898951
--- /dev/null
898951
+++ b/tests/cputestdata/x86-host-invtsc+host-model.xml
898951
@@ -0,0 +1,22 @@
898951
+<cpu mode='host-model' match='exact'>
898951
+  <model fallback='allow'>SandyBridge</model>
898951
+  <vendor>Intel</vendor>
898951
+  <feature policy='require' name='osxsave'/>
898951
+  <feature policy='require' name='pcid'/>
898951
+  <feature policy='require' name='pdcm'/>
898951
+  <feature policy='require' name='xtpr'/>
898951
+  <feature policy='require' name='tm2'/>
898951
+  <feature policy='require' name='est'/>
898951
+  <feature policy='require' name='smx'/>
898951
+  <feature policy='require' name='vmx'/>
898951
+  <feature policy='require' name='ds_cpl'/>
898951
+  <feature policy='require' name='monitor'/>
898951
+  <feature policy='require' name='dtes64'/>
898951
+  <feature policy='require' name='pbe'/>
898951
+  <feature policy='require' name='tm'/>
898951
+  <feature policy='require' name='ht'/>
898951
+  <feature policy='require' name='ss'/>
898951
+  <feature policy='require' name='acpi'/>
898951
+  <feature policy='require' name='ds'/>
898951
+  <feature policy='require' name='vme'/>
898951
+</cpu>
898951
diff --git a/tests/cputestdata/x86-host-invtsc.xml b/tests/cputestdata/x86-host-invtsc.xml
898951
new file mode 100644
898951
index 0000000..f558399
898951
--- /dev/null
898951
+++ b/tests/cputestdata/x86-host-invtsc.xml
898951
@@ -0,0 +1,27 @@
898951
+<cpu>
898951
+  <arch>x86_64</arch>
898951
+  <model>SandyBridge</model>
898951
+  <vendor>Intel</vendor>
898951
+  <topology sockets='1' cores='2' threads='2'/>
898951
+  <feature name='invtsc'/>
898951
+  <feature name='osxsave'/>
898951
+  <feature name='pcid'/>
898951
+  <feature name='pdcm'/>
898951
+  <feature name='xtpr'/>
898951
+  <feature name='tm2'/>
898951
+  <feature name='est'/>
898951
+  <feature name='smx'/>
898951
+  <feature name='vmx'/>
898951
+  <feature name='ds_cpl'/>
898951
+  <feature name='monitor'/>
898951
+  <feature name='dtes64'/>
898951
+  <feature name='pbe'/>
898951
+  <feature name='tm'/>
898951
+  <feature name='ht'/>
898951
+  <feature name='ss'/>
898951
+  <feature name='acpi'/>
898951
+  <feature name='ds'/>
898951
+  <feature name='vme'/>
898951
+  <pages unit='KiB' size='4'/>
898951
+  <pages unit='KiB' size='2048'/>
898951
+</cpu>
898951
-- 
9119d9
2.1.0
898951