From b527589d1fb15586fc92a299261180489bdc6220 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Tue, 12 Dec 2017 16:23:41 +0100
Subject: [PATCH 5/5] qemu: capabilities: force update if the microcode version
 does not match

A microcode update can cause the CPUID bits to change; an example
from the past was the update that disabled TSX on several Haswell
and Broadwell machines.

Therefore, place microcode version in the virQEMUCaps struct and
XML, and rebuild the cache if the versions do not match.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 src/qemu/qemu_capabilities.c                       | 40 +++++++++++++++++++++-
 src/qemu/qemu_capabilities.h                       |  6 ++--
 src/qemu/qemu_capspriv.h                           |  5 +++
 src/qemu/qemu_driver.c                             |  9 ++++-
 tests/qemucapabilitiesdata/caps_1.2.2.x86_64.xml   |  1 +
 tests/qemucapabilitiesdata/caps_1.3.1.x86_64.xml   |  1 +
 tests/qemucapabilitiesdata/caps_1.4.2.x86_64.xml   |  1 +
 tests/qemucapabilitiesdata/caps_1.5.3.x86_64.xml   |  1 +
 tests/qemucapabilitiesdata/caps_1.6.0.x86_64.xml   |  1 +
 tests/qemucapabilitiesdata/caps_1.7.0.x86_64.xml   |  1 +
 tests/qemucapabilitiesdata/caps_2.1.1.x86_64.xml   |  1 +
 .../caps_2.10.0-gicv2.aarch64.xml                  |  1 +
 .../caps_2.10.0-gicv3.aarch64.xml                  |  1 +
 tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml   |  1 +
 tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml   |  1 +
 tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml  |  1 +
 tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml   |  1 +
 tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml   |  1 +
 .../caps_2.6.0-gicv2.aarch64.xml                   |  1 +
 .../caps_2.6.0-gicv3.aarch64.xml                   |  1 +
 tests/qemucapabilitiesdata/caps_2.6.0.ppc64.xml    |  1 +
 tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml   |  1 +
 tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml    |  1 +
 tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml   |  1 +
 tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml    |  1 +
 tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml   |  1 +
 tests/qemucapabilitiesdata/caps_2.9.0.ppc64.xml    |  1 +
 tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml    |  1 +
 tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml   |  1 +
 tests/qemucapabilitiestest.c                       | 14 +++++---
 tests/qemucapsprobe.c                              |  2 +-
 tests/testutilsqemu.c                              |  2 +-
 32 files changed, 93 insertions(+), 10 deletions(-)

Index: libvirt-3.3.0/src/qemu/qemu_capabilities.c
===================================================================
--- libvirt-3.3.0.orig/src/qemu/qemu_capabilities.c
+++ libvirt-3.3.0/src/qemu/qemu_capabilities.c
@@ -420,6 +420,7 @@ struct _virQEMUCaps {
 
     unsigned int version;
     unsigned int kvmVersion;
+    unsigned int microcodeVersion;
     char *package;
 
     virArch arch;
@@ -2198,6 +2199,7 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEM
 
     ret->version = qemuCaps->version;
     ret->kvmVersion = qemuCaps->kvmVersion;
+    ret->microcodeVersion = qemuCaps->microcodeVersion;
 
     if (VIR_STRDUP(ret->package, qemuCaps->package) < 0)
         goto error;
@@ -3803,6 +3805,13 @@ virQEMUCapsLoadCache(virCapsPtr caps,
         goto cleanup;
     }
 
+    if (virXPathUInt("string(./microcodeVersion)", ctxt,
+                     &qemuCaps->microcodeVersion) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("missing microcode version in QEMU capabilities cache"));
+        goto cleanup;
+    }
+
     if (virXPathBoolean("boolean(./package)", ctxt) > 0) {
         qemuCaps->package = virXPathString("string(./package)", ctxt);
         if (!qemuCaps->package &&
@@ -4069,6 +4078,9 @@ virQEMUCapsFormatCache(virQEMUCapsPtr qe
     virBufferAsprintf(&buf, "<kvmVersion>%d</kvmVersion>\n",
                       qemuCaps->kvmVersion);
 
+    virBufferAsprintf(&buf, "<microcodeVersion>%u</microcodeVersion>\n",
+                      qemuCaps->microcodeVersion);
+
     if (qemuCaps->package)
         virBufferAsprintf(&buf, "<package>%s</package>\n",
                           qemuCaps->package);
@@ -4222,7 +4234,8 @@ virQEMUCapsInitCached(virCapsPtr caps,
                       virQEMUCapsPtr qemuCaps,
                       const char *cacheDir,
                       uid_t runUid,
-                      gid_t runGid)
+                      gid_t runGid,
+                      unsigned int microcodeVersion)
 {
     char *capsdir = NULL;
     char *capsfile = NULL;
@@ -4272,7 +4285,7 @@ virQEMUCapsInitCached(virCapsPtr caps,
         goto discard;
     }
 
-    if (!virQEMUCapsIsValid(qemuCaps, qemuctime, runUid, runGid))
+    if (!virQEMUCapsIsValid(qemuCaps, qemuctime, runUid, runGid, microcodeVersion))
         goto discard;
 
     /* Discard cache if QEMU binary or libvirtd changed */
@@ -5120,6 +5133,7 @@ virQEMUCapsNewForBinaryInternal(virCapsP
                                 const char *cacheDir,
                                 uid_t runUid,
                                 gid_t runGid,
+                                unsigned int microcodeVersion,
                                 bool qmpOnly)
 {
     virQEMUCapsPtr qemuCaps;
@@ -5155,7 +5169,8 @@ virQEMUCapsNewForBinaryInternal(virCapsP
     if (!cacheDir)
         rv = 0;
     else if ((rv = virQEMUCapsInitCached(caps, qemuCaps, cacheDir,
-                                         runUid, runGid)) < 0)
+                                         runUid, runGid,
+                                         microcodeVersion)) < 0)
         goto error;
 
     if (rv == 0) {
@@ -5186,6 +5201,9 @@ virQEMUCapsNewForBinaryInternal(virCapsP
         virQEMUCapsInitHostCPUModel(qemuCaps, caps, VIR_DOMAIN_VIRT_QEMU);
     }
 
+    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
+        qemuCaps->microcodeVersion = microcodeVersion;
+
  cleanup:
     VIR_FREE(qmperr);
     return qemuCaps;
@@ -5202,10 +5220,11 @@ virQEMUCapsNewForBinary(virCapsPtr caps,
                         const char *libDir,
                         const char *cacheDir,
                         uid_t runUid,
-                        gid_t runGid)
+                        gid_t runGid,
+                        unsigned int microcodeVersion)
 {
     return virQEMUCapsNewForBinaryInternal(caps, binary, libDir, cacheDir,
-                                           runUid, runGid, false);
+                                           runUid, runGid, false, microcodeVersion);
 }
 
 
@@ -5213,7 +5232,8 @@ bool
 virQEMUCapsIsValid(virQEMUCapsPtr qemuCaps,
                    time_t qemuctime,
                    uid_t runUid,
-                   gid_t runGid)
+                   gid_t runGid,
+                   unsigned int microcodeVersion)
 {
     bool kvmUsable;
 
@@ -5261,6 +5281,16 @@ virQEMUCapsIsValid(virQEMUCapsPtr qemuCa
         return false;
     }
 
+    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM) &&
+        microcodeVersion != qemuCaps->microcodeVersion) {
+        VIR_DEBUG("Outdated capabilities for '%s': microcode version changed "
+                  "(%u vs %u)",
+                  qemuCaps->binary,
+                  microcodeVersion,
+                  qemuCaps->microcodeVersion);
+        return false;
+    }
+
     return true;
 }
 
@@ -5307,7 +5337,8 @@ virQEMUCapsCachePtr
 virQEMUCapsCacheNew(const char *libDir,
                     const char *cacheDir,
                     uid_t runUid,
-                    gid_t runGid)
+                    gid_t runGid,
+                    unsigned int microcodeVersion)
 {
     virQEMUCapsCachePtr cache;
 
@@ -5330,6 +5361,7 @@ virQEMUCapsCacheNew(const char *libDir,
 
     cache->runUid = runUid;
     cache->runGid = runGid;
+    cache->microcodeVersion = microcodeVersion;
 
     return cache;
 
@@ -5346,7 +5378,8 @@ virQEMUCapsCacheValidate(virQEMUCapsCach
                          virQEMUCapsPtr *qemuCaps)
 {
     if (*qemuCaps &&
-        !virQEMUCapsIsValid(*qemuCaps, 0, cache->runUid, cache->runGid)) {
+        !virQEMUCapsIsValid(*qemuCaps, 0, cache->runUid, cache->runGid,
+                            cache->microcodeVersion)) {
         VIR_DEBUG("Cached capabilities %p no longer valid for %s",
                   *qemuCaps, binary);
         virHashRemoveEntry(cache->binaries, binary);
@@ -5357,7 +5390,8 @@ virQEMUCapsCacheValidate(virQEMUCapsCach
         VIR_DEBUG("Creating capabilities for %s", binary);
         *qemuCaps = virQEMUCapsNewForBinary(caps, binary,
                                             cache->libDir, cache->cacheDir,
-                                            cache->runUid, cache->runGid);
+                                            cache->runUid, cache->runGid,
+                                            cache->microcodeVersion);
         if (*qemuCaps) {
             VIR_DEBUG("Caching capabilities %p for %s", *qemuCaps, binary);
             if (virHashAddEntry(cache->binaries, binary, *qemuCaps) < 0) {
@@ -5871,3 +5905,11 @@ virQEMUCapsFillDomainCaps(virCapsPtr cap
         return -1;
     return 0;
 }
+
+
+void
+virQEMUCapsSetMicrocodeVersion(virQEMUCapsPtr qemuCaps,
+                               unsigned int microcodeVersion)
+{
+    qemuCaps->microcodeVersion = microcodeVersion;
+}
Index: libvirt-3.3.0/src/qemu/qemu_capabilities.h
===================================================================
--- libvirt-3.3.0.orig/src/qemu/qemu_capabilities.h
+++ libvirt-3.3.0/src/qemu/qemu_capabilities.h
@@ -490,14 +490,17 @@ int virQEMUCapsGetMachineTypesCaps(virQE
 bool virQEMUCapsIsValid(virQEMUCapsPtr qemuCaps,
                         time_t ctime,
                         uid_t runUid,
-                        gid_t runGid);
+                        gid_t runGid,
+                        unsigned int microcodeVersion);
 
 void virQEMUCapsFilterByMachineType(virQEMUCapsPtr qemuCaps,
                                     const char *machineType);
 
 virQEMUCapsCachePtr virQEMUCapsCacheNew(const char *libDir,
                                         const char *cacheDir,
-                                        uid_t uid, gid_t gid);
+                                        uid_t uid,
+                                        gid_t gid,
+                                        unsigned int microcodeVersion);
 virQEMUCapsPtr virQEMUCapsCacheLookup(virCapsPtr caps,
                                       virQEMUCapsCachePtr cache,
                                       const char *binary);
Index: libvirt-3.3.0/src/qemu/qemu_capspriv.h
===================================================================
--- libvirt-3.3.0.orig/src/qemu/qemu_capspriv.h
+++ libvirt-3.3.0/src/qemu/qemu_capspriv.h
@@ -35,6 +35,7 @@ struct _virQEMUCapsCache {
     char *cacheDir;
     uid_t runUid;
     gid_t runGid;
+    unsigned int microcodeVersion;
 };
 
 virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps);
@@ -46,6 +47,7 @@ virQEMUCapsNewForBinaryInternal(virCapsP
                                 const char *cacheDir,
                                 uid_t runUid,
                                 gid_t runGid,
+                                unsigned int microcodeVersion,
                                 bool qmpOnly);
 
 int virQEMUCapsLoadCache(virCapsPtr caps,
@@ -115,4 +117,8 @@ virQEMUCapsParseHelpStr(const char *qemu
 int
 virQEMUCapsParseDeviceStr(virQEMUCapsPtr qemuCaps,
                           const char *str);
+
+void
+virQEMUCapsSetMicrocodeVersion(virQEMUCapsPtr qemuCaps,
+                               unsigned int microcodeVersion);
 #endif
Index: libvirt-3.3.0/src/qemu/qemu_driver.c
===================================================================
--- libvirt-3.3.0.orig/src/qemu/qemu_driver.c
+++ libvirt-3.3.0/src/qemu/qemu_driver.c
@@ -628,6 +628,8 @@ qemuStateInitialize(bool privileged,
     gid_t run_gid = -1;
     char *hugepagePath = NULL;
     size_t i;
+    virCPUDefPtr hostCPU = NULL;
+    unsigned int microcodeVersion = 0;
 
     if (VIR_ALLOC(qemu_driver) < 0)
         return -1;
@@ -835,10 +837,15 @@ qemuStateInitialize(bool privileged,
         run_gid = cfg->group;
     }
 
+    if ((hostCPU = virCPUProbeHost(virArchFromHost())))
+        microcodeVersion = hostCPU->microcodeVersion;
+    virCPUDefFree(hostCPU);
+
     qemu_driver->qemuCapsCache = virQEMUCapsCacheNew(cfg->libDir,
                                                      cfg->cacheDir,
                                                      run_uid,
-                                                     run_gid);
+                                                     run_gid,
+                                                     microcodeVersion);
     if (!qemu_driver->qemuCapsCache)
         goto error;
 
Index: libvirt-3.3.0/tests/qemucapabilitiesdata/caps_1.2.2.x86_64.xml
===================================================================
--- libvirt-3.3.0.orig/tests/qemucapabilitiesdata/caps_1.2.2.x86_64.xml
+++ libvirt-3.3.0/tests/qemucapabilitiesdata/caps_1.2.2.x86_64.xml
@@ -111,6 +111,7 @@
   <flag name='query-cpu-definitions'/>
   <version>1002002</version>
   <kvmVersion>0</kvmVersion>
+  <microcodeVersion>26900</microcodeVersion>
   <package></package>
   <arch>x86_64</arch>
   <cpu type='kvm' name='qemu64'/>
Index: libvirt-3.3.0/tests/qemucapabilitiesdata/caps_1.3.1.x86_64.xml
===================================================================
--- libvirt-3.3.0.orig/tests/qemucapabilitiesdata/caps_1.3.1.x86_64.xml
+++ libvirt-3.3.0/tests/qemucapabilitiesdata/caps_1.3.1.x86_64.xml
@@ -129,6 +129,7 @@
   <flag name='query-cpu-definitions'/>
   <version>1003001</version>
   <kvmVersion>0</kvmVersion>
+  <microcodeVersion>30198</microcodeVersion>
   <package></package>
   <arch>x86_64</arch>
   <cpu type='kvm' name='qemu64'/>
Index: libvirt-3.3.0/tests/qemucapabilitiesdata/caps_1.4.2.x86_64.xml
===================================================================
--- libvirt-3.3.0.orig/tests/qemucapabilitiesdata/caps_1.4.2.x86_64.xml
+++ libvirt-3.3.0/tests/qemucapabilitiesdata/caps_1.4.2.x86_64.xml
@@ -130,6 +130,7 @@
   <flag name='query-cpu-definitions'/>
   <version>1004002</version>
   <kvmVersion>0</kvmVersion>
+  <microcodeVersion>30915</microcodeVersion>
   <package></package>
   <arch>x86_64</arch>
   <cpu type='kvm' name='Opteron_G5'/>
Index: libvirt-3.3.0/tests/qemucapabilitiesdata/caps_1.5.3.x86_64.xml
===================================================================
--- libvirt-3.3.0.orig/tests/qemucapabilitiesdata/caps_1.5.3.x86_64.xml
+++ libvirt-3.3.0/tests/qemucapabilitiesdata/caps_1.5.3.x86_64.xml
@@ -142,6 +142,7 @@
   <flag name='kernel-irqchip'/>
   <version>1005003</version>
   <kvmVersion>0</kvmVersion>
+  <microcodeVersion>47019</microcodeVersion>
   <package></package>
   <arch>x86_64</arch>
   <cpu type='kvm' name='Opteron_G5'/>
Index: libvirt-3.3.0/tests/qemucapabilitiesdata/caps_1.6.0.x86_64.xml
===================================================================
--- libvirt-3.3.0.orig/tests/qemucapabilitiesdata/caps_1.6.0.x86_64.xml
+++ libvirt-3.3.0/tests/qemucapabilitiesdata/caps_1.6.0.x86_64.xml
@@ -147,6 +147,7 @@
   <flag name='kernel-irqchip'/>
   <version>1006000</version>
   <kvmVersion>0</kvmVersion>
+  <microcodeVersion>45248</microcodeVersion>
   <package></package>
   <arch>x86_64</arch>
   <cpu type='kvm' name='Opteron_G5'/>
Index: libvirt-3.3.0/tests/qemucapabilitiesdata/caps_1.7.0.x86_64.xml
===================================================================
--- libvirt-3.3.0.orig/tests/qemucapabilitiesdata/caps_1.7.0.x86_64.xml
+++ libvirt-3.3.0/tests/qemucapabilitiesdata/caps_1.7.0.x86_64.xml
@@ -149,6 +149,7 @@
   <flag name='kernel-irqchip'/>
   <version>1007000</version>
   <kvmVersion>0</kvmVersion>
+  <microcodeVersion>50692</microcodeVersion>
   <package></package>
   <arch>x86_64</arch>
   <cpu type='kvm' name='Opteron_G5'/>
Index: libvirt-3.3.0/tests/qemucapabilitiesdata/caps_2.1.1.x86_64.xml
===================================================================
--- libvirt-3.3.0.orig/tests/qemucapabilitiesdata/caps_2.1.1.x86_64.xml
+++ libvirt-3.3.0/tests/qemucapabilitiesdata/caps_2.1.1.x86_64.xml
@@ -165,6 +165,7 @@
   <flag name='kernel-irqchip'/>
   <version>2001001</version>
   <kvmVersion>0</kvmVersion>
+  <microcodeVersion>59488</microcodeVersion>
   <package></package>
   <arch>x86_64</arch>
   <cpu type='kvm' name='Opteron_G5'/>
Index: libvirt-3.3.0/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml
===================================================================
--- libvirt-3.3.0.orig/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml
+++ libvirt-3.3.0/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml
@@ -187,6 +187,7 @@
   <flag name='kernel-irqchip'/>
   <version>2004000</version>
   <kvmVersion>0</kvmVersion>
+  <microcodeVersion>75653</microcodeVersion>
   <package></package>
   <arch>x86_64</arch>
   <cpu type='kvm' name='Opteron_G5'/>
Index: libvirt-3.3.0/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml
===================================================================
--- libvirt-3.3.0.orig/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml
+++ libvirt-3.3.0/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml
@@ -193,6 +193,7 @@
   <flag name='kernel-irqchip'/>
   <version>2005000</version>
   <kvmVersion>0</kvmVersion>
+  <microcodeVersion>216775</microcodeVersion>
   <package></package>
   <arch>x86_64</arch>
   <cpu type='kvm' name='Opteron_G5'/>
Index: libvirt-3.3.0/tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml
===================================================================
--- libvirt-3.3.0.orig/tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml
+++ libvirt-3.3.0/tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml
@@ -171,6 +171,7 @@
   <flag name='kernel-irqchip.split'/>
   <version>2006000</version>
   <kvmVersion>0</kvmVersion>
+  <microcodeVersion>228838</microcodeVersion>
   <package></package>
   <arch>aarch64</arch>
   <cpu type='kvm' name='pxa262'/>
Index: libvirt-3.3.0/tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml
===================================================================
--- libvirt-3.3.0.orig/tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml
+++ libvirt-3.3.0/tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml
@@ -171,6 +171,7 @@
   <flag name='kernel-irqchip.split'/>
   <version>2006000</version>
   <kvmVersion>0</kvmVersion>
+  <microcodeVersion>228838</microcodeVersion>
   <package></package>
   <arch>aarch64</arch>
   <cpu type='kvm' name='pxa262'/>
Index: libvirt-3.3.0/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml
===================================================================
--- libvirt-3.3.0.orig/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml
+++ libvirt-3.3.0/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml
@@ -203,6 +203,7 @@
   <flag name='kernel-irqchip.split'/>
   <version>2006000</version>
   <kvmVersion>0</kvmVersion>
+  <microcodeVersion>227579</microcodeVersion>
   <package></package>
   <arch>x86_64</arch>
   <cpu type='kvm' name='Opteron_G5'/>
Index: libvirt-3.3.0/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml
===================================================================
--- libvirt-3.3.0.orig/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml
+++ libvirt-3.3.0/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml
@@ -133,6 +133,7 @@
   <flag name='kernel-irqchip.split'/>
   <version>2007000</version>
   <kvmVersion>0</kvmVersion>
+  <microcodeVersion>217559</microcodeVersion>
   <package></package>
   <arch>s390x</arch>
   <cpu type='kvm' name='host'/>
Index: libvirt-3.3.0/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml
===================================================================
--- libvirt-3.3.0.orig/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml
+++ libvirt-3.3.0/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml
@@ -206,6 +206,7 @@
   <flag name='intel-iommu.intremap'/>
   <version>2007000</version>
   <kvmVersion>0</kvmVersion>
+  <microcodeVersion>239276</microcodeVersion>
   <package> (v2.7.0)</package>
   <arch>x86_64</arch>
   <cpu type='kvm' name='Opteron_G5'/>
Index: libvirt-3.3.0/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml
===================================================================
--- libvirt-3.3.0.orig/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml
+++ libvirt-3.3.0/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml
@@ -135,6 +135,7 @@
   <flag name='kernel-irqchip.split'/>
   <version>2007093</version>
   <kvmVersion>0</kvmVersion>
+  <microcodeVersion>242460</microcodeVersion>
   <package></package>
   <arch>s390x</arch>
   <hostCPU type='kvm' model='zEC12.2-base' migratability='no'>
Index: libvirt-3.3.0/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml
===================================================================
--- libvirt-3.3.0.orig/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml
+++ libvirt-3.3.0/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml
@@ -207,6 +207,7 @@
   <flag name='intel-iommu.intremap'/>
   <version>2008000</version>
   <kvmVersion>0</kvmVersion>
+  <microcodeVersion>255931</microcodeVersion>
   <package> (v2.8.0)</package>
   <arch>x86_64</arch>
   <cpu type='kvm' name='host' usable='yes'/>
Index: libvirt-3.3.0/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
===================================================================
--- libvirt-3.3.0.orig/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
+++ libvirt-3.3.0/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
@@ -215,6 +215,7 @@
   <flag name='intel-iommu.caching-mode'/>
   <version>2009000</version>
   <kvmVersion>0</kvmVersion>
+  <microcodeVersion>321194</microcodeVersion>
   <package> (v2.9.0)</package>
   <arch>x86_64</arch>
   <hostCPU type='kvm' model='base' migratability='yes'>
Index: libvirt-3.3.0/tests/qemucapabilitiestest.c
===================================================================
--- libvirt-3.3.0.orig/tests/qemucapabilitiestest.c
+++ libvirt-3.3.0/tests/qemucapabilitiestest.c
@@ -61,10 +61,16 @@ testQemuCaps(const void *opaque)
                                   qemuMonitorTestGetMonitor(mon)) < 0)
         goto cleanup;
 
-    if (virQEMUCapsGet(capsActual, QEMU_CAPS_KVM) &&
-        virQEMUCapsInitQMPMonitorTCG(capsActual,
-                                     qemuMonitorTestGetMonitor(mon)) < 0)
-        goto cleanup;
+    if (virQEMUCapsGet(capsActual, QEMU_CAPS_KVM)) {
+        if (virQEMUCapsInitQMPMonitorTCG(capsActual,
+                                         qemuMonitorTestGetMonitor(mon)) < 0)
+            goto cleanup;
+
+        /* Fill microcodeVersion with a "random" value which is the file
+         * length to provide a reproducible number for testing.
+         */
+        virQEMUCapsSetMicrocodeVersion(capsActual, virFileLength(repliesFile, -1));
+    }
 
     if (!(actual = virQEMUCapsFormatCache(capsActual, 0, 0)))
         goto cleanup;
Index: libvirt-3.3.0/tests/qemucapsprobe.c
===================================================================
--- libvirt-3.3.0.orig/tests/qemucapsprobe.c
+++ libvirt-3.3.0/tests/qemucapsprobe.c
@@ -71,7 +71,7 @@ main(int argc, char **argv)
         return EXIT_FAILURE;
 
     if (!(caps = virQEMUCapsNewForBinaryInternal(NULL, argv[1], "/tmp", NULL,
-                                                 -1, -1, true)))
+                                                 -1, -1, 0, true)))
         return EXIT_FAILURE;
 
     virObjectUnref(caps);
Index: libvirt-3.3.0/tests/testutilsqemu.c
===================================================================
--- libvirt-3.3.0.orig/tests/testutilsqemu.c
+++ libvirt-3.3.0/tests/testutilsqemu.c
@@ -672,7 +672,7 @@ int qemuTestDriverInit(virQEMUDriver *dr
 
     /* Using /dev/null for libDir and cacheDir automatically produces errors
      * upon attempt to use any of them */
-    driver->qemuCapsCache = virQEMUCapsCacheNew("/dev/null", "/dev/null", 0, 0);
+    driver->qemuCapsCache = virQEMUCapsCacheNew("/dev/null", "/dev/null", 0, 0, 0);
     if (!driver->qemuCapsCache)
         goto error;
 
Index: libvirt-3.3.0/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml
===================================================================
--- libvirt-3.3.0.orig/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml
+++ libvirt-3.3.0/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml
@@ -165,6 +165,7 @@
   <flag name='kernel-irqchip.split'/>
   <version>2006000</version>
   <kvmVersion>0</kvmVersion>
+  <microcodeVersion>262913</microcodeVersion>
   <package></package>
   <arch>ppc64</arch>
   <cpu type='kvm' name='default'/>
