diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 8d583e3e74bf6f5494508d3dc084428d2e6f75e9..a705fa846d4e467f49e28ddffe946136f96e3d35 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1869,6 +1869,7 @@ virHostCPUGetCount; virHostCPUGetInfo; virHostCPUGetKVMMaxVCPUs; virHostCPUGetMap; +virHostCPUGetMicrocodeVersion; virHostCPUGetOnline; virHostCPUGetOnlineBitmap; virHostCPUGetPresentBitmap; diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c index c485a97211e18a86da8fba540c5a0670de6fda6a..956e7e793cc0166e41eaf0886930fb90f845d527 100644 --- a/src/util/virhostcpu.c +++ b/src/util/virhostcpu.c @@ -1206,3 +1206,50 @@ virHostCPUGetKVMMaxVCPUs(void) return -1; } #endif /* HAVE_LINUX_KVM_H */ + + +#ifdef __linux__ + +/* + * Returns 0 if the microcode version is unknown or cannot be read for + * some reason. + */ +unsigned int +virHostCPUGetMicrocodeVersion(void) +{ + char *outbuf = NULL; + char *cur; + unsigned int version = 0; + + if (virFileReadHeaderQuiet(CPUINFO_PATH, 4096, &outbuf) < 0) { + char ebuf[1024]; + VIR_DEBUG("Failed to read microcode version from %s: %s", + CPUINFO_PATH, virStrerror(errno, ebuf, sizeof(ebuf))); + return 0; + } + + /* Account for format 'microcode : XXXX'*/ + if (!(cur = strstr(outbuf, "microcode")) || + !(cur = strchr(cur, ':'))) + goto cleanup; + cur++; + + /* Linux places the microcode revision in a 32-bit integer, so + * ui is fine for us too. */ + if (virStrToLong_ui(cur, &cur, 0, &version) < 0) + goto cleanup; + + cleanup: + VIR_FREE(outbuf); + return version; +} + +#else + +unsigned int +virHostCPUGetMicrocodeVersion(void) +{ + return 0; +} + +#endif /* __linux__ */ diff --git a/src/util/virhostcpu.h b/src/util/virhostcpu.h index 67033de8422bbc7b3ec69ad7891a00e0d1a6c2c0..f9f33592881f55e88aa1642dc956e67a9ee55d37 100644 --- a/src/util/virhostcpu.h +++ b/src/util/virhostcpu.h @@ -66,4 +66,6 @@ virBitmapPtr virHostCPUGetSiblingsList(unsigned int cpu); int virHostCPUGetOnline(unsigned int cpu, bool *online); +unsigned int virHostCPUGetMicrocodeVersion(void); + #endif /* __VIR_HOSTCPU_H__*/