Blame SOURCES/libvirt-qemu-capabilities-force-update-if-the-microcode-version-does-not-match.patch

4cd28d
From ac08fdc6dcbdc6e9fdb976fd2143c663d3748752 Mon Sep 17 00:00:00 2001
4cd28d
Message-Id: <ac08fdc6dcbdc6e9fdb976fd2143c663d3748752@dist-git>
4cd28d
From: Paolo Bonzini <pbonzini@redhat.com>
4cd28d
Date: Tue, 12 Dec 2017 16:23:41 +0100
4cd28d
Subject: [PATCH] qemu: capabilities: force update if the microcode version
4cd28d
 does not match
4cd28d
4cd28d
A microcode update can cause the CPUID bits to change; an example
4cd28d
from the past was the update that disabled TSX on several Haswell
4cd28d
and Broadwell machines.
4cd28d
4cd28d
Therefore, place microcode version in the virQEMUCaps struct and
4cd28d
XML, and rebuild the cache if the versions do not match.
4cd28d
4cd28d
CVE-2017-5715
4cd28d
4cd28d
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
4cd28d
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
4cd28d
4cd28d
Conflicts:
4cd28d
	src/qemu/qemu_capabilities.c
4cd28d
	src/qemu/qemu_capabilities.h
4cd28d
            - virQEMUCapsCache is based on virFileCache in 7.5
4cd28d
4cd28d
	src/qemu/qemu_capspriv.h
4cd28d
            - context; more functions were added in 7.5
4cd28d
4cd28d
	tests/qemucapabilitiesdata/caps_2.10.0-gicv2.aarch64.xml
4cd28d
	tests/qemucapabilitiesdata/caps_2.10.0-gicv3.aarch64.xml
4cd28d
	tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml
4cd28d
	tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml
4cd28d
	tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml
4cd28d
	tests/qemucapabilitiesdata/caps_2.9.0.ppc64.xml
4cd28d
	tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml
4cd28d
            - missing in 7.4
4cd28d
4cd28d
	tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
4cd28d
            - context; different package version in 7.4
4cd28d
4cd28d
	tests/qemucapsprobe.c
4cd28d
            - virQEMUCapsNewForBinaryInternal has fewer parameters
4cd28d
              in 7.5
4cd28d
---
4cd28d
 src/qemu/qemu_capabilities.c                       | 56 +++++++++++++++++++---
4cd28d
 src/qemu/qemu_capabilities.h                       |  7 ++-
4cd28d
 src/qemu/qemu_capspriv.h                           |  6 +++
4cd28d
 src/qemu/qemu_driver.c                             |  9 +++-
4cd28d
 tests/qemucapabilitiesdata/caps_1.2.2.x86_64.xml   |  1 +
4cd28d
 tests/qemucapabilitiesdata/caps_1.3.1.x86_64.xml   |  1 +
4cd28d
 tests/qemucapabilitiesdata/caps_1.4.2.x86_64.xml   |  1 +
4cd28d
 tests/qemucapabilitiesdata/caps_1.5.3.x86_64.xml   |  1 +
4cd28d
 tests/qemucapabilitiesdata/caps_1.6.0.x86_64.xml   |  1 +
4cd28d
 tests/qemucapabilitiesdata/caps_1.7.0.x86_64.xml   |  1 +
4cd28d
 tests/qemucapabilitiesdata/caps_2.1.1.x86_64.xml   |  1 +
4cd28d
 tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml   |  1 +
4cd28d
 tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml   |  1 +
4cd28d
 .../caps_2.6.0-gicv2.aarch64.xml                   |  1 +
4cd28d
 .../caps_2.6.0-gicv3.aarch64.xml                   |  1 +
4cd28d
 tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml  |  1 +
4cd28d
 tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml   |  1 +
4cd28d
 tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml    |  1 +
4cd28d
 tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml   |  1 +
4cd28d
 tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml    |  1 +
4cd28d
 tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml   |  1 +
4cd28d
 tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml   |  1 +
4cd28d
 tests/qemucapabilitiestest.c                       | 14 ++++--
4cd28d
 tests/qemucapsprobe.c                              |  2 +-
4cd28d
 tests/testutilsqemu.c                              |  2 +-
4cd28d
 25 files changed, 98 insertions(+), 16 deletions(-)
4cd28d
4cd28d
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
4cd28d
index a42f8d9988..504e2c9587 100644
4cd28d
--- a/src/qemu/qemu_capabilities.c
4cd28d
+++ b/src/qemu/qemu_capabilities.c
4cd28d
@@ -426,6 +426,7 @@ struct _virQEMUCaps {
4cd28d
 
4cd28d
     unsigned int version;
4cd28d
     unsigned int kvmVersion;
4cd28d
+    unsigned int microcodeVersion;
4cd28d
     char *package;
4cd28d
 
4cd28d
     virArch arch;
4cd28d
@@ -2217,6 +2218,7 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
4cd28d
 
4cd28d
     ret->version = qemuCaps->version;
4cd28d
     ret->kvmVersion = qemuCaps->kvmVersion;
4cd28d
+    ret->microcodeVersion = qemuCaps->microcodeVersion;
4cd28d
 
4cd28d
     if (VIR_STRDUP(ret->package, qemuCaps->package) < 0)
4cd28d
         goto error;
4cd28d
@@ -3817,6 +3819,13 @@ virQEMUCapsLoadCache(virCapsPtr caps,
4cd28d
         goto cleanup;
4cd28d
     }
4cd28d
 
4cd28d
+    if (virXPathUInt("string(./microcodeVersion)", ctxt,
4cd28d
+                     &qemuCaps->microcodeVersion) < 0) {
4cd28d
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
4cd28d
+                       _("missing microcode version in QEMU capabilities cache"));
4cd28d
+        goto cleanup;
4cd28d
+    }
4cd28d
+
4cd28d
     if (virXPathBoolean("boolean(./package)", ctxt) > 0) {
4cd28d
         qemuCaps->package = virXPathString("string(./package)", ctxt);
4cd28d
         if (!qemuCaps->package &&
4cd28d
@@ -4083,6 +4092,9 @@ virQEMUCapsFormatCache(virQEMUCapsPtr qemuCaps,
4cd28d
     virBufferAsprintf(&buf, "<kvmVersion>%d</kvmVersion>\n",
4cd28d
                       qemuCaps->kvmVersion);
4cd28d
 
4cd28d
+    virBufferAsprintf(&buf, "<microcodeVersion>%u</microcodeVersion>\n",
4cd28d
+                      qemuCaps->microcodeVersion);
4cd28d
+
4cd28d
     if (qemuCaps->package)
4cd28d
         virBufferAsprintf(&buf, "<package>%s</package>\n",
4cd28d
                           qemuCaps->package);
4cd28d
@@ -4286,7 +4298,8 @@ virQEMUCapsInitCached(virCapsPtr caps,
4cd28d
         goto discard;
4cd28d
     }
4cd28d
 
4cd28d
-    if (!virQEMUCapsIsValid(qemuCaps, qemuctime, runUid, runGid))
4cd28d
+    if (!virQEMUCapsIsValid(qemuCaps, qemuctime, runUid, runGid,
4cd28d
+                            virCapabilitiesGetMicrocodeVersion(caps)))
4cd28d
         goto discard;
4cd28d
 
4cd28d
     /* Discard cache if QEMU binary or libvirtd changed */
4cd28d
@@ -5138,6 +5151,7 @@ virQEMUCapsNewForBinaryInternal(virCapsPtr caps,
4cd28d
                                 const char *cacheDir,
4cd28d
                                 uid_t runUid,
4cd28d
                                 gid_t runGid,
4cd28d
+                                unsigned int microcodeVersion,
4cd28d
                                 bool qmpOnly)
4cd28d
 {
4cd28d
     virQEMUCapsPtr qemuCaps;
4cd28d
@@ -5204,6 +5218,9 @@ virQEMUCapsNewForBinaryInternal(virCapsPtr caps,
4cd28d
         virQEMUCapsInitHostCPUModel(qemuCaps, caps, VIR_DOMAIN_VIRT_QEMU);
4cd28d
     }
4cd28d
 
4cd28d
+    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
4cd28d
+        qemuCaps->microcodeVersion = microcodeVersion;
4cd28d
+
4cd28d
  cleanup:
4cd28d
     VIR_FREE(qmperr);
4cd28d
     return qemuCaps;
4cd28d
@@ -5220,10 +5237,12 @@ virQEMUCapsNewForBinary(virCapsPtr caps,
4cd28d
                         const char *libDir,
4cd28d
                         const char *cacheDir,
4cd28d
                         uid_t runUid,
4cd28d
-                        gid_t runGid)
4cd28d
+                        gid_t runGid,
4cd28d
+                        unsigned int microcodeVersion)
4cd28d
 {
4cd28d
     return virQEMUCapsNewForBinaryInternal(caps, binary, libDir, cacheDir,
4cd28d
-                                           runUid, runGid, false);
4cd28d
+                                           runUid, runGid, microcodeVersion,
4cd28d
+                                           false);
4cd28d
 }
4cd28d
 
4cd28d
 
4cd28d
@@ -5231,7 +5250,8 @@ bool
4cd28d
 virQEMUCapsIsValid(virQEMUCapsPtr qemuCaps,
4cd28d
                    time_t qemuctime,
4cd28d
                    uid_t runUid,
4cd28d
-                   gid_t runGid)
4cd28d
+                   gid_t runGid,
4cd28d
+                   unsigned int microcodeVersion)
4cd28d
 {
4cd28d
     bool kvmUsable;
4cd28d
 
4cd28d
@@ -5279,6 +5299,16 @@ virQEMUCapsIsValid(virQEMUCapsPtr qemuCaps,
4cd28d
         return false;
4cd28d
     }
4cd28d
 
4cd28d
+    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM) &&
4cd28d
+        microcodeVersion != qemuCaps->microcodeVersion) {
4cd28d
+        VIR_DEBUG("Outdated capabilities for '%s': microcode version changed "
4cd28d
+                  "(%u vs %u)",
4cd28d
+                  qemuCaps->binary,
4cd28d
+                  microcodeVersion,
4cd28d
+                  qemuCaps->microcodeVersion);
4cd28d
+        return false;
4cd28d
+    }
4cd28d
+
4cd28d
     return true;
4cd28d
 }
4cd28d
 
4cd28d
@@ -5325,7 +5355,8 @@ virQEMUCapsCachePtr
4cd28d
 virQEMUCapsCacheNew(const char *libDir,
4cd28d
                     const char *cacheDir,
4cd28d
                     uid_t runUid,
4cd28d
-                    gid_t runGid)
4cd28d
+                    gid_t runGid,
4cd28d
+                    unsigned int microcodeVersion)
4cd28d
 {
4cd28d
     virQEMUCapsCachePtr cache;
4cd28d
 
4cd28d
@@ -5348,6 +5379,7 @@ virQEMUCapsCacheNew(const char *libDir,
4cd28d
 
4cd28d
     cache->runUid = runUid;
4cd28d
     cache->runGid = runGid;
4cd28d
+    cache->microcodeVersion = microcodeVersion;
4cd28d
 
4cd28d
     return cache;
4cd28d
 
4cd28d
@@ -5364,7 +5396,8 @@ virQEMUCapsCacheValidate(virQEMUCapsCachePtr cache,
4cd28d
                          virQEMUCapsPtr *qemuCaps)
4cd28d
 {
4cd28d
     if (*qemuCaps &&
4cd28d
-        !virQEMUCapsIsValid(*qemuCaps, 0, cache->runUid, cache->runGid)) {
4cd28d
+        !virQEMUCapsIsValid(*qemuCaps, 0, cache->runUid, cache->runGid,
4cd28d
+                            virCapabilitiesGetMicrocodeVersion(caps))) {
4cd28d
         VIR_DEBUG("Cached capabilities %p no longer valid for %s",
4cd28d
                   *qemuCaps, binary);
4cd28d
         virHashRemoveEntry(cache->binaries, binary);
4cd28d
@@ -5375,7 +5408,8 @@ virQEMUCapsCacheValidate(virQEMUCapsCachePtr cache,
4cd28d
         VIR_DEBUG("Creating capabilities for %s", binary);
4cd28d
         *qemuCaps = virQEMUCapsNewForBinary(caps, binary,
4cd28d
                                             cache->libDir, cache->cacheDir,
4cd28d
-                                            cache->runUid, cache->runGid);
4cd28d
+                                            cache->runUid, cache->runGid,
4cd28d
+                                            virCapabilitiesGetMicrocodeVersion(caps));
4cd28d
         if (*qemuCaps) {
4cd28d
             VIR_DEBUG("Caching capabilities %p for %s", *qemuCaps, binary);
4cd28d
             if (virHashAddEntry(cache->binaries, binary, *qemuCaps) < 0) {
4cd28d
@@ -5926,3 +5960,11 @@ virQEMUCapsFillDomainCaps(virCapsPtr caps,
4cd28d
         return -1;
4cd28d
     return 0;
4cd28d
 }
4cd28d
+
4cd28d
+
4cd28d
+void
4cd28d
+virQEMUCapsSetMicrocodeVersion(virQEMUCapsPtr qemuCaps,
4cd28d
+                               unsigned int microcodeVersion)
4cd28d
+{
4cd28d
+    qemuCaps->microcodeVersion = microcodeVersion;
4cd28d
+}
4cd28d
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
4cd28d
index bc4ad44496..d1a1d46b5a 100644
4cd28d
--- a/src/qemu/qemu_capabilities.h
4cd28d
+++ b/src/qemu/qemu_capabilities.h
4cd28d
@@ -497,7 +497,8 @@ int virQEMUCapsGetMachineTypesCaps(virQEMUCapsPtr qemuCaps,
4cd28d
 bool virQEMUCapsIsValid(virQEMUCapsPtr qemuCaps,
4cd28d
                         time_t ctime,
4cd28d
                         uid_t runUid,
4cd28d
-                        gid_t runGid);
4cd28d
+                        gid_t runGid,
4cd28d
+                        unsigned int microcodeVersion);
4cd28d
 
4cd28d
 void virQEMUCapsFilterByMachineType(virQEMUCapsPtr qemuCaps,
4cd28d
                                     const char *machineType);
4cd28d
@@ -509,7 +510,9 @@ void virQEMUCapsSetGICCapabilities(virQEMUCapsPtr qemuCaps,
4cd28d
 
4cd28d
 virQEMUCapsCachePtr virQEMUCapsCacheNew(const char *libDir,
4cd28d
                                         const char *cacheDir,
4cd28d
-                                        uid_t uid, gid_t gid);
4cd28d
+                                        uid_t uid,
4cd28d
+                                        gid_t gid,
4cd28d
+                                        unsigned int microcodeVersion);
4cd28d
 virQEMUCapsPtr virQEMUCapsCacheLookup(virCapsPtr caps,
4cd28d
                                       virQEMUCapsCachePtr cache,
4cd28d
                                       const char *binary);
4cd28d
diff --git a/src/qemu/qemu_capspriv.h b/src/qemu/qemu_capspriv.h
4cd28d
index 1baaaf3340..d39a71a2f8 100644
4cd28d
--- a/src/qemu/qemu_capspriv.h
4cd28d
+++ b/src/qemu/qemu_capspriv.h
4cd28d
@@ -35,6 +35,7 @@ struct _virQEMUCapsCache {
4cd28d
     char *cacheDir;
4cd28d
     uid_t runUid;
4cd28d
     gid_t runGid;
4cd28d
+    unsigned int microcodeVersion;
4cd28d
 };
4cd28d
 
4cd28d
 virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps);
4cd28d
@@ -46,6 +47,7 @@ virQEMUCapsNewForBinaryInternal(virCapsPtr caps,
4cd28d
                                 const char *cacheDir,
4cd28d
                                 uid_t runUid,
4cd28d
                                 gid_t runGid,
4cd28d
+                                unsigned int microcodeVersion,
4cd28d
                                 bool qmpOnly);
4cd28d
 
4cd28d
 int virQEMUCapsLoadCache(virCapsPtr caps,
4cd28d
@@ -93,4 +95,8 @@ virCPUDefPtr
4cd28d
 virQEMUCapsProbeHostCPUForEmulator(virCapsPtr caps,
4cd28d
                                    virQEMUCapsPtr qemuCaps,
4cd28d
                                    virDomainVirtType type);
4cd28d
+
4cd28d
+void
4cd28d
+virQEMUCapsSetMicrocodeVersion(virQEMUCapsPtr qemuCaps,
4cd28d
+                               unsigned int microcodeVersion);
4cd28d
 #endif
4cd28d
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
4cd28d
index 498f787ad3..0943d222b4 100644
4cd28d
--- a/src/qemu/qemu_driver.c
4cd28d
+++ b/src/qemu/qemu_driver.c
4cd28d
@@ -628,6 +628,8 @@ qemuStateInitialize(bool privileged,
4cd28d
     gid_t run_gid = -1;
4cd28d
     char *hugepagePath = NULL;
4cd28d
     size_t i;
4cd28d
+    virCPUDefPtr hostCPU = NULL;
4cd28d
+    unsigned int microcodeVersion = 0;
4cd28d
 
4cd28d
     if (VIR_ALLOC(qemu_driver) < 0)
4cd28d
         return -1;
4cd28d
@@ -847,10 +849,15 @@ qemuStateInitialize(bool privileged,
4cd28d
         run_gid = cfg->group;
4cd28d
     }
4cd28d
 
4cd28d
+    if ((hostCPU = virCPUProbeHost(virArchFromHost())))
4cd28d
+        microcodeVersion = hostCPU->microcodeVersion;
4cd28d
+    virCPUDefFree(hostCPU);
4cd28d
+
4cd28d
     qemu_driver->qemuCapsCache = virQEMUCapsCacheNew(cfg->libDir,
4cd28d
                                                      cfg->cacheDir,
4cd28d
                                                      run_uid,
4cd28d
-                                                     run_gid);
4cd28d
+                                                     run_gid,
4cd28d
+                                                     microcodeVersion);
4cd28d
     if (!qemu_driver->qemuCapsCache)
4cd28d
         goto error;
4cd28d
 
4cd28d
diff --git a/tests/qemucapabilitiesdata/caps_1.2.2.x86_64.xml b/tests/qemucapabilitiesdata/caps_1.2.2.x86_64.xml
4cd28d
index 5ad406ce1b..12d5873251 100644
4cd28d
--- a/tests/qemucapabilitiesdata/caps_1.2.2.x86_64.xml
4cd28d
+++ b/tests/qemucapabilitiesdata/caps_1.2.2.x86_64.xml
4cd28d
@@ -112,6 +112,7 @@
4cd28d
   <flag name='query-cpu-definitions'/>
4cd28d
   <version>1002002</version>
4cd28d
   <kvmVersion>0</kvmVersion>
4cd28d
+  <microcodeVersion>26900</microcodeVersion>
4cd28d
   <package></package>
4cd28d
   <arch>x86_64</arch>
4cd28d
   <cpu type='kvm' name='qemu64'/>
4cd28d
diff --git a/tests/qemucapabilitiesdata/caps_1.3.1.x86_64.xml b/tests/qemucapabilitiesdata/caps_1.3.1.x86_64.xml
4cd28d
index 4ec731d655..8bfbf79a74 100644
4cd28d
--- a/tests/qemucapabilitiesdata/caps_1.3.1.x86_64.xml
4cd28d
+++ b/tests/qemucapabilitiesdata/caps_1.3.1.x86_64.xml
4cd28d
@@ -130,6 +130,7 @@
4cd28d
   <flag name='query-cpu-definitions'/>
4cd28d
   <version>1003001</version>
4cd28d
   <kvmVersion>0</kvmVersion>
4cd28d
+  <microcodeVersion>30198</microcodeVersion>
4cd28d
   <package></package>
4cd28d
   <arch>x86_64</arch>
4cd28d
   <cpu type='kvm' name='qemu64'/>
4cd28d
diff --git a/tests/qemucapabilitiesdata/caps_1.4.2.x86_64.xml b/tests/qemucapabilitiesdata/caps_1.4.2.x86_64.xml
4cd28d
index 601c62e65a..19925d0f29 100644
4cd28d
--- a/tests/qemucapabilitiesdata/caps_1.4.2.x86_64.xml
4cd28d
+++ b/tests/qemucapabilitiesdata/caps_1.4.2.x86_64.xml
4cd28d
@@ -131,6 +131,7 @@
4cd28d
   <flag name='query-cpu-definitions'/>
4cd28d
   <version>1004002</version>
4cd28d
   <kvmVersion>0</kvmVersion>
4cd28d
+  <microcodeVersion>30915</microcodeVersion>
4cd28d
   <package></package>
4cd28d
   <arch>x86_64</arch>
4cd28d
   <cpu type='kvm' name='Opteron_G5'/>
4cd28d
diff --git a/tests/qemucapabilitiesdata/caps_1.5.3.x86_64.xml b/tests/qemucapabilitiesdata/caps_1.5.3.x86_64.xml
4cd28d
index 14f34b2771..df3c2d87b6 100644
4cd28d
--- a/tests/qemucapabilitiesdata/caps_1.5.3.x86_64.xml
4cd28d
+++ b/tests/qemucapabilitiesdata/caps_1.5.3.x86_64.xml
4cd28d
@@ -143,6 +143,7 @@
4cd28d
   <flag name='kernel-irqchip'/>
4cd28d
   <version>1005003</version>
4cd28d
   <kvmVersion>0</kvmVersion>
4cd28d
+  <microcodeVersion>47019</microcodeVersion>
4cd28d
   <package></package>
4cd28d
   <arch>x86_64</arch>
4cd28d
   <cpu type='kvm' name='Opteron_G5'/>
4cd28d
diff --git a/tests/qemucapabilitiesdata/caps_1.6.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_1.6.0.x86_64.xml
4cd28d
index 8fc23d6aad..889cd96dde 100644
4cd28d
--- a/tests/qemucapabilitiesdata/caps_1.6.0.x86_64.xml
4cd28d
+++ b/tests/qemucapabilitiesdata/caps_1.6.0.x86_64.xml
4cd28d
@@ -148,6 +148,7 @@
4cd28d
   <flag name='kernel-irqchip'/>
4cd28d
   <version>1006000</version>
4cd28d
   <kvmVersion>0</kvmVersion>
4cd28d
+  <microcodeVersion>45248</microcodeVersion>
4cd28d
   <package></package>
4cd28d
   <arch>x86_64</arch>
4cd28d
   <cpu type='kvm' name='Opteron_G5'/>
4cd28d
diff --git a/tests/qemucapabilitiesdata/caps_1.7.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_1.7.0.x86_64.xml
4cd28d
index 47c8956b44..426fcfc139 100644
4cd28d
--- a/tests/qemucapabilitiesdata/caps_1.7.0.x86_64.xml
4cd28d
+++ b/tests/qemucapabilitiesdata/caps_1.7.0.x86_64.xml
4cd28d
@@ -150,6 +150,7 @@
4cd28d
   <flag name='kernel-irqchip'/>
4cd28d
   <version>1007000</version>
4cd28d
   <kvmVersion>0</kvmVersion>
4cd28d
+  <microcodeVersion>50692</microcodeVersion>
4cd28d
   <package></package>
4cd28d
   <arch>x86_64</arch>
4cd28d
   <cpu type='kvm' name='Opteron_G5'/>
4cd28d
diff --git a/tests/qemucapabilitiesdata/caps_2.1.1.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.1.1.x86_64.xml
4cd28d
index afe7d53ff4..82737b2a7f 100644
4cd28d
--- a/tests/qemucapabilitiesdata/caps_2.1.1.x86_64.xml
4cd28d
+++ b/tests/qemucapabilitiesdata/caps_2.1.1.x86_64.xml
4cd28d
@@ -166,6 +166,7 @@
4cd28d
   <flag name='kernel-irqchip'/>
4cd28d
   <version>2001001</version>
4cd28d
   <kvmVersion>0</kvmVersion>
4cd28d
+  <microcodeVersion>59488</microcodeVersion>
4cd28d
   <package></package>
4cd28d
   <arch>x86_64</arch>
4cd28d
   <cpu type='kvm' name='Opteron_G5'/>
4cd28d
diff --git a/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml
4cd28d
index 5bdc1a2bdd..dca3452861 100644
4cd28d
--- a/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml
4cd28d
+++ b/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml
4cd28d
@@ -188,6 +188,7 @@
4cd28d
   <flag name='kernel-irqchip'/>
4cd28d
   <version>2004000</version>
4cd28d
   <kvmVersion>0</kvmVersion>
4cd28d
+  <microcodeVersion>75653</microcodeVersion>
4cd28d
   <package></package>
4cd28d
   <arch>x86_64</arch>
4cd28d
   <cpu type='kvm' name='Opteron_G5'/>
4cd28d
diff --git a/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml
4cd28d
index 36bc1342bb..03bc558c18 100644
4cd28d
--- a/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml
4cd28d
+++ b/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml
4cd28d
@@ -194,6 +194,7 @@
4cd28d
   <flag name='kernel-irqchip'/>
4cd28d
   <version>2005000</version>
4cd28d
   <kvmVersion>0</kvmVersion>
4cd28d
+  <microcodeVersion>216775</microcodeVersion>
4cd28d
   <package></package>
4cd28d
   <arch>x86_64</arch>
4cd28d
   <cpu type='kvm' name='Opteron_G5'/>
4cd28d
diff --git a/tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml b/tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml
4cd28d
index 33bc462084..c78719c778 100644
4cd28d
--- a/tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml
4cd28d
+++ b/tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml
4cd28d
@@ -172,6 +172,7 @@
4cd28d
   <flag name='kernel-irqchip.split'/>
4cd28d
   <version>2006000</version>
4cd28d
   <kvmVersion>0</kvmVersion>
4cd28d
+  <microcodeVersion>228838</microcodeVersion>
4cd28d
   <package></package>
4cd28d
   <arch>aarch64</arch>
4cd28d
   <cpu type='kvm' name='pxa262'/>
4cd28d
diff --git a/tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml b/tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml
4cd28d
index a8ce6b03b1..314b9407c0 100644
4cd28d
--- a/tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml
4cd28d
+++ b/tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml
4cd28d
@@ -172,6 +172,7 @@
4cd28d
   <flag name='kernel-irqchip.split'/>
4cd28d
   <version>2006000</version>
4cd28d
   <kvmVersion>0</kvmVersion>
4cd28d
+  <microcodeVersion>228838</microcodeVersion>
4cd28d
   <package></package>
4cd28d
   <arch>aarch64</arch>
4cd28d
   <cpu type='kvm' name='pxa262'/>
4cd28d
diff --git a/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml b/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml
4cd28d
index 425992f0d5..f09d0f74d1 100644
4cd28d
--- a/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml
4cd28d
+++ b/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml
4cd28d
@@ -166,6 +166,7 @@
4cd28d
   <flag name='kernel-irqchip.split'/>
4cd28d
   <version>2006000</version>
4cd28d
   <kvmVersion>0</kvmVersion>
4cd28d
+  <microcodeVersion>262913</microcodeVersion>
4cd28d
   <package></package>
4cd28d
   <arch>ppc64</arch>
4cd28d
   <cpu type='kvm' name='default'/>
4cd28d
diff --git a/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml
4cd28d
index 97e71ec4f4..4dadf178bd 100644
4cd28d
--- a/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml
4cd28d
+++ b/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml
4cd28d
@@ -204,6 +204,7 @@
4cd28d
   <flag name='kernel-irqchip.split'/>
4cd28d
   <version>2006000</version>
4cd28d
   <kvmVersion>0</kvmVersion>
4cd28d
+  <microcodeVersion>227579</microcodeVersion>
4cd28d
   <package></package>
4cd28d
   <arch>x86_64</arch>
4cd28d
   <cpu type='kvm' name='Opteron_G5'/>
4cd28d
diff --git a/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml
4cd28d
index 70cce64179..75d77ccd13 100644
4cd28d
--- a/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml
4cd28d
+++ b/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml
4cd28d
@@ -134,6 +134,7 @@
4cd28d
   <flag name='kernel-irqchip.split'/>
4cd28d
   <version>2007000</version>
4cd28d
   <kvmVersion>0</kvmVersion>
4cd28d
+  <microcodeVersion>217559</microcodeVersion>
4cd28d
   <package></package>
4cd28d
   <arch>s390x</arch>
4cd28d
   <cpu type='kvm' name='host'/>
4cd28d
diff --git a/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml
4cd28d
index 49c046212b..b9531ad2d2 100644
4cd28d
--- a/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml
4cd28d
+++ b/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml
4cd28d
@@ -207,6 +207,7 @@
4cd28d
   <flag name='intel-iommu.intremap'/>
4cd28d
   <version>2007000</version>
4cd28d
   <kvmVersion>0</kvmVersion>
4cd28d
+  <microcodeVersion>239276</microcodeVersion>
4cd28d
   <package> (v2.7.0)</package>
4cd28d
   <arch>x86_64</arch>
4cd28d
   <cpu type='kvm' name='Opteron_G5'/>
4cd28d
diff --git a/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml
4cd28d
index 51be9bce4d..a707d76bc3 100644
4cd28d
--- a/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml
4cd28d
+++ b/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml
4cd28d
@@ -136,6 +136,7 @@
4cd28d
   <flag name='kernel-irqchip.split'/>
4cd28d
   <version>2007093</version>
4cd28d
   <kvmVersion>0</kvmVersion>
4cd28d
+  <microcodeVersion>242460</microcodeVersion>
4cd28d
   <package></package>
4cd28d
   <arch>s390x</arch>
4cd28d
   <hostCPU type='kvm' model='zEC12.2-base' migratability='no'>
4cd28d
diff --git a/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml
4cd28d
index 01edbc88da..d3bce6b15c 100644
4cd28d
--- a/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml
4cd28d
+++ b/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml
4cd28d
@@ -209,6 +209,7 @@
4cd28d
   <flag name='intel-iommu.eim'/>
4cd28d
   <version>2008000</version>
4cd28d
   <kvmVersion>0</kvmVersion>
4cd28d
+  <microcodeVersion>255931</microcodeVersion>
4cd28d
   <package> (v2.8.0)</package>
4cd28d
   <arch>x86_64</arch>
4cd28d
   <cpu type='kvm' name='host' usable='yes'/>
4cd28d
diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
4cd28d
index 2140eab398..34dd9353d8 100644
4cd28d
--- a/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
4cd28d
+++ b/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
4cd28d
@@ -219,6 +219,7 @@
4cd28d
   <flag name='virtio.ats'/>
4cd28d
   <version>2008090</version>
4cd28d
   <kvmVersion>0</kvmVersion>
4cd28d
+  <microcodeVersion>317985</microcodeVersion>
4cd28d
   <package> (v2.9.0-rc0-142-g940a8ce)</package>
4cd28d
   <arch>x86_64</arch>
4cd28d
   <hostCPU type='kvm' model='base' migratability='yes'>
4cd28d
diff --git a/tests/qemucapabilitiestest.c b/tests/qemucapabilitiestest.c
4cd28d
index 2918ff4695..c817478e49 100644
4cd28d
--- a/tests/qemucapabilitiestest.c
4cd28d
+++ b/tests/qemucapabilitiestest.c
4cd28d
@@ -61,10 +61,16 @@ testQemuCaps(const void *opaque)
4cd28d
                                   qemuMonitorTestGetMonitor(mon)) < 0)
4cd28d
         goto cleanup;
4cd28d
 
4cd28d
-    if (virQEMUCapsGet(capsActual, QEMU_CAPS_KVM) &&
4cd28d
-        virQEMUCapsInitQMPMonitorTCG(capsActual,
4cd28d
-                                     qemuMonitorTestGetMonitor(mon)) < 0)
4cd28d
-        goto cleanup;
4cd28d
+    if (virQEMUCapsGet(capsActual, QEMU_CAPS_KVM)) {
4cd28d
+        if (virQEMUCapsInitQMPMonitorTCG(capsActual,
4cd28d
+                                         qemuMonitorTestGetMonitor(mon)) < 0)
4cd28d
+            goto cleanup;
4cd28d
+
4cd28d
+        /* Fill microcodeVersion with a "random" value which is the file
4cd28d
+         * length to provide a reproducible number for testing.
4cd28d
+         */
4cd28d
+        virQEMUCapsSetMicrocodeVersion(capsActual, virFileLength(repliesFile, -1));
4cd28d
+    }
4cd28d
 
4cd28d
     if (!(actual = virQEMUCapsFormatCache(capsActual, 0, 0)))
4cd28d
         goto cleanup;
4cd28d
diff --git a/tests/qemucapsprobe.c b/tests/qemucapsprobe.c
4cd28d
index 561c5d7c14..03bf81d3bd 100644
4cd28d
--- a/tests/qemucapsprobe.c
4cd28d
+++ b/tests/qemucapsprobe.c
4cd28d
@@ -71,7 +71,7 @@ main(int argc, char **argv)
4cd28d
         return EXIT_FAILURE;
4cd28d
 
4cd28d
     if (!(caps = virQEMUCapsNewForBinaryInternal(NULL, argv[1], "/tmp", NULL,
4cd28d
-                                                 -1, -1, true)))
4cd28d
+                                                 -1, -1, 0, true)))
4cd28d
         return EXIT_FAILURE;
4cd28d
 
4cd28d
     virObjectUnref(caps);
4cd28d
diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c
4cd28d
index 4cc482dfb0..e0fb97fba1 100644
4cd28d
--- a/tests/testutilsqemu.c
4cd28d
+++ b/tests/testutilsqemu.c
4cd28d
@@ -600,7 +600,7 @@ int qemuTestDriverInit(virQEMUDriver *driver)
4cd28d
 
4cd28d
     /* Using /dev/null for libDir and cacheDir automatically produces errors
4cd28d
      * upon attempt to use any of them */
4cd28d
-    driver->qemuCapsCache = virQEMUCapsCacheNew("/dev/null", "/dev/null", 0, 0);
4cd28d
+    driver->qemuCapsCache = virQEMUCapsCacheNew("/dev/null", "/dev/null", 0, 0, 0);
4cd28d
     if (!driver->qemuCapsCache)
4cd28d
         goto error;
4cd28d
 
4cd28d
-- 
4cd28d
2.15.1
4cd28d