diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 9673ef857b..abf02a9b17 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -507,6 +507,7 @@ struct _virQEMUCaps {
unsigned int version;
unsigned int kvmVersion;
unsigned int libvirtVersion;
+ unsigned int microcodeVersion;
char *package;
virArch arch;
@@ -2296,6 +2297,7 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
ret->version = qemuCaps->version;
ret->kvmVersion = qemuCaps->kvmVersion;
+ ret->microcodeVersion = qemuCaps->microcodeVersion;
if (VIR_STRDUP(ret->package, qemuCaps->package) < 0)
goto error;
@@ -3830,6 +3832,7 @@ struct _virQEMUCapsCachePriv {
uid_t runUid;
gid_t runGid;
virArch hostArch;
+ unsigned int microcodeVersion;
};
typedef struct _virQEMUCapsCachePriv virQEMUCapsCachePriv;
typedef virQEMUCapsCachePriv *virQEMUCapsCachePrivPtr;
@@ -3952,6 +3955,13 @@ virQEMUCapsLoadCache(virArch hostArch,
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 &&
@@ -4230,6 +4240,9 @@ virQEMUCapsFormatCache(virQEMUCapsPtr qemuCaps)
virBufferAsprintf(&buf, "%d\n",
qemuCaps->kvmVersion);
+ virBufferAsprintf(&buf, "%u\n",
+ qemuCaps->microcodeVersion);
+
if (qemuCaps->package)
virBufferAsprintf(&buf, "%s\n",
qemuCaps->package);
@@ -4371,6 +4384,16 @@ virQEMUCapsIsValid(void *data,
return false;
}
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM) &&
+ priv->microcodeVersion != qemuCaps->microcodeVersion) {
+ VIR_DEBUG("Outdated capabilities for '%s': microcode version changed "
+ "(%u vs %u)",
+ qemuCaps->binary,
+ priv->microcodeVersion,
+ qemuCaps->microcodeVersion);
+ return false;
+ }
+
return true;
}
@@ -5197,6 +5220,7 @@ virQEMUCapsNewForBinaryInternal(virArch hostArch,
const char *libDir,
uid_t runUid,
gid_t runGid,
+ unsigned int microcodeVersion,
bool qmpOnly)
{
virQEMUCapsPtr qemuCaps;
@@ -5253,6 +5277,9 @@ virQEMUCapsNewForBinaryInternal(virArch hostArch,
virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_KVM);
virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_QEMU);
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
+ qemuCaps->microcodeVersion = microcodeVersion;
+
cleanup:
VIR_FREE(qmperr);
return qemuCaps;
@@ -5274,6 +5301,7 @@ virQEMUCapsNewData(const char *binary,
priv->libDir,
priv->runUid,
priv->runGid,
+ priv->microcodeVersion,
false);
}
@@ -5356,7 +5384,8 @@ virFileCachePtr
virQEMUCapsCacheNew(const char *libDir,
const char *cacheDir,
uid_t runUid,
- gid_t runGid)
+ gid_t runGid,
+ unsigned int microcodeVersion)
{
char *capsCacheDir = NULL;
virFileCachePtr cache = NULL;
@@ -5379,6 +5408,7 @@ virQEMUCapsCacheNew(const char *libDir,
priv->runUid = runUid;
priv->runGid = runGid;
+ priv->microcodeVersion = microcodeVersion;
cleanup:
VIR_FREE(capsCacheDir);
@@ -5856,3 +5886,11 @@ virQEMUCapsFillDomainCaps(virCapsPtr caps,
return -1;
return 0;
}
+
+
+void
+virQEMUCapsSetMicrocodeVersion(virQEMUCapsPtr qemuCaps,
+ unsigned int microcodeVersion)
+{
+ qemuCaps->microcodeVersion = microcodeVersion;
+}
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index e73dbaa557..8bb0b6a232 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -520,8 +520,10 @@ void virQEMUCapsFilterByMachineType(virQEMUCapsPtr qemuCaps,
const char *machineType);
virFileCachePtr virQEMUCapsCacheNew(const char *libDir,
- const char *cacheDir,
- uid_t uid, gid_t gid);
+ const char *cacheDir,
+ uid_t uid,
+ gid_t gid,
+ unsigned int microcodeVersion);
virQEMUCapsPtr virQEMUCapsCacheLookup(virFileCachePtr cache,
const char *binary);
virQEMUCapsPtr virQEMUCapsCacheLookupCopy(virFileCachePtr cache,
diff --git a/src/qemu/qemu_capspriv.h b/src/qemu/qemu_capspriv.h
index 219daa3629..98d163b920 100644
--- a/src/qemu/qemu_capspriv.h
+++ b/src/qemu/qemu_capspriv.h
@@ -36,6 +36,7 @@ virQEMUCapsNewForBinaryInternal(virArch hostArch,
const char *libDir,
uid_t runUid,
gid_t runGid,
+ unsigned int microcodeVersion,
bool qmpOnly);
int virQEMUCapsLoadCache(virArch hostArch,
@@ -102,4 +103,8 @@ int
virQEMUCapsProbeQMPCPUDefinitions(virQEMUCapsPtr qemuCaps,
qemuMonitorPtr mon,
bool tcg);
+
+void
+virQEMUCapsSetMicrocodeVersion(virQEMUCapsPtr qemuCaps,
+ unsigned int microcodeVersion);
#endif
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 97b194b057..1ebc1177f8 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -633,6 +633,8 @@ qemuStateInitialize(bool privileged,
char *hugepagePath = NULL;
char *memoryBackingPath = NULL;
size_t i;
+ virCPUDefPtr hostCPU = NULL;
+ unsigned int microcodeVersion = 0;
if (VIR_ALLOC(qemu_driver) < 0)
return -1;
@@ -855,10 +857,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;
diff --git a/tests/qemucapabilitiesdata/caps_1.2.2.x86_64.xml b/tests/qemucapabilitiesdata/caps_1.2.2.x86_64.xml
index d560811ab7..3001d487c6 100644
--- a/tests/qemucapabilitiesdata/caps_1.2.2.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_1.2.2.x86_64.xml
@@ -112,6 +112,7 @@
1002002
0
+ 26900
x86_64
diff --git a/tests/qemucapabilitiesdata/caps_1.3.1.x86_64.xml b/tests/qemucapabilitiesdata/caps_1.3.1.x86_64.xml
index 576475f7fa..283f30ef07 100644
--- a/tests/qemucapabilitiesdata/caps_1.3.1.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_1.3.1.x86_64.xml
@@ -130,6 +130,7 @@
1003001
0
+ 30198
x86_64
diff --git a/tests/qemucapabilitiesdata/caps_1.4.2.x86_64.xml b/tests/qemucapabilitiesdata/caps_1.4.2.x86_64.xml
index 0c271d3e41..200069ae86 100644
--- a/tests/qemucapabilitiesdata/caps_1.4.2.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_1.4.2.x86_64.xml
@@ -131,6 +131,7 @@
1004002
0
+ 30915
x86_64
diff --git a/tests/qemucapabilitiesdata/caps_1.5.3.x86_64.xml b/tests/qemucapabilitiesdata/caps_1.5.3.x86_64.xml
index 5c667975bf..e02c0961cd 100644
--- a/tests/qemucapabilitiesdata/caps_1.5.3.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_1.5.3.x86_64.xml
@@ -143,6 +143,7 @@
1005003
0
+ 47019
x86_64
diff --git a/tests/qemucapabilitiesdata/caps_1.6.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_1.6.0.x86_64.xml
index 8ae07a91db..e3896685e9 100644
--- a/tests/qemucapabilitiesdata/caps_1.6.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_1.6.0.x86_64.xml
@@ -148,6 +148,7 @@
1006000
0
+ 45248
x86_64
diff --git a/tests/qemucapabilitiesdata/caps_1.7.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_1.7.0.x86_64.xml
index 34bd6be1cd..5b4d1ea661 100644
--- a/tests/qemucapabilitiesdata/caps_1.7.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_1.7.0.x86_64.xml
@@ -150,6 +150,7 @@
1007000
0
+ 50692
x86_64
diff --git a/tests/qemucapabilitiesdata/caps_2.1.1.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.1.1.x86_64.xml
index 0d7c144ff7..200e57adac 100644
--- a/tests/qemucapabilitiesdata/caps_2.1.1.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.1.1.x86_64.xml
@@ -166,6 +166,7 @@
2001001
0
+ 59488
x86_64
diff --git a/tests/qemucapabilitiesdata/caps_2.10.0-gicv2.aarch64.xml b/tests/qemucapabilitiesdata/caps_2.10.0-gicv2.aarch64.xml
index eeb1840d3f..51d19aacb1 100644
--- a/tests/qemucapabilitiesdata/caps_2.10.0-gicv2.aarch64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.10.0-gicv2.aarch64.xml
@@ -187,6 +187,7 @@
2010000
0
+ 304138
(v2.10.0)
aarch64
diff --git a/tests/qemucapabilitiesdata/caps_2.10.0-gicv3.aarch64.xml b/tests/qemucapabilitiesdata/caps_2.10.0-gicv3.aarch64.xml
index 1e7b95ec02..b8309f35b3 100644
--- a/tests/qemucapabilitiesdata/caps_2.10.0-gicv3.aarch64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.10.0-gicv3.aarch64.xml
@@ -187,6 +187,7 @@
2010000
0
+ 304138
(v2.10.0)
aarch64
diff --git a/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml
index ca55e11ebe..c866ce3ee8 100644
--- a/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml
@@ -185,6 +185,7 @@
2010000
0
+ 383421
(v2.10.0)
ppc64
diff --git a/tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml
index 64e70f54be..e9115d304e 100644
--- a/tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml
+++ b/tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml
@@ -147,6 +147,7 @@
2010000
0
+ 304153
s390x
diff --git a/tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml
index 8fea70a522..1687417081 100644
--- a/tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml
@@ -230,6 +230,7 @@
2010000
0
+ 345185
(v2.10.0)
x86_64
diff --git a/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml
index 5007523c1f..9b315aecf4 100644
--- a/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml
@@ -191,6 +191,7 @@
2004000
0
+ 75653
x86_64
diff --git a/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml
index a9ad292d01..3096eadf72 100644
--- a/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml
@@ -197,6 +197,7 @@
2005000
0
+ 216775
x86_64
diff --git a/tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml b/tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml
index d3e2e18faa..4cdd894a97 100644
--- a/tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml
@@ -176,6 +176,7 @@
2006000
0
+ 228838
aarch64
diff --git a/tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml b/tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml
index bc86d03537..5655af7d3d 100644
--- a/tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml
@@ -176,6 +176,7 @@
2006000
0
+ 228838
aarch64
diff --git a/tests/qemucapabilitiesdata/caps_2.6.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_2.6.0.ppc64.xml
index 27d99bd937..31701bb40b 100644
--- a/tests/qemucapabilitiesdata/caps_2.6.0.ppc64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.6.0.ppc64.xml
@@ -171,6 +171,7 @@
2006000
0
+ 263602
ppc64
diff --git a/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml
index 97621612ab..6ae19ffd36 100644
--- a/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml
@@ -207,6 +207,7 @@
2006000
0
+ 227579
x86_64
diff --git a/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml
index c2f310cd46..b6ec680d5c 100644
--- a/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml
+++ b/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml
@@ -138,6 +138,7 @@
2007000
0
+ 217559
s390x
diff --git a/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml
index e4ea9452c5..294ac126e5 100644
--- a/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml
@@ -211,6 +211,7 @@
2007000
0
+ 239276
(v2.7.0)
x86_64
diff --git a/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml
index f6e024dc61..d788ad206e 100644
--- a/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml
+++ b/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml
@@ -140,6 +140,7 @@
2007093
0
+ 242460
s390x
diff --git a/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml
index c6d3e21d5c..156563d99a 100644
--- a/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml
@@ -213,6 +213,7 @@
2008000
0
+ 255931
(v2.8.0)
x86_64
diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_2.9.0.ppc64.xml
index 96aa5d59fc..cca643a3a5 100644
--- a/tests/qemucapabilitiesdata/caps_2.9.0.ppc64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.9.0.ppc64.xml
@@ -179,6 +179,7 @@
2009000
0
+ 347135
(v2.9.0)
ppc64
diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml
index baac0b7aeb..5d0f0aa6c6 100644
--- a/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml
+++ b/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml
@@ -143,6 +143,7 @@
2009000
0
+ 265878
s390x
diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
index 9f489129fb..907f543ee3 100644
--- a/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
@@ -226,6 +226,7 @@
2009000
0
+ 321194
(v2.9.0)
x86_64
diff --git a/tests/qemucapabilitiestest.c b/tests/qemucapabilitiestest.c
index dde5f767b8..87807b4135 100644
--- a/tests/qemucapabilitiestest.c
+++ b/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)))
goto cleanup;
diff --git a/tests/qemucapsprobe.c b/tests/qemucapsprobe.c
index 4b8d6229b4..a5f5a38b16 100644
--- a/tests/qemucapsprobe.c
+++ b/tests/qemucapsprobe.c
@@ -72,7 +72,7 @@ main(int argc, char **argv)
return EXIT_FAILURE;
if (!(caps = virQEMUCapsNewForBinaryInternal(VIR_ARCH_NONE, argv[1], "/tmp",
- -1, -1, true)))
+ -1, -1, 0, true)))
return EXIT_FAILURE;
virObjectUnref(caps);
diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c
index 2c7124bf26..f8182033fc 100644
--- a/tests/testutilsqemu.c
+++ b/tests/testutilsqemu.c
@@ -603,7 +603,7 @@ int qemuTestDriverInit(virQEMUDriver *driver)
/* 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;