Blame SOURCES/virt-manager-cpu-Have-host-copy-use-domcaps-if-qemu-is-new-enough-bz-1637767.patch

e4cbec
From 83eb392c410394be09c234d74bba44eb9ade9331 Mon Sep 17 00:00:00 2001
e4cbec
Message-Id: <83eb392c410394be09c234d74bba44eb9ade9331@dist-git>
e4cbec
From: Pavel Hrdina <phrdina@redhat.com>
e4cbec
Date: Sat, 13 Oct 2018 17:47:31 -0400
e4cbec
Subject: [PATCH] cpu: Have host-copy use domcaps if qemu is new enough (bz
e4cbec
 1637767)
e4cbec
e4cbec
From: Cole Robinson <crobinso@redhat.com>
e4cbec
e4cbec
capabilities is known problematic. Use domcaps if libvirt+qemu
e4cbec
reports working host-model
e4cbec
e4cbec
https://bugzilla.redhat.com/show_bug.cgi?id=1637767
e4cbec
(cherry picked from commit b051b6c95d8adca7f7ec6a8d582e62d6427d28e3)
e4cbec
e4cbec
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1525337
e4cbec
e4cbec
Conflicts:
e4cbec
    - _XML_ROOT_NAME is renamed to XML_NAME in upstream
e4cbec
e4cbec
Reviewed-by: Cole Robinson <crobinso@redhat.com>
e4cbec
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
e4cbec
---
e4cbec
 .../virt-install-kvm-hostcopy-fallback.xml    | 157 ++++++++++++++++++
e4cbec
 .../virt-install-singleton-config-1.xml       |  16 +-
e4cbec
 tests/clitest.py                              |   3 +-
e4cbec
 tests/xmlparse.py                             |   2 +-
e4cbec
 virtinst/cpu.py                               |  30 +++-
e4cbec
 virtinst/domcapabilities.py                   |  12 +-
e4cbec
 6 files changed, 207 insertions(+), 13 deletions(-)
e4cbec
 create mode 100644 tests/cli-test-xml/compare/virt-install-kvm-hostcopy-fallback.xml
e4cbec
e4cbec
diff --git a/tests/cli-test-xml/compare/virt-install-kvm-hostcopy-fallback.xml b/tests/cli-test-xml/compare/virt-install-kvm-hostcopy-fallback.xml
e4cbec
new file mode 100644
e4cbec
index 00000000..7ca064e2
e4cbec
--- /dev/null
e4cbec
+++ b/tests/cli-test-xml/compare/virt-install-kvm-hostcopy-fallback.xml
e4cbec
@@ -0,0 +1,157 @@
e4cbec
+<domain type="kvm">
e4cbec
+  <name>foobar</name>
e4cbec
+  <uuid>00000000-1111-2222-3333-444444444444</uuid>
e4cbec
+  <memory>65536</memory>
e4cbec
+  <currentMemory>65536</currentMemory>
e4cbec
+  <vcpu>1</vcpu>
e4cbec
+  <os>
e4cbec
+    <type arch="x86_64">hvm</type>
e4cbec
+    <boot dev="network"/>
e4cbec
+  </os>
e4cbec
+  <features>
e4cbec
+    <acpi/>
e4cbec
+    <apic/>
e4cbec
+    <vmport state="off"/>
e4cbec
+  </features>
e4cbec
+  <cpu mode="custom" match="exact">
e4cbec
+    <model>Opteron_G4</model>
e4cbec
+    <vendor>AMD</vendor>
e4cbec
+    <feature name="invtsc"/>
e4cbec
+    <feature name="perfctr_nb"/>
e4cbec
+    <feature name="perfctr_core"/>
e4cbec
+    <feature name="topoext"/>
e4cbec
+    <feature name="nodeid_msr"/>
e4cbec
+    <feature name="lwp"/>
e4cbec
+    <feature name="wdt"/>
e4cbec
+    <feature name="skinit"/>
e4cbec
+    <feature name="ibs"/>
e4cbec
+    <feature name="osvw"/>
e4cbec
+    <feature name="cr8legacy"/>
e4cbec
+    <feature name="extapic"/>
e4cbec
+    <feature name="cmp_legacy"/>
e4cbec
+    <feature name="fxsr_opt"/>
e4cbec
+    <feature name="mmxext"/>
e4cbec
+    <feature name="osxsave"/>
e4cbec
+    <feature name="monitor"/>
e4cbec
+    <feature name="ht"/>
e4cbec
+    <feature name="vme"/>
e4cbec
+  </cpu>
e4cbec
+  <clock offset="utc">
e4cbec
+    <timer name="rtc" tickpolicy="catchup"/>
e4cbec
+    <timer name="pit" tickpolicy="delay"/>
e4cbec
+    <timer name="hpet" present="no"/>
e4cbec
+  </clock>
e4cbec
+  <on_reboot>destroy</on_reboot>
e4cbec
+  <pm>
e4cbec
+    <suspend-to-mem enabled="no"/>
e4cbec
+    <suspend-to-disk enabled="no"/>
e4cbec
+  </pm>
e4cbec
+  <devices>
e4cbec
+    <emulator>/usr/bin/qemu-kvm</emulator>
e4cbec
+    <controller type="usb" index="0" model="ich9-ehci1"/>
e4cbec
+    <controller type="usb" index="0" model="ich9-uhci1">
e4cbec
+      <master startport="0"/>
e4cbec
+    </controller>
e4cbec
+    <controller type="usb" index="0" model="ich9-uhci2">
e4cbec
+      <master startport="2"/>
e4cbec
+    </controller>
e4cbec
+    <controller type="usb" index="0" model="ich9-uhci3">
e4cbec
+      <master startport="4"/>
e4cbec
+    </controller>
e4cbec
+    <interface type="bridge">
e4cbec
+      <source bridge="eth0"/>
e4cbec
+      <mac address="00:11:22:33:44:55"/>
e4cbec
+    </interface>
e4cbec
+    <graphics type="spice" port="-1" tlsPort="-1" autoport="yes">
e4cbec
+      <image compression="off"/>
e4cbec
+    </graphics>
e4cbec
+    <console type="pty"/>
e4cbec
+    <channel type="spicevmc">
e4cbec
+      <target type="virtio" name="com.redhat.spice.0"/>
e4cbec
+    </channel>
e4cbec
+    <sound model="ich6"/>
e4cbec
+    <video>
e4cbec
+      <model type="qxl"/>
e4cbec
+    </video>
e4cbec
+    <redirdev bus="usb" type="spicevmc"/>
e4cbec
+    <redirdev bus="usb" type="spicevmc"/>
e4cbec
+  </devices>
e4cbec
+</domain>
e4cbec
+<domain type="kvm">
e4cbec
+  <name>foobar</name>
e4cbec
+  <uuid>00000000-1111-2222-3333-444444444444</uuid>
e4cbec
+  <memory>65536</memory>
e4cbec
+  <currentMemory>65536</currentMemory>
e4cbec
+  <vcpu>1</vcpu>
e4cbec
+  <os>
e4cbec
+    <type arch="x86_64">hvm</type>
e4cbec
+    <boot dev="network"/>
e4cbec
+  </os>
e4cbec
+  <features>
e4cbec
+    <acpi/>
e4cbec
+    <apic/>
e4cbec
+    <vmport state="off"/>
e4cbec
+  </features>
e4cbec
+  <cpu mode="custom" match="exact">
e4cbec
+    <model>Opteron_G4</model>
e4cbec
+    <vendor>AMD</vendor>
e4cbec
+    <feature name="invtsc"/>
e4cbec
+    <feature name="perfctr_nb"/>
e4cbec
+    <feature name="perfctr_core"/>
e4cbec
+    <feature name="topoext"/>
e4cbec
+    <feature name="nodeid_msr"/>
e4cbec
+    <feature name="lwp"/>
e4cbec
+    <feature name="wdt"/>
e4cbec
+    <feature name="skinit"/>
e4cbec
+    <feature name="ibs"/>
e4cbec
+    <feature name="osvw"/>
e4cbec
+    <feature name="cr8legacy"/>
e4cbec
+    <feature name="extapic"/>
e4cbec
+    <feature name="cmp_legacy"/>
e4cbec
+    <feature name="fxsr_opt"/>
e4cbec
+    <feature name="mmxext"/>
e4cbec
+    <feature name="osxsave"/>
e4cbec
+    <feature name="monitor"/>
e4cbec
+    <feature name="ht"/>
e4cbec
+    <feature name="vme"/>
e4cbec
+  </cpu>
e4cbec
+  <clock offset="utc">
e4cbec
+    <timer name="rtc" tickpolicy="catchup"/>
e4cbec
+    <timer name="pit" tickpolicy="delay"/>
e4cbec
+    <timer name="hpet" present="no"/>
e4cbec
+  </clock>
e4cbec
+  <pm>
e4cbec
+    <suspend-to-mem enabled="no"/>
e4cbec
+    <suspend-to-disk enabled="no"/>
e4cbec
+  </pm>
e4cbec
+  <devices>
e4cbec
+    <emulator>/usr/bin/qemu-kvm</emulator>
e4cbec
+    <controller type="usb" index="0" model="ich9-ehci1"/>
e4cbec
+    <controller type="usb" index="0" model="ich9-uhci1">
e4cbec
+      <master startport="0"/>
e4cbec
+    </controller>
e4cbec
+    <controller type="usb" index="0" model="ich9-uhci2">
e4cbec
+      <master startport="2"/>
e4cbec
+    </controller>
e4cbec
+    <controller type="usb" index="0" model="ich9-uhci3">
e4cbec
+      <master startport="4"/>
e4cbec
+    </controller>
e4cbec
+    <interface type="bridge">
e4cbec
+      <source bridge="eth0"/>
e4cbec
+      <mac address="00:11:22:33:44:55"/>
e4cbec
+    </interface>
e4cbec
+    <graphics type="spice" port="-1" tlsPort="-1" autoport="yes">
e4cbec
+      <image compression="off"/>
e4cbec
+    </graphics>
e4cbec
+    <console type="pty"/>
e4cbec
+    <channel type="spicevmc">
e4cbec
+      <target type="virtio" name="com.redhat.spice.0"/>
e4cbec
+    </channel>
e4cbec
+    <sound model="ich6"/>
e4cbec
+    <video>
e4cbec
+      <model type="qxl"/>
e4cbec
+    </video>
e4cbec
+    <redirdev bus="usb" type="spicevmc"/>
e4cbec
+    <redirdev bus="usb" type="spicevmc"/>
e4cbec
+  </devices>
e4cbec
+</domain>
e4cbec
diff --git a/tests/cli-test-xml/compare/virt-install-singleton-config-1.xml b/tests/cli-test-xml/compare/virt-install-singleton-config-1.xml
e4cbec
index fc22e0ac..40041451 100644
e4cbec
--- a/tests/cli-test-xml/compare/virt-install-singleton-config-1.xml
e4cbec
+++ b/tests/cli-test-xml/compare/virt-install-singleton-config-1.xml
e4cbec
@@ -23,7 +23,21 @@
e4cbec
     <acpi/>
e4cbec
     <vmport state="off"/>
e4cbec
   </features>
e4cbec
-  <cpu mode="host-model"/>
e4cbec
+  <cpu mode="custom" match="exact">
e4cbec
+    <model fallback="forbid">Broadwell</model>
e4cbec
+    <vendor>Intel</vendor>
e4cbec
+    <feature policy="require" name="vme"/>
e4cbec
+    <feature policy="require" name="ss"/>
e4cbec
+    <feature policy="require" name="f16c"/>
e4cbec
+    <feature policy="require" name="rdrand"/>
e4cbec
+    <feature policy="require" name="hypervisor"/>
e4cbec
+    <feature policy="require" name="arat"/>
e4cbec
+    <feature policy="require" name="tsc_adjust"/>
e4cbec
+    <feature policy="require" name="xsaveopt"/>
e4cbec
+    <feature policy="require" name="pdpe1gb"/>
e4cbec
+    <feature policy="require" name="abm"/>
e4cbec
+    <feature policy="require" name="invtsc"/>
e4cbec
+  </cpu>
e4cbec
   <clock offset="localtime">
e4cbec
     <timer name="rtc" tickpolicy="catchup"/>
e4cbec
     <timer name="pit" tickpolicy="delay"/>
e4cbec
diff --git a/tests/clitest.py b/tests/clitest.py
e4cbec
index 23d4f109..eb608769 100644
e4cbec
--- a/tests/clitest.py
e4cbec
+++ b/tests/clitest.py
e4cbec
@@ -389,7 +389,7 @@ c = vinst.add_category("xml-comparsion", "--connect %(URI-KVM)s --noautoconsole
e4cbec
 c.add_compare(""" \
e4cbec
 --memory 1024 \
e4cbec
 --vcpus 4 --cpuset=1,3-5 \
e4cbec
---cpu host \
e4cbec
+--cpu host-copy \
e4cbec
 --description \"foobar & baz\" \
e4cbec
 --boot uefi \
e4cbec
 --security type=dynamic \
e4cbec
@@ -806,6 +806,7 @@ c.add_compare("--disk none --location nfs:example.com/fake --nonetworks", "locat
e4cbec
 c.add_compare("--disk %(EXISTIMG1)s --pxe --os-variant rhel6.4", "kvm-rhel6")  # RHEL6 defaults
e4cbec
 c.add_compare("--disk %(EXISTIMG1)s --pxe --os-variant rhel7.0", "kvm-rhel7")  # RHEL7 defaults
e4cbec
 c.add_compare("--connect " + utils.uri_kvm_nodomcaps + " --disk %(EXISTIMG1)s --pxe --os-variant rhel7.0", "kvm-cpu-default-fallback")  # No domcaps, so mode=host-model isn't safe, so we fallback to host-model-only
e4cbec
+c.add_compare("--connect " + utils.uri_kvm_nodomcaps + " --cpu host-copy --disk none --pxe", "kvm-hostcopy-fallback")  # No domcaps so need to use capabilities for CPU host-copy
e4cbec
 c.add_compare("--disk %(EXISTIMG1)s --pxe --os-variant centos7.0", "kvm-centos7")  # Centos 7 defaults
e4cbec
 c.add_compare("--os-variant win7 --cdrom %(EXISTIMG2)s --boot loader_type=pflash,loader=CODE.fd,nvram_template=VARS.fd --disk %(EXISTIMG1)s", "win7-uefi")  # no HYPER-V with UEFI
e4cbec
 c.add_compare("--machine q35 --cdrom %(EXISTIMG2)s --disk %(EXISTIMG1)s", "q35-defaults")  # proper q35 disk defaults
e4cbec
diff --git a/tests/xmlparse.py b/tests/xmlparse.py
e4cbec
index 35b237ea..e7d291f3 100644
e4cbec
--- a/tests/xmlparse.py
e4cbec
+++ b/tests/xmlparse.py
e4cbec
@@ -1362,7 +1362,7 @@ class XMLParseTest(unittest.TestCase):
e4cbec
         outfile = "tests/xmlparse-xml/%s-out.xml" % basename
e4cbec
         guest = virtinst.Guest(kvmconn, parsexml=open(infile).read())
e4cbec
 
e4cbec
-        guest.cpu.copy_host_cpu()
e4cbec
+        guest.cpu.copy_host_cpu(guest)
e4cbec
         guest.cpu.clear()
e4cbec
         utils.diff_compare(guest.get_xml_config(), outfile)
e4cbec
 
e4cbec
diff --git a/virtinst/cpu.py b/virtinst/cpu.py
e4cbec
index 356df206..f109445c 100644
e4cbec
--- a/virtinst/cpu.py
e4cbec
+++ b/virtinst/cpu.py
e4cbec
@@ -118,7 +118,7 @@ class CPU(XMLBuilder):
e4cbec
                 self.remove_feature(f)
e4cbec
             self.mode = val
e4cbec
         elif val == self.SPECIAL_MODE_HOST_COPY:
e4cbec
-            self.copy_host_cpu()
e4cbec
+            self.copy_host_cpu(guest)
e4cbec
         elif (val == self.SPECIAL_MODE_HV_DEFAULT or
e4cbec
               val == self.SPECIAL_MODE_CLEAR):
e4cbec
             self.clear()
e4cbec
@@ -154,24 +154,36 @@ class CPU(XMLBuilder):
e4cbec
         self.add_child(obj)
e4cbec
         return obj
e4cbec
 
e4cbec
-    def copy_host_cpu(self):
e4cbec
+    def copy_host_cpu(self, guest):
e4cbec
         """
e4cbec
-        Enact the equivalent of qemu -cpu host, pulling all info
e4cbec
-        from capabilities about the host CPU
e4cbec
+        Try to manually mimic host-model, copying all the info
e4cbec
+        preferably out of domcapabilities, but capabilities as fallback.
e4cbec
         """
e4cbec
-        cpu = self.conn.caps.host.cpu
e4cbec
-        if not cpu.model:
e4cbec
-            raise ValueError(_("No host CPU reported in capabilities"))
e4cbec
+        domcaps = guest.lookup_domcaps()
e4cbec
+        if domcaps.supports_safe_host_model():
e4cbec
+            logging.debug("Using domcaps for host-copy")
e4cbec
+            cpu = domcaps.cpu.get_mode("host-model")
e4cbec
+            model = cpu.models[0].model
e4cbec
+            fallback = cpu.models[0].fallback
e4cbec
+        else:
e4cbec
+            cpu = self.conn.caps.host.cpu
e4cbec
+            model = cpu.model
e4cbec
+            fallback = None
e4cbec
+            if not model:
e4cbec
+                raise ValueError(_("No host CPU reported in capabilities"))
e4cbec
 
e4cbec
         self.mode = "custom"
e4cbec
         self.match = "exact"
e4cbec
-        self.model = cpu.model
e4cbec
+        self.model = model
e4cbec
+        if fallback:
e4cbec
+            self.model_fallback = fallback
e4cbec
         self.vendor = cpu.vendor
e4cbec
 
e4cbec
         for feature in self.features:
e4cbec
             self.remove_feature(feature)
e4cbec
         for feature in cpu.features:
e4cbec
-            self.add_feature(feature.name)
e4cbec
+            policy = getattr(feature, "policy", "require")
e4cbec
+            self.add_feature(feature.name, policy)
e4cbec
 
e4cbec
     def vcpus_from_topology(self):
e4cbec
         """
e4cbec
diff --git a/virtinst/domcapabilities.py b/virtinst/domcapabilities.py
e4cbec
index 7d7e2af7..ddc8b17c 100644
e4cbec
--- a/virtinst/domcapabilities.py
e4cbec
+++ b/virtinst/domcapabilities.py
e4cbec
@@ -80,19 +80,29 @@ class _CPUModel(XMLBuilder):
e4cbec
     _XML_ROOT_NAME = "model"
e4cbec
     model = XMLProperty(".")
e4cbec
     usable = XMLProperty("./@usable", is_yesno=True)
e4cbec
+    fallback = XMLProperty("./@fallback")
e4cbec
+
e4cbec
+
e4cbec
+class _CPUFeature(XMLBuilder):
e4cbec
+    _XML_ROOT_NAME = "feature"
e4cbec
+    name = XMLProperty("./@name")
e4cbec
+    policy = XMLProperty("./@policy")
e4cbec
 
e4cbec
 
e4cbec
 class _CPUMode(XMLBuilder):
e4cbec
     _XML_ROOT_NAME = "mode"
e4cbec
     name = XMLProperty("./@name")
e4cbec
     supported = XMLProperty("./@supported", is_yesno=True)
e4cbec
+    vendor = XMLProperty("./vendor")
e4cbec
+
e4cbec
     models = XMLChildProperty(_CPUModel)
e4cbec
-
e4cbec
     def get_model(self, name):
e4cbec
         for model in self.models:
e4cbec
             if model.model == name:
e4cbec
                 return model
e4cbec
 
e4cbec
+    features = XMLChildProperty(_CPUFeature)
e4cbec
+
e4cbec
 
e4cbec
 class _CPU(XMLBuilder):
e4cbec
     _XML_ROOT_NAME = "cpu"
e4cbec
-- 
e4cbec
2.20.1
e4cbec