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);