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