virt-manager/virtinst-use-cpu-from-domcapabilities.patch
2018-03-27 19:49:18 +00:00

132 lines
5.0 KiB
Diff

References: bsc#1086038
The issue is when the host has been updated with microcode for Spectre v2
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. Setting
the model to the 'IBRS' version in the installation XML will cause qemu to
fail because of an unknown CPU model.
When the capabilities CPU does not match the domcapabilities CPU,
leave the model unset in the cpu mode XML.
Index: virt-manager-1.5.0/virtinst/domcapabilities.py
===================================================================
--- virt-manager-1.5.0.orig/virtinst/domcapabilities.py
+++ virt-manager-1.5.0/virtinst/domcapabilities.py
@@ -41,9 +41,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 [m.model for m 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]
@@ -52,6 +70,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):
@@ -65,6 +89,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_ROOT_NAME = "devices"
hostdev = XMLChildProperty(_make_capsblock("hostdev"), is_single=True)
@@ -163,6 +192,7 @@ class DomainCapabilities(XMLBuilder):
_XML_ROOT_NAME = "domainCapabilities"
os = XMLChildProperty(_OS, is_single=True)
+ cpu = XMLChildProperty(_CPU, is_single=True)
devices = XMLChildProperty(_Devices, is_single=True)
arch = XMLProperty("./arch")
Index: virt-manager-1.5.0/virtinst/cpu.py
===================================================================
--- virt-manager-1.5.0.orig/virtinst/cpu.py
+++ virt-manager-1.5.0/virtinst/cpu.py
@@ -17,7 +17,9 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA.
+from .domcapabilities import DomainCapabilities
from .xmlbuilder import XMLBuilder, XMLProperty, XMLChildProperty
+import logging
class _CPUCellSibling(XMLBuilder):
@@ -96,7 +98,7 @@ class CPU(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 or
val == self.SPECIAL_MODE_HOST_COPY):
@@ -118,6 +120,15 @@ class CPU(XMLBuilder):
if self.conn.caps.host.cpu.model:
self.clear()
self.model = self.conn.caps.host.cpu.model
+ if guest:
+ domcaps = DomainCapabilities.build_from_guest(guest)
+ domcaps_model = domcaps.cpu.get_mode("host-model").get_models()
+ if (isinstance(domcaps_model, list) and len(domcaps_model) and
+ domcaps_model[0] != self.conn.caps.host.cpu.model):
+ logging.debug("Host capabilities CPU '%s' does not match "
+ "domain capabilities CPU '%s'. Leaving CPU model unset.",
+ self.conn.caps.host.cpu.model, domcaps_model[0])
+ self.model = None
else:
raise RuntimeError("programming error: unknown "
"special cpu mode '%s'" % val)
Index: virt-manager-1.5.0/virtinst/guest.py
===================================================================
--- virt-manager-1.5.0.orig/virtinst/guest.py
+++ virt-manager-1.5.0/virtinst/guest.py
@@ -930,7 +930,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")