diff --git a/SOURCES/libvirt-conf-include-x86-microcode-version-in-virsh-capabiltiies.patch b/SOURCES/libvirt-conf-include-x86-microcode-version-in-virsh-capabiltiies.patch
new file mode 100644
index 0000000..7c45cd5
--- /dev/null
+++ b/SOURCES/libvirt-conf-include-x86-microcode-version-in-virsh-capabiltiies.patch
@@ -0,0 +1,188 @@
+From a2fe4ef20df702070ffec676172c19e6c89b8312 Mon Sep 17 00:00:00 2001
+Message-Id: <a2fe4ef20df702070ffec676172c19e6c89b8312@dist-git>
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Tue, 12 Dec 2017 16:23:40 +0100
+Subject: [PATCH] conf: include x86 microcode version in virsh capabiltiies
+
+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.
+
+In order to track the x86 microcode version in the QEMU capabilities,
+we have to fetch it and store it in the host CPU.  This also makes the
+version visible in "virsh capabilities", which is a nice side effect.
+
+CVE-2017-5715
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+
+Conflicts:
+	src/cpu/cpu_x86.c
+            - context; x86DecodeCPUData has more parameters in 7.4
+---
+ src/conf/capabilities.c  | 12 ++++++++++++
+ src/conf/capabilities.h  |  2 ++
+ src/conf/cpu_conf.c      | 14 ++++++++++++++
+ src/conf/cpu_conf.h      |  1 +
+ src/cpu/cpu_x86.c        |  9 +++++++++
+ src/libvirt_private.syms |  1 +
+ 6 files changed, 39 insertions(+)
+
+diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c
+index 08907aced1..fad6cc1c07 100644
+--- a/src/conf/capabilities.c
++++ b/src/conf/capabilities.c
+@@ -355,6 +355,18 @@ virCapabilitiesAddHostNUMACell(virCapsPtr caps,
+ }
+ 
+ 
++/**
++ * virCapabilitiesGetMicrocodeVersion:
++ * @caps: capabilities to access
++ *
++ * Get host CPU microcode version, or 0 if unavailable
++ */
++unsigned int
++virCapabilitiesGetMicrocodeVersion(virCapsPtr caps)
++{
++    return caps->host.cpu ? caps->host.cpu->microcodeVersion : 0;
++}
++
+ /**
+  * virCapabilitiesSetHostCPU:
+  * @caps: capabilities to extend
+diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h
+index d10eef3afd..75e0748e9e 100644
+--- a/src/conf/capabilities.h
++++ b/src/conf/capabilities.h
+@@ -299,6 +299,8 @@ virBitmapPtr virCapabilitiesGetCpusForNodemask(virCapsPtr caps,
+ 
+ int virCapabilitiesGetNodeInfo(virNodeInfoPtr nodeinfo);
+ 
++unsigned int virCapabilitiesGetMicrocodeVersion(virCapsPtr caps);
++
+ int virCapabilitiesInitPages(virCapsPtr caps);
+ 
+ int virCapabilitiesInitNUMA(virCapsPtr caps);
+diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c
+index e570dffcd2..239f671fa7 100644
+--- a/src/conf/cpu_conf.c
++++ b/src/conf/cpu_conf.c
+@@ -127,6 +127,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;
+ 
+@@ -178,6 +179,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;
+@@ -379,6 +381,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, "<vendor>%s</vendor>\n", def->vendor);
+ 
++    if (def->type == VIR_CPU_TYPE_HOST && def->microcodeVersion)
++        virBufferAsprintf(buf, "<microcode version='%u'/>\n",
++                          def->microcodeVersion);
++
+     if (def->sockets && def->cores && def->threads) {
+         virBufferAddLit(buf, "<topology");
+         virBufferAsprintf(buf, " sockets='%u'", def->sockets);
+diff --git a/src/conf/cpu_conf.h b/src/conf/cpu_conf.h
+index 1978814d36..1a13ae6e46 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 8af0a1a2b7..efef7f235d 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);
+ 
+@@ -1391,6 +1394,8 @@ virCPUx86DriverOnceInit(void)
+     if (!(cpuMap = virCPUx86LoadMap()))
+         return -1;
+ 
++    microcodeVersion = virHostCPUGetMicrocodeVersion();
++
+     return 0;
+ }
+ 
+@@ -2408,6 +2413,9 @@ virCPUx86GetHost(virCPUDefPtr cpu,
+     virCPUDataPtr cpuData = NULL;
+     int ret = -1;
+ 
++    if (virCPUx86DriverInitialize() < 0)
++        goto cleanup;
++
+     if (!(cpuData = virCPUDataNew(archs[0])))
+         goto cleanup;
+ 
+@@ -2416,6 +2424,7 @@ virCPUx86GetHost(virCPUDefPtr cpu,
+         goto cleanup;
+ 
+     ret = x86DecodeCPUData(cpu, cpuData, models, nmodels, NULL);
++    cpu->microcodeVersion = microcodeVersion;
+ 
+  cleanup:
+     virCPUx86DataFree(cpuData);
+diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
+index c50b6c2f77..c7834115fd 100644
+--- a/src/libvirt_private.syms
++++ b/src/libvirt_private.syms
+@@ -57,6 +57,7 @@ virCapabilitiesFreeGuest;
+ virCapabilitiesFreeMachines;
+ virCapabilitiesFreeNUMAInfo;
+ virCapabilitiesGetCpusForNodemask;
++virCapabilitiesGetMicrocodeVersion;
+ virCapabilitiesGetNodeInfo;
+ virCapabilitiesHostSecModelAddBaseLabel;
+ virCapabilitiesInitNUMA;
+-- 
+2.15.1
+
diff --git a/SOURCES/libvirt-cpu-add-CPU-features-and-model-for-indirect-branch-prediction-protection.patch b/SOURCES/libvirt-cpu-add-CPU-features-and-model-for-indirect-branch-prediction-protection.patch
new file mode 100644
index 0000000..d264d5d
--- /dev/null
+++ b/SOURCES/libvirt-cpu-add-CPU-features-and-model-for-indirect-branch-prediction-protection.patch
@@ -0,0 +1,153 @@
+From b3505e6f099cf4af35e254e077bb61cf62f035ed Mon Sep 17 00:00:00 2001
+Message-Id: <b3505e6f099cf4af35e254e077bb61cf62f035ed@dist-git>
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Tue, 12 Dec 2017 16:23:42 +0100
+Subject: [PATCH] cpu: add CPU features and model for indirect branch
+ prediction protection
+
+CVE-2017-5715
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+
+Conflicts:
+	src/cpu/cpu_map.xml
+            - no Skylake-Server and EPYC CPU models
+---
+ src/cpu/cpu_map.xml | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 50 insertions(+)
+
+diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml
+index 29b5b596f4..7fbba9f0d8 100644
+--- a/src/cpu/cpu_map.xml
++++ b/src/cpu/cpu_map.xml
+@@ -283,6 +283,15 @@
+     <feature name='avx512-4fmaps'>
+       <cpuid eax_in='0x07' edx='0x00000008'/>
+     </feature>
++    <feature name='spec-ctrl'>
++      <cpuid eax_in='0x07' ecx_in='0x00' edx='0x04000000'/>
++    </feature>
++    <feature name='stibp'>
++      <cpuid eax_in='0x07' ecx_in='0x00' edx='0x08000000'/>
++    </feature>
++    <feature name='arch-facilities'>
++      <cpuid eax_in='0x07' ecx_in='0x00' edx='0x20000000'/>
++    </feature>
+ 
+     <!-- Processor Extended State Enumeration sub leaf 1 -->
+     <feature name='xsaveopt'>
+@@ -411,6 +420,11 @@
+       <cpuid eax_in='0x80000007' edx='0x00000100'/>
+     </feature>
+ 
++    <!-- More AMD-specific features -->
++    <feature name='ibpb'>
++      <cpuid eax_in='0x80000008' ebx='0x00001000'/>
++    </feature>
++
+     <!-- models -->
+     <model name='486'>
+       <feature name='fpu'/>
+@@ -857,6 +871,10 @@
+       <feature name='syscall'/>
+       <feature name='tsc'/>
+     </model>
++    <model name='Nehalem-IBRS'>
++      <model name='Nehalem'/>
++      <feature name='spec-ctrl'/>
++    </model>
+ 
+     <model name='Westmere'>
+       <signature family='6' model='44'/>
+@@ -894,6 +912,10 @@
+       <feature name='syscall'/>
+       <feature name='tsc'/>
+     </model>
++    <model name='Westmere-IBRS'>
++      <model name='Westmere'/>
++      <feature name='spec-ctrl'/>
++    </model>
+ 
+     <model name='SandyBridge'>
+       <signature family='6' model='42'/>
+@@ -937,6 +959,10 @@
+       <feature name='x2apic'/>
+       <feature name='xsave'/>
+     </model>
++    <model name='SandyBridge-IBRS'>
++      <model name='SandyBridge'/>
++      <feature name='spec-ctrl'/>
++    </model>
+ 
+     <model name='IvyBridge'>
+       <signature family='6' model='58'/>
+@@ -986,6 +1012,10 @@
+       <feature name='x2apic'/>
+       <feature name='xsave'/>
+     </model>
++    <model name='IvyBridge-IBRS'>
++      <model name='IvyBridge'/>
++      <feature name='spec-ctrl'/>
++    </model>
+ 
+     <model name='Haswell-noTSX'>
+       <signature family='6' model='60'/>
+@@ -1039,6 +1069,10 @@
+       <feature name='x2apic'/>
+       <feature name='xsave'/>
+     </model>
++    <model name='Haswell-noTSX-IBRS'>
++      <model name='Haswell-noTSX'/>
++      <feature name='spec-ctrl'/>
++    </model>
+ 
+     <model name='Haswell'>
+       <signature family='6' model='60'/>
+@@ -1094,6 +1128,10 @@
+       <feature name='x2apic'/>
+       <feature name='xsave'/>
+     </model>
++    <model name='Haswell-IBRS'>
++      <model name='Haswell'/>
++      <feature name='spec-ctrl'/>
++    </model>
+ 
+     <model name='Broadwell-noTSX'>
+       <signature family='6' model='61'/>
+@@ -1151,6 +1189,10 @@
+       <feature name='x2apic'/>
+       <feature name='xsave'/>
+     </model>
++    <model name='Broadwell-noTSX-IBRS'>
++      <model name='Broadwell-noTSX'/>
++      <feature name='spec-ctrl'/>
++    </model>
+ 
+     <model name='Broadwell'>
+       <signature family='6' model='61'/>
+@@ -1210,6 +1252,10 @@
+       <feature name='x2apic'/>
+       <feature name='xsave'/>
+     </model>
++    <model name='Broadwell-IBRS'>
++      <model name='Broadwell'/>
++      <feature name='spec-ctrl'/>
++    </model>
+ 
+     <model name='Skylake-Client'>
+       <signature family='6' model='94'/>
+@@ -1278,6 +1324,10 @@
+       <feature name='xsavec'/>
+       <feature name='xsaveopt'/>
+     </model>
++    <model name='Skylake-Client-IBRS'>
++      <model name='Skylake-Client'/>
++      <feature name='spec-ctrl'/>
++    </model>
+ 
+     <!-- AMD CPUs -->
+     <model name='athlon'>
+-- 
+2.15.1
+
diff --git a/SOURCES/libvirt-cpu_x86-Rename-virCPUx86MapInitialize.patch b/SOURCES/libvirt-cpu_x86-Rename-virCPUx86MapInitialize.patch
new file mode 100644
index 0000000..1808387
--- /dev/null
+++ b/SOURCES/libvirt-cpu_x86-Rename-virCPUx86MapInitialize.patch
@@ -0,0 +1,52 @@
+From 3a74e5ae1229d1be6792178e650174f4a740e869 Mon Sep 17 00:00:00 2001
+Message-Id: <3a74e5ae1229d1be6792178e650174f4a740e869@dist-git>
+From: Jiri Denemark <jdenemar@redhat.com>
+Date: Wed, 13 Dec 2017 22:30:31 +0100
+Subject: [PATCH] cpu_x86: Rename virCPUx86MapInitialize
+
+The function will be used to initialize internal data of the x86 CPU
+driver (including the CPU map).
+
+CVE-2017-5715
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/cpu/cpu_x86.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
+index 2864454211..8af0a1a2b7 100644
+--- a/src/cpu/cpu_x86.c
++++ b/src/cpu/cpu_x86.c
+@@ -153,8 +153,8 @@ struct _virCPUx86Map {
+ };
+ 
+ static virCPUx86MapPtr cpuMap;
+-int virCPUx86MapOnceInit(void);
+-VIR_ONCE_GLOBAL_INIT(virCPUx86Map);
++int virCPUx86DriverOnceInit(void);
++VIR_ONCE_GLOBAL_INIT(virCPUx86Driver);
+ 
+ 
+ typedef enum {
+@@ -1386,7 +1386,7 @@ virCPUx86LoadMap(void)
+ 
+ 
+ int
+-virCPUx86MapOnceInit(void)
++virCPUx86DriverOnceInit(void)
+ {
+     if (!(cpuMap = virCPUx86LoadMap()))
+         return -1;
+@@ -1398,7 +1398,7 @@ virCPUx86MapOnceInit(void)
+ static virCPUx86MapPtr
+ virCPUx86GetMap(void)
+ {
+-    if (virCPUx86MapInitialize() < 0)
++    if (virCPUx86DriverInitialize() < 0)
+         return NULL;
+ 
+     return cpuMap;
+-- 
+2.15.1
+
diff --git a/SOURCES/libvirt-qemu-Properly-store-microcode-version-in-QEMU-caps-cache.patch b/SOURCES/libvirt-qemu-Properly-store-microcode-version-in-QEMU-caps-cache.patch
new file mode 100644
index 0000000..3ff4a58
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Properly-store-microcode-version-in-QEMU-caps-cache.patch
@@ -0,0 +1,47 @@
+From e3e7aa7c8ad6d687b9605b0da3b46ad0ef171157 Mon Sep 17 00:00:00 2001
+Message-Id: <e3e7aa7c8ad6d687b9605b0da3b46ad0ef171157@dist-git>
+From: Jiri Denemark <jdenemar@redhat.com>
+Date: Tue, 19 Dec 2017 08:36:49 +0100
+Subject: [PATCH] qemu: Properly store microcode version in QEMU caps cache
+
+This fixes a misplaced hunk in the backport of "qemu: capabilities:
+force update if the microcode version does not match". We need to make
+sure the microcode version is assigned to QEMU caps object before the
+caps get stored on a disk. Otherwise QEMU caps cached on a disk would
+always be considered invalid when libvirtd starts and tries to load
+them.
+
+CVE-2017-5715
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/qemu/qemu_capabilities.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
+index 504e2c9587..8f9b1493a5 100644
+--- a/src/qemu/qemu_capabilities.c
++++ b/src/qemu/qemu_capabilities.c
+@@ -5210,6 +5210,9 @@ virQEMUCapsNewForBinaryInternal(virCapsPtr caps,
+             goto error;
+         }
+ 
++        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
++            qemuCaps->microcodeVersion = microcodeVersion;
++
+         if (cacheDir &&
+             virQEMUCapsRememberCached(qemuCaps, cacheDir) < 0)
+             goto error;
+@@ -5218,9 +5221,6 @@ virQEMUCapsNewForBinaryInternal(virCapsPtr caps,
+         virQEMUCapsInitHostCPUModel(qemuCaps, caps, VIR_DOMAIN_VIRT_QEMU);
+     }
+ 
+-    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
+-        qemuCaps->microcodeVersion = microcodeVersion;
+-
+  cleanup:
+     VIR_FREE(qmperr);
+     return qemuCaps;
+-- 
+2.15.1
+
diff --git a/SOURCES/libvirt-qemu-capabilities-force-update-if-the-microcode-version-does-not-match.patch b/SOURCES/libvirt-qemu-capabilities-force-update-if-the-microcode-version-does-not-match.patch
new file mode 100644
index 0000000..d993f7d
--- /dev/null
+++ b/SOURCES/libvirt-qemu-capabilities-force-update-if-the-microcode-version-does-not-match.patch
@@ -0,0 +1,588 @@
+From ac08fdc6dcbdc6e9fdb976fd2143c663d3748752 Mon Sep 17 00:00:00 2001
+Message-Id: <ac08fdc6dcbdc6e9fdb976fd2143c663d3748752@dist-git>
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Tue, 12 Dec 2017 16:23:41 +0100
+Subject: [PATCH] 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.
+
+CVE-2017-5715
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+
+Conflicts:
+	src/qemu/qemu_capabilities.c
+	src/qemu/qemu_capabilities.h
+            - virQEMUCapsCache is based on virFileCache in 7.5
+
+	src/qemu/qemu_capspriv.h
+            - context; more functions were added in 7.5
+
+	tests/qemucapabilitiesdata/caps_2.10.0-gicv2.aarch64.xml
+	tests/qemucapabilitiesdata/caps_2.10.0-gicv3.aarch64.xml
+	tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml
+	tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml
+	tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml
+	tests/qemucapabilitiesdata/caps_2.9.0.ppc64.xml
+	tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml
+            - missing in 7.4
+
+	tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
+            - context; different package version in 7.4
+
+	tests/qemucapsprobe.c
+            - virQEMUCapsNewForBinaryInternal has fewer parameters
+              in 7.5
+---
+ src/qemu/qemu_capabilities.c                       | 56 +++++++++++++++++++---
+ src/qemu/qemu_capabilities.h                       |  7 ++-
+ src/qemu/qemu_capspriv.h                           |  6 +++
+ src/qemu/qemu_driver.c                             |  9 +++-
+ tests/qemucapabilitiesdata/caps_1.2.2.x86_64.xml   |  1 +
+ tests/qemucapabilitiesdata/caps_1.3.1.x86_64.xml   |  1 +
+ tests/qemucapabilitiesdata/caps_1.4.2.x86_64.xml   |  1 +
+ tests/qemucapabilitiesdata/caps_1.5.3.x86_64.xml   |  1 +
+ tests/qemucapabilitiesdata/caps_1.6.0.x86_64.xml   |  1 +
+ tests/qemucapabilitiesdata/caps_1.7.0.x86_64.xml   |  1 +
+ tests/qemucapabilitiesdata/caps_2.1.1.x86_64.xml   |  1 +
+ tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml   |  1 +
+ tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml   |  1 +
+ .../caps_2.6.0-gicv2.aarch64.xml                   |  1 +
+ .../caps_2.6.0-gicv3.aarch64.xml                   |  1 +
+ tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml  |  1 +
+ tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml   |  1 +
+ tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml    |  1 +
+ tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml   |  1 +
+ tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml    |  1 +
+ tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml   |  1 +
+ tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml   |  1 +
+ tests/qemucapabilitiestest.c                       | 14 ++++--
+ tests/qemucapsprobe.c                              |  2 +-
+ tests/testutilsqemu.c                              |  2 +-
+ 25 files changed, 98 insertions(+), 16 deletions(-)
+
+diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
+index a42f8d9988..504e2c9587 100644
+--- a/src/qemu/qemu_capabilities.c
++++ b/src/qemu/qemu_capabilities.c
+@@ -426,6 +426,7 @@ struct _virQEMUCaps {
+ 
+     unsigned int version;
+     unsigned int kvmVersion;
++    unsigned int microcodeVersion;
+     char *package;
+ 
+     virArch arch;
+@@ -2217,6 +2218,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;
+@@ -3817,6 +3819,13 @@ virQEMUCapsLoadCache(virCapsPtr caps,
+         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 &&
+@@ -4083,6 +4092,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);
+@@ -4286,7 +4298,8 @@ virQEMUCapsInitCached(virCapsPtr caps,
+         goto discard;
+     }
+ 
+-    if (!virQEMUCapsIsValid(qemuCaps, qemuctime, runUid, runGid))
++    if (!virQEMUCapsIsValid(qemuCaps, qemuctime, runUid, runGid,
++                            virCapabilitiesGetMicrocodeVersion(caps)))
+         goto discard;
+ 
+     /* Discard cache if QEMU binary or libvirtd changed */
+@@ -5138,6 +5151,7 @@ virQEMUCapsNewForBinaryInternal(virCapsPtr caps,
+                                 const char *cacheDir,
+                                 uid_t runUid,
+                                 gid_t runGid,
++                                unsigned int microcodeVersion,
+                                 bool qmpOnly)
+ {
+     virQEMUCapsPtr qemuCaps;
+@@ -5204,6 +5218,9 @@ virQEMUCapsNewForBinaryInternal(virCapsPtr caps,
+         virQEMUCapsInitHostCPUModel(qemuCaps, caps, VIR_DOMAIN_VIRT_QEMU);
+     }
+ 
++    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
++        qemuCaps->microcodeVersion = microcodeVersion;
++
+  cleanup:
+     VIR_FREE(qmperr);
+     return qemuCaps;
+@@ -5220,10 +5237,12 @@ virQEMUCapsNewForBinary(virCapsPtr caps,
+                         const char *libDir,
+                         const char *cacheDir,
+                         uid_t runUid,
+-                        gid_t runGid)
++                        gid_t runGid,
++                        unsigned int microcodeVersion)
+ {
+     return virQEMUCapsNewForBinaryInternal(caps, binary, libDir, cacheDir,
+-                                           runUid, runGid, false);
++                                           runUid, runGid, microcodeVersion,
++                                           false);
+ }
+ 
+ 
+@@ -5231,7 +5250,8 @@ bool
+ virQEMUCapsIsValid(virQEMUCapsPtr qemuCaps,
+                    time_t qemuctime,
+                    uid_t runUid,
+-                   gid_t runGid)
++                   gid_t runGid,
++                   unsigned int microcodeVersion)
+ {
+     bool kvmUsable;
+ 
+@@ -5279,6 +5299,16 @@ virQEMUCapsIsValid(virQEMUCapsPtr qemuCaps,
+         return false;
+     }
+ 
++    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM) &&
++        microcodeVersion != qemuCaps->microcodeVersion) {
++        VIR_DEBUG("Outdated capabilities for '%s': microcode version changed "
++                  "(%u vs %u)",
++                  qemuCaps->binary,
++                  microcodeVersion,
++                  qemuCaps->microcodeVersion);
++        return false;
++    }
++
+     return true;
+ }
+ 
+@@ -5325,7 +5355,8 @@ virQEMUCapsCachePtr
+ virQEMUCapsCacheNew(const char *libDir,
+                     const char *cacheDir,
+                     uid_t runUid,
+-                    gid_t runGid)
++                    gid_t runGid,
++                    unsigned int microcodeVersion)
+ {
+     virQEMUCapsCachePtr cache;
+ 
+@@ -5348,6 +5379,7 @@ virQEMUCapsCacheNew(const char *libDir,
+ 
+     cache->runUid = runUid;
+     cache->runGid = runGid;
++    cache->microcodeVersion = microcodeVersion;
+ 
+     return cache;
+ 
+@@ -5364,7 +5396,8 @@ virQEMUCapsCacheValidate(virQEMUCapsCachePtr cache,
+                          virQEMUCapsPtr *qemuCaps)
+ {
+     if (*qemuCaps &&
+-        !virQEMUCapsIsValid(*qemuCaps, 0, cache->runUid, cache->runGid)) {
++        !virQEMUCapsIsValid(*qemuCaps, 0, cache->runUid, cache->runGid,
++                            virCapabilitiesGetMicrocodeVersion(caps))) {
+         VIR_DEBUG("Cached capabilities %p no longer valid for %s",
+                   *qemuCaps, binary);
+         virHashRemoveEntry(cache->binaries, binary);
+@@ -5375,7 +5408,8 @@ virQEMUCapsCacheValidate(virQEMUCapsCachePtr cache,
+         VIR_DEBUG("Creating capabilities for %s", binary);
+         *qemuCaps = virQEMUCapsNewForBinary(caps, binary,
+                                             cache->libDir, cache->cacheDir,
+-                                            cache->runUid, cache->runGid);
++                                            cache->runUid, cache->runGid,
++                                            virCapabilitiesGetMicrocodeVersion(caps));
+         if (*qemuCaps) {
+             VIR_DEBUG("Caching capabilities %p for %s", *qemuCaps, binary);
+             if (virHashAddEntry(cache->binaries, binary, *qemuCaps) < 0) {
+@@ -5926,3 +5960,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 bc4ad44496..d1a1d46b5a 100644
+--- a/src/qemu/qemu_capabilities.h
++++ b/src/qemu/qemu_capabilities.h
+@@ -497,7 +497,8 @@ int virQEMUCapsGetMachineTypesCaps(virQEMUCapsPtr qemuCaps,
+ bool virQEMUCapsIsValid(virQEMUCapsPtr qemuCaps,
+                         time_t ctime,
+                         uid_t runUid,
+-                        gid_t runGid);
++                        gid_t runGid,
++                        unsigned int microcodeVersion);
+ 
+ void virQEMUCapsFilterByMachineType(virQEMUCapsPtr qemuCaps,
+                                     const char *machineType);
+@@ -509,7 +510,9 @@ void virQEMUCapsSetGICCapabilities(virQEMUCapsPtr qemuCaps,
+ 
+ virQEMUCapsCachePtr virQEMUCapsCacheNew(const char *libDir,
+                                         const char *cacheDir,
+-                                        uid_t uid, gid_t gid);
++                                        uid_t uid,
++                                        gid_t gid,
++                                        unsigned int microcodeVersion);
+ virQEMUCapsPtr virQEMUCapsCacheLookup(virCapsPtr caps,
+                                       virQEMUCapsCachePtr cache,
+                                       const char *binary);
+diff --git a/src/qemu/qemu_capspriv.h b/src/qemu/qemu_capspriv.h
+index 1baaaf3340..d39a71a2f8 100644
+--- a/src/qemu/qemu_capspriv.h
++++ b/src/qemu/qemu_capspriv.h
+@@ -35,6 +35,7 @@ struct _virQEMUCapsCache {
+     char *cacheDir;
+     uid_t runUid;
+     gid_t runGid;
++    unsigned int microcodeVersion;
+ };
+ 
+ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps);
+@@ -46,6 +47,7 @@ virQEMUCapsNewForBinaryInternal(virCapsPtr caps,
+                                 const char *cacheDir,
+                                 uid_t runUid,
+                                 gid_t runGid,
++                                unsigned int microcodeVersion,
+                                 bool qmpOnly);
+ 
+ int virQEMUCapsLoadCache(virCapsPtr caps,
+@@ -93,4 +95,8 @@ virCPUDefPtr
+ virQEMUCapsProbeHostCPUForEmulator(virCapsPtr caps,
+                                    virQEMUCapsPtr qemuCaps,
+                                    virDomainVirtType type);
++
++void
++virQEMUCapsSetMicrocodeVersion(virQEMUCapsPtr qemuCaps,
++                               unsigned int microcodeVersion);
+ #endif
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 498f787ad3..0943d222b4 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -628,6 +628,8 @@ qemuStateInitialize(bool privileged,
+     gid_t run_gid = -1;
+     char *hugepagePath = NULL;
+     size_t i;
++    virCPUDefPtr hostCPU = NULL;
++    unsigned int microcodeVersion = 0;
+ 
+     if (VIR_ALLOC(qemu_driver) < 0)
+         return -1;
+@@ -847,10 +849,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 5ad406ce1b..12d5873251 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 @@
+   <flag name='query-cpu-definitions'/>
+   <version>1002002</version>
+   <kvmVersion>0</kvmVersion>
++  <microcodeVersion>26900</microcodeVersion>
+   <package></package>
+   <arch>x86_64</arch>
+   <cpu type='kvm' name='qemu64'/>
+diff --git a/tests/qemucapabilitiesdata/caps_1.3.1.x86_64.xml b/tests/qemucapabilitiesdata/caps_1.3.1.x86_64.xml
+index 4ec731d655..8bfbf79a74 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 @@
+   <flag name='query-cpu-definitions'/>
+   <version>1003001</version>
+   <kvmVersion>0</kvmVersion>
++  <microcodeVersion>30198</microcodeVersion>
+   <package></package>
+   <arch>x86_64</arch>
+   <cpu type='kvm' name='qemu64'/>
+diff --git a/tests/qemucapabilitiesdata/caps_1.4.2.x86_64.xml b/tests/qemucapabilitiesdata/caps_1.4.2.x86_64.xml
+index 601c62e65a..19925d0f29 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 @@
+   <flag name='query-cpu-definitions'/>
+   <version>1004002</version>
+   <kvmVersion>0</kvmVersion>
++  <microcodeVersion>30915</microcodeVersion>
+   <package></package>
+   <arch>x86_64</arch>
+   <cpu type='kvm' name='Opteron_G5'/>
+diff --git a/tests/qemucapabilitiesdata/caps_1.5.3.x86_64.xml b/tests/qemucapabilitiesdata/caps_1.5.3.x86_64.xml
+index 14f34b2771..df3c2d87b6 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 @@
+   <flag name='kernel-irqchip'/>
+   <version>1005003</version>
+   <kvmVersion>0</kvmVersion>
++  <microcodeVersion>47019</microcodeVersion>
+   <package></package>
+   <arch>x86_64</arch>
+   <cpu type='kvm' name='Opteron_G5'/>
+diff --git a/tests/qemucapabilitiesdata/caps_1.6.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_1.6.0.x86_64.xml
+index 8fc23d6aad..889cd96dde 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 @@
+   <flag name='kernel-irqchip'/>
+   <version>1006000</version>
+   <kvmVersion>0</kvmVersion>
++  <microcodeVersion>45248</microcodeVersion>
+   <package></package>
+   <arch>x86_64</arch>
+   <cpu type='kvm' name='Opteron_G5'/>
+diff --git a/tests/qemucapabilitiesdata/caps_1.7.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_1.7.0.x86_64.xml
+index 47c8956b44..426fcfc139 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 @@
+   <flag name='kernel-irqchip'/>
+   <version>1007000</version>
+   <kvmVersion>0</kvmVersion>
++  <microcodeVersion>50692</microcodeVersion>
+   <package></package>
+   <arch>x86_64</arch>
+   <cpu type='kvm' name='Opteron_G5'/>
+diff --git a/tests/qemucapabilitiesdata/caps_2.1.1.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.1.1.x86_64.xml
+index afe7d53ff4..82737b2a7f 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 @@
+   <flag name='kernel-irqchip'/>
+   <version>2001001</version>
+   <kvmVersion>0</kvmVersion>
++  <microcodeVersion>59488</microcodeVersion>
+   <package></package>
+   <arch>x86_64</arch>
+   <cpu type='kvm' name='Opteron_G5'/>
+diff --git a/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml
+index 5bdc1a2bdd..dca3452861 100644
+--- a/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml
++++ b/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml
+@@ -188,6 +188,7 @@
+   <flag name='kernel-irqchip'/>
+   <version>2004000</version>
+   <kvmVersion>0</kvmVersion>
++  <microcodeVersion>75653</microcodeVersion>
+   <package></package>
+   <arch>x86_64</arch>
+   <cpu type='kvm' name='Opteron_G5'/>
+diff --git a/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml
+index 36bc1342bb..03bc558c18 100644
+--- a/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml
++++ b/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml
+@@ -194,6 +194,7 @@
+   <flag name='kernel-irqchip'/>
+   <version>2005000</version>
+   <kvmVersion>0</kvmVersion>
++  <microcodeVersion>216775</microcodeVersion>
+   <package></package>
+   <arch>x86_64</arch>
+   <cpu type='kvm' name='Opteron_G5'/>
+diff --git a/tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml b/tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml
+index 33bc462084..c78719c778 100644
+--- a/tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml
++++ b/tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml
+@@ -172,6 +172,7 @@
+   <flag name='kernel-irqchip.split'/>
+   <version>2006000</version>
+   <kvmVersion>0</kvmVersion>
++  <microcodeVersion>228838</microcodeVersion>
+   <package></package>
+   <arch>aarch64</arch>
+   <cpu type='kvm' name='pxa262'/>
+diff --git a/tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml b/tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml
+index a8ce6b03b1..314b9407c0 100644
+--- a/tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml
++++ b/tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml
+@@ -172,6 +172,7 @@
+   <flag name='kernel-irqchip.split'/>
+   <version>2006000</version>
+   <kvmVersion>0</kvmVersion>
++  <microcodeVersion>228838</microcodeVersion>
+   <package></package>
+   <arch>aarch64</arch>
+   <cpu type='kvm' name='pxa262'/>
+diff --git a/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml b/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml
+index 425992f0d5..f09d0f74d1 100644
+--- a/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml
++++ b/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml
+@@ -166,6 +166,7 @@
+   <flag name='kernel-irqchip.split'/>
+   <version>2006000</version>
+   <kvmVersion>0</kvmVersion>
++  <microcodeVersion>262913</microcodeVersion>
+   <package></package>
+   <arch>ppc64</arch>
+   <cpu type='kvm' name='default'/>
+diff --git a/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml
+index 97e71ec4f4..4dadf178bd 100644
+--- a/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml
++++ b/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml
+@@ -204,6 +204,7 @@
+   <flag name='kernel-irqchip.split'/>
+   <version>2006000</version>
+   <kvmVersion>0</kvmVersion>
++  <microcodeVersion>227579</microcodeVersion>
+   <package></package>
+   <arch>x86_64</arch>
+   <cpu type='kvm' name='Opteron_G5'/>
+diff --git a/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml
+index 70cce64179..75d77ccd13 100644
+--- a/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml
++++ b/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml
+@@ -134,6 +134,7 @@
+   <flag name='kernel-irqchip.split'/>
+   <version>2007000</version>
+   <kvmVersion>0</kvmVersion>
++  <microcodeVersion>217559</microcodeVersion>
+   <package></package>
+   <arch>s390x</arch>
+   <cpu type='kvm' name='host'/>
+diff --git a/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml
+index 49c046212b..b9531ad2d2 100644
+--- a/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml
++++ b/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml
+@@ -207,6 +207,7 @@
+   <flag name='intel-iommu.intremap'/>
+   <version>2007000</version>
+   <kvmVersion>0</kvmVersion>
++  <microcodeVersion>239276</microcodeVersion>
+   <package> (v2.7.0)</package>
+   <arch>x86_64</arch>
+   <cpu type='kvm' name='Opteron_G5'/>
+diff --git a/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml
+index 51be9bce4d..a707d76bc3 100644
+--- a/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml
++++ b/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml
+@@ -136,6 +136,7 @@
+   <flag name='kernel-irqchip.split'/>
+   <version>2007093</version>
+   <kvmVersion>0</kvmVersion>
++  <microcodeVersion>242460</microcodeVersion>
+   <package></package>
+   <arch>s390x</arch>
+   <hostCPU type='kvm' model='zEC12.2-base' migratability='no'>
+diff --git a/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml
+index 01edbc88da..d3bce6b15c 100644
+--- a/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml
++++ b/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml
+@@ -209,6 +209,7 @@
+   <flag name='intel-iommu.eim'/>
+   <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'/>
+diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
+index 2140eab398..34dd9353d8 100644
+--- a/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
++++ b/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
+@@ -219,6 +219,7 @@
+   <flag name='virtio.ats'/>
+   <version>2008090</version>
+   <kvmVersion>0</kvmVersion>
++  <microcodeVersion>317985</microcodeVersion>
+   <package> (v2.9.0-rc0-142-g940a8ce)</package>
+   <arch>x86_64</arch>
+   <hostCPU type='kvm' model='base' migratability='yes'>
+diff --git a/tests/qemucapabilitiestest.c b/tests/qemucapabilitiestest.c
+index 2918ff4695..c817478e49 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, 0, 0)))
+         goto cleanup;
+diff --git a/tests/qemucapsprobe.c b/tests/qemucapsprobe.c
+index 561c5d7c14..03bf81d3bd 100644
+--- a/tests/qemucapsprobe.c
++++ b/tests/qemucapsprobe.c
+@@ -71,7 +71,7 @@ main(int argc, char **argv)
+         return EXIT_FAILURE;
+ 
+     if (!(caps = virQEMUCapsNewForBinaryInternal(NULL, argv[1], "/tmp", NULL,
+-                                                 -1, -1, true)))
++                                                 -1, -1, 0, true)))
+         return EXIT_FAILURE;
+ 
+     virObjectUnref(caps);
+diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c
+index 4cc482dfb0..e0fb97fba1 100644
+--- a/tests/testutilsqemu.c
++++ b/tests/testutilsqemu.c
+@@ -600,7 +600,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;
+ 
+-- 
+2.15.1
+
diff --git a/SOURCES/libvirt-util-add-virFileReadHeaderQuiet-wrapper-around-virFileReadHeaderFD.patch b/SOURCES/libvirt-util-add-virFileReadHeaderQuiet-wrapper-around-virFileReadHeaderFD.patch
new file mode 100644
index 0000000..038c84a
--- /dev/null
+++ b/SOURCES/libvirt-util-add-virFileReadHeaderQuiet-wrapper-around-virFileReadHeaderFD.patch
@@ -0,0 +1,75 @@
+From da15d67c5cf0b6c0c1974d8ca251dbeec3d6a964 Mon Sep 17 00:00:00 2001
+Message-Id: <da15d67c5cf0b6c0c1974d8ca251dbeec3d6a964@dist-git>
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Tue, 12 Dec 2017 16:23:40 +0100
+Subject: [PATCH] util: add virFileReadHeaderQuiet wrapper around
+ virFileReadHeaderFD
+
+CVE-2017-5715
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/libvirt_private.syms |  1 +
+ src/util/virfile.c       | 19 +++++++++++++++++++
+ src/util/virfile.h       |  2 ++
+ 3 files changed, 22 insertions(+)
+
+diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
+index 62ebb8180e..0c972d1861 100644
+--- a/src/libvirt_private.syms
++++ b/src/libvirt_private.syms
+@@ -1646,6 +1646,7 @@ virFileReadAll;
+ virFileReadAllQuiet;
+ virFileReadBufQuiet;
+ virFileReadHeaderFD;
++virFileReadHeaderQuiet;
+ virFileReadLimFD;
+ virFileReadLink;
+ virFileReadValueBitmap;
+diff --git a/src/util/virfile.c b/src/util/virfile.c
+index a91c2c3495..51d1f5ce66 100644
+--- a/src/util/virfile.c
++++ b/src/util/virfile.c
+@@ -1356,6 +1356,25 @@ virFileReadHeaderFD(int fd, int maxlen, char **buf)
+ }
+ 
+ 
++int
++virFileReadHeaderQuiet(const char *path,
++                       int maxlen,
++                       char **buf)
++{
++    int fd;
++    int len;
++
++    fd = open(path, O_RDONLY);
++    if (fd < 0)
++        return -1;
++
++    len = virFileReadHeaderFD(fd, maxlen, buf);
++    VIR_FORCE_CLOSE(fd);
++
++    return len;
++}
++
++
+ /* A wrapper around saferead_lim that maps a failure due to
+    exceeding the maximum size limitation to EOVERFLOW.  */
+ int
+diff --git a/src/util/virfile.h b/src/util/virfile.h
+index ba1c57c06a..38cc23ecaa 100644
+--- a/src/util/virfile.h
++++ b/src/util/virfile.h
+@@ -129,6 +129,8 @@ int virFileDeleteTree(const char *dir);
+ 
+ int virFileReadHeaderFD(int fd, int maxlen, char **buf)
+     ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(3);
++int virFileReadHeaderQuiet(const char *path, int maxlen, char **buf)
++    ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3);
+ int virFileReadLimFD(int fd, int maxlen, char **buf)
+     ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(3);
+ int virFileReadAll(const char *path, int maxlen, char **buf)
+-- 
+2.15.1
+
diff --git a/SOURCES/libvirt-util-introduce-virHostCPUGetMicrocodeVersion.patch b/SOURCES/libvirt-util-introduce-virHostCPUGetMicrocodeVersion.patch
new file mode 100644
index 0000000..e20bc64
--- /dev/null
+++ b/SOURCES/libvirt-util-introduce-virHostCPUGetMicrocodeVersion.patch
@@ -0,0 +1,98 @@
+From 7de4d78e69462ddea11864732e5cd38290a94016 Mon Sep 17 00:00:00 2001
+Message-Id: <7de4d78e69462ddea11864732e5cd38290a94016@dist-git>
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Tue, 12 Dec 2017 16:23:41 +0100
+Subject: [PATCH] util: introduce virHostCPUGetMicrocodeVersion
+
+This new API reads host's CPU microcode version from /proc/cpuinfo.
+
+Unfortunately, there is no other way of reading microcode version which
+would be usable from both system and session daemon.
+
+CVE-2017-5715
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/libvirt_private.syms |  1 +
+ src/util/virhostcpu.c    | 43 +++++++++++++++++++++++++++++++++++++++++++
+ src/util/virhostcpu.h    |  2 ++
+ 3 files changed, 46 insertions(+)
+
+diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
+index 0c972d1861..c50b6c2f77 100644
+--- a/src/libvirt_private.syms
++++ b/src/libvirt_private.syms
+@@ -1739,6 +1739,7 @@ virHostCPUGetCount;
+ virHostCPUGetInfo;
+ virHostCPUGetKVMMaxVCPUs;
+ virHostCPUGetMap;
++virHostCPUGetMicrocodeVersion;
+ virHostCPUGetOnline;
+ virHostCPUGetOnlineBitmap;
+ virHostCPUGetPresentBitmap;
+diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c
+index 67daace890..8135365d08 100644
+--- a/src/util/virhostcpu.c
++++ b/src/util/virhostcpu.c
+@@ -1199,3 +1199,46 @@ virHostCPUGetKVMMaxVCPUs(void)
+     return -1;
+ }
+ #endif /* HAVE_LINUX_KVM_H */
++
++
++#ifdef __linux__
++
++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
+diff --git a/src/util/virhostcpu.h b/src/util/virhostcpu.h
+index e9c22eecc9..7d77392454 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__*/
+-- 
+2.15.1
+
diff --git a/SPECS/libvirt.spec b/SPECS/libvirt.spec
index 722b4c6..128b841 100644
--- a/SPECS/libvirt.spec
+++ b/SPECS/libvirt.spec
@@ -228,7 +228,7 @@
 Summary: Library providing a simple virtualization API
 Name: libvirt
 Version: 3.2.0
-Release: 14%{?dist}.5%{?extra_release}
+Release: 14%{?dist}.7%{?extra_release}
 License: LGPLv2+
 Group: Development/Libraries
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
@@ -491,6 +491,13 @@ Patch248: libvirt-qemu-Fix-CPU-model-broken-by-older-libvirt.patch
 Patch249: libvirt-qemu-block-commit-Don-t-overwrite-error-when-rolling-back-disk-labels.patch
 Patch250: libvirt-qemu-block-commit-Determine-relative-path-of-images-before-initializing.patch
 Patch251: libvirt-qemu-domain-Don-t-call-namespace-setup-for-storage-already-accessed-by-vm.patch
+Patch252: libvirt-util-add-virFileReadHeaderQuiet-wrapper-around-virFileReadHeaderFD.patch
+Patch253: libvirt-util-introduce-virHostCPUGetMicrocodeVersion.patch
+Patch254: libvirt-cpu_x86-Rename-virCPUx86MapInitialize.patch
+Patch255: libvirt-conf-include-x86-microcode-version-in-virsh-capabiltiies.patch
+Patch256: libvirt-qemu-capabilities-force-update-if-the-microcode-version-does-not-match.patch
+Patch257: libvirt-cpu-add-CPU-features-and-model-for-indirect-branch-prediction-protection.patch
+Patch258: libvirt-qemu-Properly-store-microcode-version-in-QEMU-caps-cache.patch
 
 Requires: libvirt-daemon = %{version}-%{release}
 Requires: libvirt-daemon-config-network = %{version}-%{release}
@@ -2339,6 +2346,17 @@ exit 0
 
 
 %changelog
+* Tue Dec 19 2017 Jiri Denemark <jdenemar@redhat.com> - 3.2.0-14.el7_4.7
+- qemu: Properly store microcode version in QEMU caps cache (CVE-2017-5715)
+
+* Thu Dec 14 2017 Jiri Denemark <jdenemar@redhat.com> - 3.2.0-14.el7_4.6
+- util: add virFileReadHeaderQuiet wrapper around virFileReadHeaderFD (CVE-2017-5715)
+- util: introduce virHostCPUGetMicrocodeVersion (CVE-2017-5715)
+- cpu_x86: Rename virCPUx86MapInitialize (CVE-2017-5715)
+- conf: include x86 microcode version in virsh capabiltiies (CVE-2017-5715)
+- qemu: capabilities: force update if the microcode version does not match (CVE-2017-5715)
+- cpu: add CPU features and model for indirect branch prediction protection (CVE-2017-5715)
+
 * Fri Dec  1 2017 Jiri Denemark <jdenemar@redhat.com> - 3.2.0-14.el7_4.5
 - qemu: block commit: Don't overwrite error when rolling back disk labels (rhbz#1516717)
 - qemu: block commit: Determine relative path of images before initializing (rhbz#1516717)