提交 b527589d 编写于 作者: P Paolo Bonzini 提交者: Jiri Denemark

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: NPaolo Bonzini <pbonzini@redhat.com>
Signed-off-by: NJiri Denemark <jdenemar@redhat.com>
上级 d2440f3b
......@@ -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, "<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);
......@@ -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;
}
......@@ -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,
......
......@@ -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
......@@ -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;
......
......@@ -112,6 +112,7 @@
<flag name='isa-serial'/>
<version>1002002</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>26900</microcodeVersion>
<package></package>
<arch>x86_64</arch>
<cpu type='kvm' name='qemu64'/>
......
......@@ -130,6 +130,7 @@
<flag name='isa-serial'/>
<version>1003001</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>30198</microcodeVersion>
<package></package>
<arch>x86_64</arch>
<cpu type='kvm' name='qemu64'/>
......
......@@ -131,6 +131,7 @@
<flag name='isa-serial'/>
<version>1004002</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>30915</microcodeVersion>
<package></package>
<arch>x86_64</arch>
<cpu type='kvm' name='Opteron_G5'/>
......
......@@ -143,6 +143,7 @@
<flag name='isa-serial'/>
<version>1005003</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>47019</microcodeVersion>
<package></package>
<arch>x86_64</arch>
<cpu type='kvm' name='Opteron_G5'/>
......
......@@ -148,6 +148,7 @@
<flag name='isa-serial'/>
<version>1006000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>45248</microcodeVersion>
<package></package>
<arch>x86_64</arch>
<cpu type='kvm' name='Opteron_G5'/>
......
......@@ -150,6 +150,7 @@
<flag name='isa-serial'/>
<version>1007000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>50692</microcodeVersion>
<package></package>
<arch>x86_64</arch>
<cpu type='kvm' name='Opteron_G5'/>
......
......@@ -166,6 +166,7 @@
<flag name='isa-serial'/>
<version>2001001</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>59488</microcodeVersion>
<package></package>
<arch>x86_64</arch>
<cpu type='kvm' name='Opteron_G5'/>
......
......@@ -187,6 +187,7 @@
<flag name='pl011'/>
<version>2010000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>304138</microcodeVersion>
<package> (v2.10.0)</package>
<arch>aarch64</arch>
<cpu type='kvm' name='pxa262'/>
......
......@@ -187,6 +187,7 @@
<flag name='pl011'/>
<version>2010000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>304138</microcodeVersion>
<package> (v2.10.0)</package>
<arch>aarch64</arch>
<cpu type='kvm' name='pxa262'/>
......
......@@ -185,6 +185,7 @@
<flag name='isa-serial'/>
<version>2010000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>383421</microcodeVersion>
<package> (v2.10.0)</package>
<arch>ppc64</arch>
<cpu type='kvm' name='default'/>
......
......@@ -147,6 +147,7 @@
<flag name='iscsi.password-secret'/>
<version>2010000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>304153</microcodeVersion>
<package></package>
<arch>s390x</arch>
<hostCPU type='kvm' model='z14-base' migratability='no'>
......
......@@ -230,6 +230,7 @@
<flag name='isa-serial'/>
<version>2010000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>345185</microcodeVersion>
<package> (v2.10.0)</package>
<arch>x86_64</arch>
<hostCPU type='kvm' model='base' migratability='yes'>
......
......@@ -191,6 +191,7 @@
<flag name='isa-serial'/>
<version>2004000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>75653</microcodeVersion>
<package></package>
<arch>x86_64</arch>
<cpu type='kvm' name='Opteron_G5'/>
......
......@@ -197,6 +197,7 @@
<flag name='isa-serial'/>
<version>2005000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>216775</microcodeVersion>
<package></package>
<arch>x86_64</arch>
<cpu type='kvm' name='Opteron_G5'/>
......
......@@ -176,6 +176,7 @@
<flag name='pl011'/>
<version>2006000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>228838</microcodeVersion>
<package></package>
<arch>aarch64</arch>
<cpu type='kvm' name='pxa262'/>
......
......@@ -176,6 +176,7 @@
<flag name='pl011'/>
<version>2006000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>228838</microcodeVersion>
<package></package>
<arch>aarch64</arch>
<cpu type='kvm' name='pxa262'/>
......
......@@ -171,6 +171,7 @@
<flag name='isa-serial'/>
<version>2006000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>263602</microcodeVersion>
<package></package>
<arch>ppc64</arch>
<cpu type='kvm' name='default'/>
......
......@@ -207,6 +207,7 @@
<flag name='isa-serial'/>
<version>2006000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>227579</microcodeVersion>
<package></package>
<arch>x86_64</arch>
<cpu type='kvm' name='Opteron_G5'/>
......
......@@ -138,6 +138,7 @@
<flag name='sclplmconsole'/>
<version>2007000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>217559</microcodeVersion>
<package></package>
<arch>s390x</arch>
<cpu type='kvm' name='host'/>
......
......@@ -211,6 +211,7 @@
<flag name='isa-serial'/>
<version>2007000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>239276</microcodeVersion>
<package> (v2.7.0)</package>
<arch>x86_64</arch>
<cpu type='kvm' name='Opteron_G5'/>
......
......@@ -140,6 +140,7 @@
<flag name='sclplmconsole'/>
<version>2007093</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>242460</microcodeVersion>
<package></package>
<arch>s390x</arch>
<hostCPU type='kvm' model='zEC12.2-base' migratability='no'>
......
......@@ -213,6 +213,7 @@
<flag name='isa-serial'/>
<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'/>
......
......@@ -179,6 +179,7 @@
<flag name='isa-serial'/>
<version>2009000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>347135</microcodeVersion>
<package> (v2.9.0)</package>
<arch>ppc64</arch>
<cpu type='kvm' name='default'/>
......
......@@ -143,6 +143,7 @@
<flag name='iscsi.password-secret'/>
<version>2009000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>265878</microcodeVersion>
<package></package>
<arch>s390x</arch>
<hostCPU type='kvm' model='z13.2-base' migratability='no'>
......
......@@ -226,6 +226,7 @@
<flag name='isa-serial'/>
<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'>
......
......@@ -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;
......
......@@ -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);
......
......@@ -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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册