[libvirt] [PATCH 13/14] cpu: Avoid adding <vendor> to custom CPUs

Jiri Denemark jdenemar at redhat.com
Thu Nov 10 22:39:38 UTC 2016


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 at redhat.com>
---
 src/conf/cpu_conf.c                                | 28 +++++++++++++++++++---
 src/conf/cpu_conf.h                                |  3 ++-
 src/cpu/cpu_arm.c                                  |  2 +-
 src/cpu/cpu_x86.c                                  |  5 ++--
 .../cputestdata/x86-host+guest,model486-result.xml |  1 -
 tests/cputestdata/x86-host+guest,models-result.xml |  1 -
 tests/cputestdata/x86-host+min.xml                 |  1 -
 tests/cputestdata/x86-host+pentium3.xml            |  1 -
 ...-Haswell-noTSX+Haswell-noTSX,haswell-result.xml |  1 -
 .../x86-host-better+pentium3-result.xml            |  1 -
 10 files changed, 31 insertions(+), 13 deletions(-)

diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c
index f174529..9eb69c9 100644
--- a/src/conf/cpu_conf.c
+++ b/src/conf/cpu_conf.c
@@ -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);
+    }
 }
 
 
diff --git a/src/conf/cpu_conf.h b/src/conf/cpu_conf.h
index e084392..cc3fbf0 100644
--- a/src/conf/cpu_conf.h
+++ b/src/conf/cpu_conf.h
@@ -139,7 +139,8 @@ virCPUDefCopyModelFilter(virCPUDefPtr dst,
 
 void
 virCPUDefStealModel(virCPUDefPtr dst,
-                    virCPUDefPtr src);
+                    virCPUDefPtr src,
+                    bool keepVendor);
 
 virCPUDefPtr
 virCPUDefCopy(const virCPUDef *cpu);
diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c
index db603a6..b5002c3 100644
--- a/src/cpu/cpu_arm.c
+++ b/src/cpu/cpu_arm.c
@@ -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;
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index 4f2a111..851ec5d 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -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:
diff --git a/tests/cputestdata/x86-host+guest,model486-result.xml b/tests/cputestdata/x86-host+guest,model486-result.xml
index 88df467..85564ff 100644
--- a/tests/cputestdata/x86-host+guest,model486-result.xml
+++ b/tests/cputestdata/x86-host+guest,model486-result.xml
@@ -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'/>
diff --git a/tests/cputestdata/x86-host+guest,models-result.xml b/tests/cputestdata/x86-host+guest,models-result.xml
index e7a77c2..f79ed32 100644
--- a/tests/cputestdata/x86-host+guest,models-result.xml
+++ b/tests/cputestdata/x86-host+guest,models-result.xml
@@ -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'/>
diff --git a/tests/cputestdata/x86-host+min.xml b/tests/cputestdata/x86-host+min.xml
index a284767..8101151 100644
--- a/tests/cputestdata/x86-host+min.xml
+++ b/tests/cputestdata/x86-host+min.xml
@@ -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'/>
diff --git a/tests/cputestdata/x86-host+pentium3.xml b/tests/cputestdata/x86-host+pentium3.xml
index a284767..8101151 100644
--- a/tests/cputestdata/x86-host+pentium3.xml
+++ b/tests/cputestdata/x86-host+pentium3.xml
@@ -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'/>
diff --git a/tests/cputestdata/x86-host-Haswell-noTSX+Haswell-noTSX,haswell-result.xml b/tests/cputestdata/x86-host-Haswell-noTSX+Haswell-noTSX,haswell-result.xml
index 5902f6c..5d149bb 100644
--- a/tests/cputestdata/x86-host-Haswell-noTSX+Haswell-noTSX,haswell-result.xml
+++ b/tests/cputestdata/x86-host-Haswell-noTSX+Haswell-noTSX,haswell-result.xml
@@ -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'/>
diff --git a/tests/cputestdata/x86-host-better+pentium3-result.xml b/tests/cputestdata/x86-host-better+pentium3-result.xml
index 12336da..9d4f98f 100644
--- a/tests/cputestdata/x86-host-better+pentium3-result.xml
+++ b/tests/cputestdata/x86-host-better+pentium3-result.xml
@@ -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'/>
-- 
2.10.2




More information about the libvir-list mailing list