[PATCH] [RFC] CPU model capabilities vs domcapabilities

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The issue is when the host has been updated with microcode for Spectre
but qemu has _not_ been updated. In this scenario (as an example),
'virsh capabilities' shows the host cpu model as IvyBridge-IBRS, which is
correct. However, 'virsh domcapabilities' shows IvyBridge as the host-model
and does not show any of the '-IBRS' flavors available under the custom model,
which is also correct since the qemu does not have Spectre patches.

Be default, virt-manager uses 'custom' for the cpu mode XML. For example,

  <cpu mode="custom" match="exact">
    <model>IvyBridge-IBRS</model>
  </cpu>

Starting an installation in the above scenario will fail because qemu
doesn't understand '-IBRS' but will be okay using the domcapabilities
model which does not contain '-IBRS'.

The patch below pulls the cpu model from domcapabilites instead of
capabilities. Not sure this is the right way to go so please chime in on
how you think this problem could be solved.

Thanks


Signed-off-by: Charles Arnold <carnold@xxxxxxxx>

diff --git a/virtinst/domain/cpu.py b/virtinst/domain/cpu.py
index 3c1089c..b3607ea 100644
--- a/virtinst/domain/cpu.py
+++ b/virtinst/domain/cpu.py
@@ -6,6 +6,7 @@
 # See the COPYING file in the top-level directory.
 
 from ..xmlbuilder import XMLBuilder, XMLProperty, XMLChildProperty
+from .domcapabilities import DomainCapabilities
 
 
 class _CPUCellSibling(XMLBuilder):
@@ -79,7 +80,7 @@ class DomainCpu(XMLBuilder):
     SPECIAL_MODES = [SPECIAL_MODE_HOST_MODEL_ONLY, SPECIAL_MODE_HV_DEFAULT,
                      SPECIAL_MODE_HOST_COPY, SPECIAL_MODE_HOST_MODEL,
                      SPECIAL_MODE_HOST_PASSTHROUGH, SPECIAL_MODE_CLEAR]
-    def set_special_mode(self, val):
+    def set_special_mode(self, val, guest=None):
         if (val == self.SPECIAL_MODE_HOST_MODEL or
             val == self.SPECIAL_MODE_HOST_PASSTHROUGH):
             self.model = None
@@ -94,7 +95,16 @@ class DomainCpu(XMLBuilder):
               val == self.SPECIAL_MODE_CLEAR):
             self.clear()
         elif val == self.SPECIAL_MODE_HOST_MODEL_ONLY:
-            if self.conn.caps.host.cpu.model:
+            domcaps_model = None
+            if guest:
+                domcaps = DomainCapabilities.build_from_guest(guest)
+                model = domcaps.cpu.get_mode("host-model").get_models()
+                if len(model):
+                    domcaps_model = model[0]
+            if domcaps_model:
+                self.clear()
+                self.model = domcaps_model
+            elif self.conn.caps.host.cpu.model:
                 self.clear()
                 self.model = self.conn.caps.host.cpu.model
         else:
diff --git a/virtinst/domcapabilities.py b/virtinst/domcapabilities.py
index f98c807..cae1fb2 100644
--- a/virtinst/domcapabilities.py
+++ b/virtinst/domcapabilities.py
@@ -29,9 +29,27 @@ class _Enum(_HasValues):
     name = XMLProperty("./@name")
 
 
+class _Model(XMLBuilder):
+    _XML_ROOT_NAME = "model"
+    model = XMLProperty(".")
+
+
+class _HasModels(XMLBuilder):
+    models = XMLChildProperty(_Model)
+
+    def get_models(self):
+        return [v.model for v in self.models]
+
+
+class _CPUMode(_HasModels):
+    _XML_ROOT_NAME = "mode"
+    name = XMLProperty("./@name")
+
+
 class _CapsBlock(_HasValues):
     supported = XMLProperty("./@supported", is_yesno=True)
     enums = XMLChildProperty(_Enum)
+    modes = XMLChildProperty(_CPUMode)
 
     def enum_names(self):
         return [e.name for e in self.enums]
@@ -40,6 +58,12 @@ class _CapsBlock(_HasValues):
         d = dict((e.name, e) for e in self.enums)
         return d[name]
 
+    def mode_names(self):
+        return [m.name for m in self.modes]
+
+    def get_mode(self, name):
+        d = dict((m.name, m) for m in self.modes)
+        return d[name]
 
 def _make_capsblock(xml_root_name):
     class TmpClass(_CapsBlock):
@@ -53,6 +77,11 @@ class _OS(_CapsBlock):
     loader = XMLChildProperty(_make_capsblock("loader"), is_single=True)
 
 
+class _CPU(_CapsBlock):
+    _XML_ROOT_NAME = "cpu"
+    mode = XMLChildProperty(_make_capsblock("mode"), is_single=True)
+
+
 class _Devices(_CapsBlock):
     XML_NAME = "devices"
     hostdev = XMLChildProperty(_make_capsblock("hostdev"), is_single=True)
@@ -151,6 +180,7 @@ class DomainCapabilities(XMLBuilder):
 
     XML_NAME = "domainCapabilities"
     os = XMLChildProperty(_OS, is_single=True)
+    cpu = XMLChildProperty(_CPU, is_single=True)
     devices = XMLChildProperty(_Devices, is_single=True)
 
     arch = XMLProperty("./arch")
diff --git a/virtinst/guest.py b/virtinst/guest.py
index 5e7d807..35d162c 100644
--- a/virtinst/guest.py
+++ b/virtinst/guest.py
@@ -868,7 +868,7 @@ class Guest(XMLBuilder):
             if self.os.arch != self.conn.caps.host.cpu.arch:
                 return
 
-            self.cpu.set_special_mode(self.x86_cpu_default)
+            self.cpu.set_special_mode(self.x86_cpu_default, self)
             if self._os_object.broken_x2apic():
                 self.cpu.add_feature("x2apic", policy="disable")
 

_______________________________________________
virt-tools-list mailing list
virt-tools-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/virt-tools-list



[Index of Archives]     [Linux Virtualization]     [KVM Development]     [CentOS Virtualization]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]     [Video 4 Linux]

  Powered by Linux