diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c
index 603cf0e471..43a3ab5dcd 100644
--- a/src/conf/cpu_conf.c
+++ b/src/conf/cpu_conf.c
@@ -130,6 +130,7 @@ virCPUDefCopyModelFilter(virCPUDefPtr dst,
VIR_STRDUP(dst->vendor_id, src->vendor_id) < 0 ||
VIR_ALLOC_N(dst->features, src->nfeatures) < 0)
return -1;
+ dst->microcodeVersion = src->microcodeVersion;
dst->nfeatures_max = src->nfeatures;
dst->nfeatures = 0;
@@ -181,6 +182,7 @@ virCPUDefStealModel(virCPUDefPtr dst,
VIR_STEAL_PTR(dst->model, src->model);
VIR_STEAL_PTR(dst->features, src->features);
+ dst->microcodeVersion = src->microcodeVersion;
dst->nfeatures_max = src->nfeatures_max;
src->nfeatures_max = 0;
dst->nfeatures = src->nfeatures;
@@ -382,6 +384,14 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt,
goto cleanup;
}
VIR_FREE(arch);
+
+ if (virXPathBoolean("boolean(./microcode[1]/@version)", ctxt) > 0 &&
+ virXPathUInt("string(./microcode[1]/@version)", ctxt,
+ &def->microcodeVersion) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("invalid microcode version"));
+ goto cleanup;
+ }
}
if (!(def->model = virXPathString("string(./model[1])", ctxt)) &&
@@ -720,6 +730,10 @@ virCPUDefFormatBuf(virBufferPtr buf,
if (formatModel && def->vendor)
virBufferEscapeString(buf, "%s\n", def->vendor);
+ if (def->type == VIR_CPU_TYPE_HOST && def->microcodeVersion)
+ virBufferAsprintf(buf, "\n",
+ def->microcodeVersion);
+
if (def->sockets && def->cores && def->threads) {
virBufferAddLit(buf, "sockets);
diff --git a/src/conf/cpu_conf.h b/src/conf/cpu_conf.h
index d1983f5d4f..9f2e7ee264 100644
--- a/src/conf/cpu_conf.h
+++ b/src/conf/cpu_conf.h
@@ -133,6 +133,7 @@ struct _virCPUDef {
char *vendor_id; /* vendor id returned by CPUID in the guest */
int fallback; /* enum virCPUFallback */
char *vendor;
+ unsigned int microcodeVersion;
unsigned int sockets;
unsigned int cores;
unsigned int threads;
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index fddde64d8c..26314a5b3a 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -33,6 +33,7 @@
#include "virbuffer.h"
#include "virendian.h"
#include "virstring.h"
+#include "virhostcpu.h"
#define VIR_FROM_THIS VIR_FROM_CPU
@@ -153,6 +154,8 @@ struct _virCPUx86Map {
};
static virCPUx86MapPtr cpuMap;
+static unsigned int microcodeVersion;
+
int virCPUx86DriverOnceInit(void);
VIR_ONCE_GLOBAL_INIT(virCPUx86Driver);
@@ -1409,6 +1412,8 @@ virCPUx86DriverOnceInit(void)
if (!(cpuMap = virCPUx86LoadMap()))
return -1;
+ microcodeVersion = virHostCPUGetMicrocodeVersion();
+
return 0;
}
@@ -2424,6 +2429,9 @@ virCPUx86GetHost(virCPUDefPtr cpu,
virCPUDataPtr cpuData = NULL;
int ret = -1;
+ if (virCPUx86DriverInitialize() < 0)
+ goto cleanup;
+
if (!(cpuData = virCPUDataNew(archs[0])))
goto cleanup;
@@ -2432,6 +2440,7 @@ virCPUx86GetHost(virCPUDefPtr cpu,
goto cleanup;
ret = x86DecodeCPUData(cpu, cpuData, models);
+ cpu->microcodeVersion = microcodeVersion;
cleanup:
virCPUx86DataFree(cpuData);