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;