diff --git a/SOURCES/libvirt-cpu_x86-Properly-disable-unknown-CPU-features.patch b/SOURCES/libvirt-cpu_x86-Properly-disable-unknown-CPU-features.patch
new file mode 100644
index 0000000..a54fa77
--- /dev/null
+++ b/SOURCES/libvirt-cpu_x86-Properly-disable-unknown-CPU-features.patch
@@ -0,0 +1,453 @@
+From 73e87a037ccd6d9fd02c3fd0a082f014412c7555 Mon Sep 17 00:00:00 2001
+Message-Id: <73e87a037ccd6d9fd02c3fd0a082f014412c7555@dist-git>
+From: Jiri Denemark <jdenemar@redhat.com>
+Date: Mon, 19 Jun 2017 13:18:52 +0200
+Subject: [PATCH] cpu_x86: Properly disable unknown CPU features
+
+CPU features unknown to a hypervisor will not be present in dataDisabled
+even though the features won't naturally be enabled because.
+Thus any features we asked for which are not in dataEnabled should be
+considered disabled.
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+(cherry picked from commit 83e081b8ab32dd990b4e4ccc7bf8a1a416fc51c2)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1470582
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
+---
+ src/cpu/cpu_x86.c                                  |   9 +-
+ tests/cputest.c                                    |   1 +
+ .../x86_64-cpuid-Core-i7-5600U-arat-disabled.xml   |   5 +
+ .../x86_64-cpuid-Core-i7-5600U-arat-enabled.xml    |   8 +
+ .../x86_64-cpuid-Core-i7-5600U-arat-guest.xml      |  29 +++
+ .../x86_64-cpuid-Core-i7-5600U-arat-host.xml       |  30 +++
+ .../x86_64-cpuid-Core-i7-5600U-arat-json.xml       |  14 ++
+ .../x86_64-cpuid-Core-i7-5600U-arat.json           | 202 +++++++++++++++++++++
+ .../x86_64-cpuid-Core-i7-5600U-arat.xml            |  41 +++++
+ 9 files changed, 335 insertions(+), 4 deletions(-)
+ create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat-disabled.xml
+ create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat-enabled.xml
+ create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat-guest.xml
+ create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat-host.xml
+ create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat-json.xml
+ create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat.json
+ create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat.xml
+
+diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
+index 53359ff9b6..2864454211 100644
+--- a/src/cpu/cpu_x86.c
++++ b/src/cpu/cpu_x86.c
+@@ -2664,12 +2664,11 @@ virCPUx86UpdateLive(virCPUDefPtr cpu,
+         x86DataCopy(&disabled, &dataDisabled->data.x86) < 0)
+         goto cleanup;
+ 
+-    x86DataSubtract(&enabled, &model->data);
+-
+     for (i = 0; i < map->nfeatures; i++) {
+         virCPUx86FeaturePtr feature = map->features[i];
+ 
+-        if (x86DataIsSubset(&enabled, &feature->data)) {
++        if (x86DataIsSubset(&enabled, &feature->data) &&
++            !x86DataIsSubset(&model->data, &feature->data)) {
+             VIR_DEBUG("Feature '%s' enabled by the hypervisor", feature->name);
+             if (cpu->check == VIR_CPU_CHECK_FULL)
+                 virBufferAsprintf(&bufAdded, "%s,", feature->name);
+@@ -2678,7 +2677,9 @@ virCPUx86UpdateLive(virCPUDefPtr cpu,
+                 goto cleanup;
+         }
+ 
+-        if (x86DataIsSubset(&disabled, &feature->data)) {
++        if (x86DataIsSubset(&disabled, &feature->data) ||
++            (x86DataIsSubset(&model->data, &feature->data) &&
++             !x86DataIsSubset(&enabled, &feature->data))) {
+             VIR_DEBUG("Feature '%s' disabled by the hypervisor", feature->name);
+             if (cpu->check == VIR_CPU_CHECK_FULL)
+                 virBufferAsprintf(&bufRemoved, "%s,", feature->name);
+diff --git a/tests/cputest.c b/tests/cputest.c
+index 97b34de9ed..5190a83467 100644
+--- a/tests/cputest.c
++++ b/tests/cputest.c
+@@ -991,6 +991,7 @@ mymain(void)
+     DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i7-4600U", true);
+     DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i7-4510U", true);
+     DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i7-5600U", true);
++    DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i7-5600U-arat", true);
+     DO_TEST_CPUID(VIR_ARCH_X86_64, "Core2-E6850", true);
+     DO_TEST_CPUID(VIR_ARCH_X86_64, "Core2-Q9500", false);
+     DO_TEST_CPUID(VIR_ARCH_X86_64, "FX-8150", false);
+diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat-disabled.xml b/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat-disabled.xml
+new file mode 100644
+index 0000000000..4a0477f788
+--- /dev/null
++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat-disabled.xml
+@@ -0,0 +1,5 @@
++<!-- Features disabled by QEMU -->
++<cpudata arch='x86'>
++  <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x0800c1dc' edx='0xb0600000'/>
++  <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/>
++</cpudata>
+diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat-enabled.xml b/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat-enabled.xml
+new file mode 100644
+index 0000000000..5cffacef59
+--- /dev/null
++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat-enabled.xml
+@@ -0,0 +1,8 @@
++<!-- Features enabled by QEMU -->
++<cpudata arch='x86'>
++  <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0xf7fa3223' edx='0x0f8bfbff'/>
++  <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x001c0fbb' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x0000000d' ecx_in='0x01' eax='0x00000001' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x40000001' ecx_in='0x00' eax='0x010000fa' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000121' edx='0x2c100800'/>
++</cpudata>
+diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat-guest.xml b/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat-guest.xml
+new file mode 100644
+index 0000000000..877895cf15
+--- /dev/null
++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat-guest.xml
+@@ -0,0 +1,29 @@
++<cpu mode='custom' match='exact'>
++  <model fallback='forbid'>Broadwell</model>
++  <vendor>Intel</vendor>
++  <feature policy='require' name='vme'/>
++  <feature policy='require' name='ds'/>
++  <feature policy='require' name='acpi'/>
++  <feature policy='require' name='ss'/>
++  <feature policy='require' name='ht'/>
++  <feature policy='require' name='tm'/>
++  <feature policy='require' name='pbe'/>
++  <feature policy='require' name='dtes64'/>
++  <feature policy='require' name='monitor'/>
++  <feature policy='require' name='ds_cpl'/>
++  <feature policy='require' name='vmx'/>
++  <feature policy='require' name='smx'/>
++  <feature policy='require' name='est'/>
++  <feature policy='require' name='tm2'/>
++  <feature policy='require' name='xtpr'/>
++  <feature policy='require' name='pdcm'/>
++  <feature policy='require' name='osxsave'/>
++  <feature policy='require' name='f16c'/>
++  <feature policy='require' name='rdrand'/>
++  <feature policy='require' name='arat'/>
++  <feature policy='require' name='tsc_adjust'/>
++  <feature policy='require' name='xsaveopt'/>
++  <feature policy='require' name='pdpe1gb'/>
++  <feature policy='require' name='abm'/>
++  <feature policy='require' name='invtsc'/>
++</cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat-host.xml b/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat-host.xml
+new file mode 100644
+index 0000000000..9b24941e0e
+--- /dev/null
++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat-host.xml
+@@ -0,0 +1,30 @@
++<cpu>
++  <arch>x86_64</arch>
++  <model>Broadwell</model>
++  <vendor>Intel</vendor>
++  <feature name='vme'/>
++  <feature name='ds'/>
++  <feature name='acpi'/>
++  <feature name='ss'/>
++  <feature name='ht'/>
++  <feature name='tm'/>
++  <feature name='pbe'/>
++  <feature name='dtes64'/>
++  <feature name='monitor'/>
++  <feature name='ds_cpl'/>
++  <feature name='vmx'/>
++  <feature name='smx'/>
++  <feature name='est'/>
++  <feature name='tm2'/>
++  <feature name='xtpr'/>
++  <feature name='pdcm'/>
++  <feature name='osxsave'/>
++  <feature name='f16c'/>
++  <feature name='rdrand'/>
++  <feature name='arat'/>
++  <feature name='tsc_adjust'/>
++  <feature name='xsaveopt'/>
++  <feature name='pdpe1gb'/>
++  <feature name='abm'/>
++  <feature name='invtsc'/>
++</cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat-json.xml b/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat-json.xml
+new file mode 100644
+index 0000000000..4f253fc08a
+--- /dev/null
++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat-json.xml
+@@ -0,0 +1,14 @@
++<cpu mode='custom' match='exact'>
++  <model fallback='forbid'>Broadwell</model>
++  <vendor>Intel</vendor>
++  <feature policy='require' name='vme'/>
++  <feature policy='require' name='ss'/>
++  <feature policy='require' name='vmx'/>
++  <feature policy='require' name='f16c'/>
++  <feature policy='require' name='rdrand'/>
++  <feature policy='require' name='hypervisor'/>
++  <feature policy='require' name='tsc_adjust'/>
++  <feature policy='require' name='xsaveopt'/>
++  <feature policy='require' name='pdpe1gb'/>
++  <feature policy='require' name='abm'/>
++</cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat.json b/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat.json
+new file mode 100644
+index 0000000000..f2aa7f3185
+--- /dev/null
++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat.json
+@@ -0,0 +1,202 @@
++{
++  "return": {
++    "model": {
++      "name": "base",
++      "props": {
++        "pfthreshold": false,
++        "pku": false,
++        "rtm": true,
++        "tsc_adjust": true,
++        "tsc-deadline": true,
++        "xstore-en": false,
++        "tsc-scale": false,
++        "sse": true,
++        "smap": true,
++        "stepping": 4,
++        "tce": false,
++        "kvm_steal_time": true,
++        "smep": true,
++        "rdpid": false,
++        "xcrypt": false,
++        "sse4_2": true,
++        "monitor": false,
++        "sse4_1": true,
++        "kvm-mmu": false,
++        "flushbyasid": false,
++        "kvm-steal-time": true,
++        "lm": true,
++        "tsc": true,
++        "adx": true,
++        "fxsr": true,
++        "sha-ni": false,
++        "tm": false,
++        "pclmuldq": true,
++        "xgetbv1": false,
++        "xstore": false,
++        "vmcb_clean": false,
++        "vme": true,
++        "vendor": "GenuineIntel",
++        "ffxsr": false,
++        "de": true,
++        "avx512f": false,
++        "pse": true,
++        "ds-cpl": false,
++        "tbm": false,
++        "ia64": false,
++        "phe-en": false,
++        "f16c": true,
++        "ds": false,
++        "mpx": false,
++        "tsc-adjust": true,
++        "aes": true,
++        "avx2": true,
++        "pbe": false,
++        "cx16": true,
++        "ds_cpl": false,
++        "movbe": true,
++        "perfctr-nb": false,
++        "nrip_save": false,
++        "kvm_mmu": false,
++        "ospke": false,
++        "avx512ifma": false,
++        "vmx": true,
++        "sep": true,
++        "xsaveopt": true,
++        "sse4a": false,
++        "avx512dq": false,
++        "i64": true,
++        "avx512-4vnniw": false,
++        "xsave": true,
++        "erms": true,
++        "hle": true,
++        "nodeid_msr": false,
++        "est": false,
++        "svm_lock": false,
++        "xop": false,
++        "model-id": "Intel(R) Core(TM) i7-5600U CPU @ 2.60GHz",
++        "abm": true,
++        "avx512er": false,
++        "sse4.1": true,
++        "sse4.2": true,
++        "pause-filter": false,
++        "lahf-lm": true,
++        "kvm-nopiodelay": true,
++        "cmp_legacy": false,
++        "acpi": false,
++        "fma4": false,
++        "popcnt": true,
++        "mmx": true,
++        "osxsave": false,
++        "pcommit": false,
++        "avx512pf": false,
++        "clwb": false,
++        "dca": false,
++        "pdcm": false,
++        "xcrypt-en": false,
++        "3dnow": false,
++        "invtsc": false,
++        "tm2": false,
++        "hypervisor": true,
++        "kvmclock-stable-bit": true,
++        "fxsr-opt": false,
++        "pcid": true,
++        "sse4-1": true,
++        "sse4-2": true,
++        "avx512-vpopcntdq": false,
++        "avx512-4fmaps": false,
++        "pause_filter": false,
++        "svm-lock": false,
++        "rdrand": true,
++        "nrip-save": false,
++        "avx512vl": false,
++        "x2apic": true,
++        "kvmclock": true,
++        "pge": true,
++        "family": 6,
++        "dtes64": false,
++        "xd": true,
++        "kvm_pv_eoi": true,
++        "ace2": false,
++        "kvm_pv_unhalt": true,
++        "xtpr": false,
++        "perfctr_nb": false,
++        "avx512bw": false,
++        "nx": true,
++        "lwp": false,
++        "msr": true,
++        "ace2-en": false,
++        "decodeassists": false,
++        "perfctr-core": false,
++        "pn": false,
++        "fma": true,
++        "nodeid-msr": false,
++        "kvm_asyncpf": true,
++        "clflush": true,
++        "cx8": true,
++        "mce": true,
++        "avx512cd": false,
++        "cr8legacy": false,
++        "mca": true,
++        "pni": true,
++        "rdseed": true,
++        "apic": true,
++        "fsgsbase": true,
++        "cmp-legacy": false,
++        "kvm-pv-unhalt": true,
++        "rdtscp": true,
++        "mmxext": false,
++        "cid": false,
++        "ssse3": true,
++        "extapic": false,
++        "pse36": true,
++        "mtrr": true,
++        "ibs": false,
++        "la57": false,
++        "avx": true,
++        "syscall": true,
++        "umip": false,
++        "invpcid": true,
++        "avx512vbmi": false,
++        "kvm-asyncpf": true,
++        "vmcb-clean": false,
++        "pmm": false,
++        "cmov": true,
++        "perfctr_core": false,
++        "misalignsse": false,
++        "clflushopt": false,
++        "pat": true,
++        "lbrv": false,
++        "3dnowprefetch": true,
++        "fpu": true,
++        "pae": true,
++        "wdt": false,
++        "tsc_scale": false,
++        "skinit": false,
++        "fxsr_opt": false,
++        "kvm_nopiodelay": true,
++        "pmm-en": false,
++        "phe": false,
++        "3dnowext": false,
++        "osvw": false,
++        "ht": false,
++        "pdpe1gb": true,
++        "kvm-pv-eoi": true,
++        "npt": false,
++        "xsavec": false,
++        "lahf_lm": true,
++        "pclmulqdq": true,
++        "svm": false,
++        "sse3": true,
++        "sse2": true,
++        "ss": true,
++        "topoext": false,
++        "smx": false,
++        "bmi1": true,
++        "bmi2": true,
++        "xsaves": false,
++        "model": 61
++      }
++    }
++  },
++  "id": "model-expansion"
++}
+diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat.xml b/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat.xml
+new file mode 100644
+index 0000000000..ecb4a6e15c
+--- /dev/null
++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat.xml
+@@ -0,0 +1,41 @@
++<!-- Intel(R) Core(TM) i7-5600U CPU @ 2.60GHz -->
++<cpudata arch='x86'>
++  <cpuid eax_in='0x00000000' ecx_in='0x00' eax='0x00000014' ebx='0x756e6547' ecx='0x6c65746e' edx='0x49656e69'/>
++  <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x000306d4' ebx='0x00100800' ecx='0x7ffafbff' edx='0xbfebfbff'/>
++  <cpuid eax_in='0x00000002' ecx_in='0x00' eax='0x76036301' ebx='0x00f0b5ff' ecx='0x00000000' edx='0x00c30000'/>
++  <cpuid eax_in='0x00000003' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x00000004' ecx_in='0x00' eax='0x1c004121' ebx='0x01c0003f' ecx='0x0000003f' edx='0x00000000'/>
++  <cpuid eax_in='0x00000004' ecx_in='0x01' eax='0x1c004122' ebx='0x01c0003f' ecx='0x0000003f' edx='0x00000000'/>
++  <cpuid eax_in='0x00000004' ecx_in='0x02' eax='0x1c004143' ebx='0x01c0003f' ecx='0x000001ff' edx='0x00000000'/>
++  <cpuid eax_in='0x00000004' ecx_in='0x03' eax='0x1c03c163' ebx='0x03c0003f' ecx='0x00000fff' edx='0x00000006'/>
++  <cpuid eax_in='0x00000005' ecx_in='0x00' eax='0x00000040' ebx='0x00000040' ecx='0x00000003' edx='0x11142120'/>
++  <cpuid eax_in='0x00000006' ecx_in='0x00' eax='0x00000077' ebx='0x00000002' ecx='0x00000009' edx='0x00000000'/>
++  <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x021c2fbb' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x00000008' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x00000009' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x0000000a' ecx_in='0x00' eax='0x07300403' ebx='0x00000000' ecx='0x00000000' edx='0x00000603'/>
++  <cpuid eax_in='0x0000000b' ecx_in='0x00' eax='0x00000001' ebx='0x00000002' ecx='0x00000100' edx='0x00000000'/>
++  <cpuid eax_in='0x0000000b' ecx_in='0x01' eax='0x00000004' ebx='0x00000004' ecx='0x00000201' edx='0x00000000'/>
++  <cpuid eax_in='0x0000000c' ecx_in='0x00' eax='0x00000000' ebx='0x00000001' ecx='0x00000001' edx='0x00000000'/>
++  <cpuid eax_in='0x0000000d' ecx_in='0x00' eax='0x00000007' ebx='0x00000340' ecx='0x00000340' edx='0x00000000'/>
++  <cpuid eax_in='0x0000000d' ecx_in='0x01' eax='0x00000001' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x0000000d' ecx_in='0x02' eax='0x00000100' ebx='0x00000240' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x0000000e' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x0000000f' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x00000010' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x00000011' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x00000012' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x00000013' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x00000014' ecx_in='0x00' eax='0x00000000' ebx='0x00000001' ecx='0x00000001' edx='0x00000000'/>
++  <cpuid eax_in='0x80000000' ecx_in='0x00' eax='0x80000008' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000121' edx='0x2c100800'/>
++  <cpuid eax_in='0x80000002' ecx_in='0x00' eax='0x65746e49' ebx='0x2952286c' ecx='0x726f4320' edx='0x4d542865'/>
++  <cpuid eax_in='0x80000003' ecx_in='0x00' eax='0x37692029' ebx='0x3036352d' ecx='0x43205530' edx='0x40205550'/>
++  <cpuid eax_in='0x80000004' ecx_in='0x00' eax='0x362e3220' ebx='0x7a484730' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x80000005' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x80000006' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x01006040' edx='0x00000000'/>
++  <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/>
++  <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x00003027' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x80860000' ecx_in='0x00' eax='0x00000000' ebx='0x00000001' ecx='0x00000001' edx='0x00000000'/>
++  <cpuid eax_in='0xc0000000' ecx_in='0x00' eax='0x00000000' ebx='0x00000001' ecx='0x00000001' edx='0x00000000'/>
++</cpudata>
+-- 
+2.13.2
+
diff --git a/SOURCES/libvirt-qemu-Add-qemuProcessFetchGuestCPU.patch b/SOURCES/libvirt-qemu-Add-qemuProcessFetchGuestCPU.patch
new file mode 100644
index 0000000..3890b04
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Add-qemuProcessFetchGuestCPU.patch
@@ -0,0 +1,102 @@
+From 57a9f46878f57d1602a030cfd8484c8566201c40 Mon Sep 17 00:00:00 2001
+Message-Id: <57a9f46878f57d1602a030cfd8484c8566201c40@dist-git>
+From: Jiri Denemark <jdenemar@redhat.com>
+Date: Tue, 11 Jul 2017 13:18:45 +0200
+Subject: [PATCH] qemu: Add qemuProcessFetchGuestCPU
+
+Separated from qemuProcessUpdateLiveGuestCPU. Its purpose is to fetch
+guest CPU data from a running QEMU process. The data can later be used
+to verify and update the active guest CPU definition.
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
+(cherry picked from commit 40d246a22b46f1691d09cbce5904c79d712d8c16)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1470582
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
+---
+ src/qemu/qemu_process.c | 58 +++++++++++++++++++++++++++++++++++++------------
+ 1 file changed, 44 insertions(+), 14 deletions(-)
+
+diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
+index 4d7c8d8e40..d3fa8ef41e 100644
+--- a/src/qemu/qemu_process.c
++++ b/src/qemu/qemu_process.c
+@@ -3905,6 +3905,47 @@ qemuProcessVerifyCPUFeatures(virDomainDefPtr def,
+ 
+ 
+ static int
++qemuProcessFetchGuestCPU(virQEMUDriverPtr driver,
++                         virDomainObjPtr vm,
++                         qemuDomainAsyncJob asyncJob,
++                         virCPUDataPtr *enabled,
++                         virCPUDataPtr *disabled)
++{
++    qemuDomainObjPrivatePtr priv = vm->privateData;
++    virCPUDataPtr dataEnabled = NULL;
++    virCPUDataPtr dataDisabled = NULL;
++    int rc;
++
++    *enabled = NULL;
++    *disabled = NULL;
++
++    if (!ARCH_IS_X86(vm->def->os.arch))
++        return 0;
++
++    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
++        goto error;
++
++    rc = qemuMonitorGetGuestCPU(priv->mon, vm->def->os.arch,
++                                &dataEnabled, &dataDisabled);
++
++    if (qemuDomainObjExitMonitor(driver, vm) < 0)
++        goto error;
++
++    if (rc == -1)
++        goto error;
++
++    *enabled = dataEnabled;
++    *disabled = dataDisabled;
++    return 0;
++
++ error:
++    virCPUDataFree(dataEnabled);
++    virCPUDataFree(dataDisabled);
++    return -1;
++}
++
++
++static int
+ qemuProcessUpdateLiveGuestCPU(virQEMUDriverPtr driver,
+                               virDomainObjPtr vm,
+                               qemuDomainAsyncJob asyncJob)
+@@ -3917,21 +3958,10 @@ qemuProcessUpdateLiveGuestCPU(virQEMUDriverPtr driver,
+     int ret = -1;
+     virCPUDefPtr orig = NULL;
+ 
+-    if (ARCH_IS_X86(def->os.arch)) {
+-        if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+-            goto cleanup;
+-
+-        rc = qemuMonitorGetGuestCPU(priv->mon, def->os.arch, &cpu, &disabled);
+-
+-        if (qemuDomainObjExitMonitor(driver, vm) < 0)
+-            goto cleanup;
+-
+-        if (rc < 0) {
+-            if (rc == -2)
+-                ret = 0;
+-            goto cleanup;
+-        }
++    if (qemuProcessFetchGuestCPU(driver, vm, asyncJob, &cpu, &disabled) < 0)
++        goto cleanup;
+ 
++    if (cpu) {
+         if (qemuProcessVerifyKVMFeatures(def, cpu) < 0 ||
+             qemuProcessVerifyHypervFeatures(def, cpu) < 0)
+             goto cleanup;
+-- 
+2.13.2
+
diff --git a/SOURCES/libvirt-qemu-Add-qemuProcessUpdateLiveGuestCPU.patch b/SOURCES/libvirt-qemu-Add-qemuProcessUpdateLiveGuestCPU.patch
new file mode 100644
index 0000000..33bd482
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Add-qemuProcessUpdateLiveGuestCPU.patch
@@ -0,0 +1,127 @@
+From e5840b68e6376a514c6c5de1897ac87dc57e7a58 Mon Sep 17 00:00:00 2001
+Message-Id: <e5840b68e6376a514c6c5de1897ac87dc57e7a58@dist-git>
+From: Jiri Denemark <jdenemar@redhat.com>
+Date: Tue, 11 Jul 2017 13:51:17 +0200
+Subject: [PATCH] qemu: Add qemuProcessUpdateLiveGuestCPU
+
+Separated from qemuProcessUpdateAndVerifyCPU to handle updating of an
+active guest CPU definition according to live data from QEMU.
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
+(cherry picked from commit eef9f83b691e0713e4fc480b497b85517aba6ca4)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1470582
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
+---
+ src/qemu/qemu_process.c | 72 ++++++++++++++++++++++++++++++-------------------
+ 1 file changed, 44 insertions(+), 28 deletions(-)
+
+diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
+index 1e7724e784..9df463094e 100644
+--- a/src/qemu/qemu_process.c
++++ b/src/qemu/qemu_process.c
+@@ -3971,17 +3971,55 @@ qemuProcessVerifyCPU(virDomainObjPtr vm,
+ 
+ 
+ static int
++qemuProcessUpdateLiveGuestCPU(virDomainObjPtr vm,
++                              virCPUDataPtr enabled,
++                              virCPUDataPtr disabled)
++{
++    virDomainDefPtr def = vm->def;
++    qemuDomainObjPrivatePtr priv = vm->privateData;
++    virCPUDefPtr orig = NULL;
++    int rc;
++    int ret = -1;
++
++    if (!enabled)
++        return 0;
++
++    if (!def->cpu ||
++        (def->cpu->mode == VIR_CPU_MODE_CUSTOM &&
++         !def->cpu->model))
++        return 0;
++
++    if (!(orig = virCPUDefCopy(def->cpu)))
++        goto cleanup;
++
++    if ((rc = virCPUUpdateLive(def->os.arch, def->cpu, enabled, disabled)) < 0) {
++        goto cleanup;
++    } else if (rc == 0) {
++        /* Store the original CPU in priv if QEMU changed it and we didn't
++         * get the original CPU via migration, restore, or snapshot revert.
++         */
++        if (!priv->origCPU && !virCPUDefIsEqual(def->cpu, orig, false))
++            VIR_STEAL_PTR(priv->origCPU, orig);
++
++        def->cpu->check = VIR_CPU_CHECK_FULL;
++    }
++
++    ret = 0;
++
++ cleanup:
++    virCPUDefFree(orig);
++    return ret;
++}
++
++
++static int
+ qemuProcessUpdateAndVerifyCPU(virQEMUDriverPtr driver,
+                               virDomainObjPtr vm,
+                               qemuDomainAsyncJob asyncJob)
+ {
+-    virDomainDefPtr def = vm->def;
+     virCPUDataPtr cpu = NULL;
+     virCPUDataPtr disabled = NULL;
+-    qemuDomainObjPrivatePtr priv = vm->privateData;
+-    int rc;
+     int ret = -1;
+-    virCPUDefPtr orig = NULL;
+ 
+     if (qemuProcessFetchGuestCPU(driver, vm, asyncJob, &cpu, &disabled) < 0)
+         goto cleanup;
+@@ -3989,36 +4027,14 @@ qemuProcessUpdateAndVerifyCPU(virQEMUDriverPtr driver,
+     if (qemuProcessVerifyCPU(vm, cpu) < 0)
+         goto cleanup;
+ 
+-    if (cpu) {
+-        if (!def->cpu ||
+-            (def->cpu->mode == VIR_CPU_MODE_CUSTOM &&
+-             !def->cpu->model)) {
+-            ret = 0;
+-            goto cleanup;
+-        }
+-
+-        if (!(orig = virCPUDefCopy(def->cpu)))
+-            goto cleanup;
+-
+-        if ((rc = virCPUUpdateLive(def->os.arch, def->cpu, cpu, disabled)) < 0) {
+-            goto cleanup;
+-        } else if (rc == 0) {
+-            /* Store the original CPU in priv if QEMU changed it and we didn't
+-             * get the original CPU via migration, restore, or snapshot revert.
+-             */
+-            if (!priv->origCPU && !virCPUDefIsEqual(def->cpu, orig, false))
+-                VIR_STEAL_PTR(priv->origCPU, orig);
+-
+-            def->cpu->check = VIR_CPU_CHECK_FULL;
+-        }
+-    }
++    if (qemuProcessUpdateLiveGuestCPU(vm, cpu, disabled) < 0)
++        goto cleanup;
+ 
+     ret = 0;
+ 
+  cleanup:
+     virCPUDataFree(cpu);
+     virCPUDataFree(disabled);
+-    virCPUDefFree(orig);
+     return ret;
+ }
+ 
+-- 
+2.13.2
+
diff --git a/SOURCES/libvirt-qemu-Add-qemuProcessVerifyCPU.patch b/SOURCES/libvirt-qemu-Add-qemuProcessVerifyCPU.patch
new file mode 100644
index 0000000..c557e14
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Add-qemuProcessVerifyCPU.patch
@@ -0,0 +1,85 @@
+From 9d41cae9942d2909be00261b3ae2a2e1ec717808 Mon Sep 17 00:00:00 2001
+Message-Id: <9d41cae9942d2909be00261b3ae2a2e1ec717808@dist-git>
+From: Jiri Denemark <jdenemar@redhat.com>
+Date: Tue, 11 Jul 2017 13:26:12 +0200
+Subject: [PATCH] qemu: Add qemuProcessVerifyCPU
+
+Separated from qemuProcessUpdateLiveGuestCPU. The function makes sure
+a guest CPU provides all features required by a domain definition.
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
+(cherry picked from commit 5cac2fe108f957b2629a29bea1747fdb3c8d7aa3)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1470582
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
+---
+ src/qemu/qemu_process.c | 35 ++++++++++++++++++++++++++++-------
+ 1 file changed, 28 insertions(+), 7 deletions(-)
+
+diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
+index d3fa8ef41e..3f7a9f4c02 100644
+--- a/src/qemu/qemu_process.c
++++ b/src/qemu/qemu_process.c
+@@ -3946,6 +3946,31 @@ qemuProcessFetchGuestCPU(virQEMUDriverPtr driver,
+ 
+ 
+ static int
++qemuProcessVerifyCPU(virDomainObjPtr vm,
++                     virCPUDataPtr cpu)
++{
++    virDomainDefPtr def = vm->def;
++
++    if (!cpu)
++        return 0;
++
++    if (qemuProcessVerifyKVMFeatures(def, cpu) < 0 ||
++        qemuProcessVerifyHypervFeatures(def, cpu) < 0)
++        return -1;
++
++    if (!def->cpu ||
++        (def->cpu->mode == VIR_CPU_MODE_CUSTOM &&
++         !def->cpu->model))
++        return 0;
++
++    if (qemuProcessVerifyCPUFeatures(def, cpu) < 0)
++        return -1;
++
++    return 0;
++}
++
++
++static int
+ qemuProcessUpdateLiveGuestCPU(virQEMUDriverPtr driver,
+                               virDomainObjPtr vm,
+                               qemuDomainAsyncJob asyncJob)
+@@ -3961,11 +3986,10 @@ qemuProcessUpdateLiveGuestCPU(virQEMUDriverPtr driver,
+     if (qemuProcessFetchGuestCPU(driver, vm, asyncJob, &cpu, &disabled) < 0)
+         goto cleanup;
+ 
+-    if (cpu) {
+-        if (qemuProcessVerifyKVMFeatures(def, cpu) < 0 ||
+-            qemuProcessVerifyHypervFeatures(def, cpu) < 0)
+-            goto cleanup;
++    if (qemuProcessVerifyCPU(vm, cpu) < 0)
++        goto cleanup;
+ 
++    if (cpu) {
+         if (!def->cpu ||
+             (def->cpu->mode == VIR_CPU_MODE_CUSTOM &&
+              !def->cpu->model)) {
+@@ -3973,9 +3997,6 @@ qemuProcessUpdateLiveGuestCPU(virQEMUDriverPtr driver,
+             goto cleanup;
+         }
+ 
+-        if (qemuProcessVerifyCPUFeatures(def, cpu) < 0)
+-            goto cleanup;
+-
+         if (!(orig = virCPUDefCopy(def->cpu)))
+             goto cleanup;
+ 
+-- 
+2.13.2
+
diff --git a/SOURCES/libvirt-qemu-Don-t-update-CPU-when-checking-ABI-stability.patch b/SOURCES/libvirt-qemu-Don-t-update-CPU-when-checking-ABI-stability.patch
new file mode 100644
index 0000000..85a5901
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Don-t-update-CPU-when-checking-ABI-stability.patch
@@ -0,0 +1,61 @@
+From d260867d18aa20c4d79f4319b82453120d209eae Mon Sep 17 00:00:00 2001
+Message-Id: <d260867d18aa20c4d79f4319b82453120d209eae@dist-git>
+From: Jiri Denemark <jdenemar@redhat.com>
+Date: Tue, 27 Jun 2017 15:06:10 +0200
+Subject: [PATCH] qemu: Don't update CPU when checking ABI stability
+
+When checking ABI stability between two domain definitions, we first
+make migratable copies of them. However, we also asked for the guest CPU
+to be updated, even though the updated CPU is supposed to be already
+included in the original definitions. Moreover, if we do this on the
+destination host during migration, we're potentially updating the
+definition with according to an incompatible host CPU.
+
+While updating the CPU when checking ABI stability doesn't make any
+sense, it actually just worked because updating the CPU doesn't do
+anything for custom CPUs (only host-model CPUs are affected) and we
+updated both definitions in the same way.
+
+Less then a year ago commit v2.3.0-rc1~42 stopped updating the CPU in
+the definition we got internally and only the user supplied definition
+was updated. However, the same commit started updating host-model CPUs
+to custom CPUs which are not affected by the request to update the CPU.
+So it still seemed to work right, unless a user upgraded libvirt 2.2.0
+to a newer version while there were some domains with host-model CPUs
+running on the host. Such domains couldn't be migrated with a user
+supplied XML since libvirt would complain:
+
+    Target CPU mode custom does not match source host-model
+
+The fix is pretty straightforward, we just need to stop updating the CPU
+when checking ABI stability.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1463957
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
+(cherry picked from commit ee68bb391efb684341edb6286a1278631167f08c)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1470582
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
+---
+ src/qemu/qemu_domain.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index 1528c6a137..6ccc9f6f5b 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -5910,7 +5910,6 @@ qemuDomainMigratableDefCheckABIStability(virQEMUDriverPtr driver,
+ 
+ 
+ #define COPY_FLAGS (VIR_DOMAIN_XML_SECURE | \
+-                    VIR_DOMAIN_XML_UPDATE_CPU | \
+                     VIR_DOMAIN_XML_MIGRATABLE)
+ 
+ bool
+-- 
+2.13.2
+
diff --git a/SOURCES/libvirt-qemu-Export-virQEMUCapsGuestIsNative.patch b/SOURCES/libvirt-qemu-Export-virQEMUCapsGuestIsNative.patch
new file mode 100644
index 0000000..75fc214
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Export-virQEMUCapsGuestIsNative.patch
@@ -0,0 +1,47 @@
+From b06befbc433e1b6dc1a8ee5ee0814a20a2288685 Mon Sep 17 00:00:00 2001
+Message-Id: <b06befbc433e1b6dc1a8ee5ee0814a20a2288685@dist-git>
+From: Jiri Denemark <jdenemar@redhat.com>
+Date: Tue, 11 Jul 2017 15:15:01 +0200
+Subject: [PATCH] qemu: Export virQEMUCapsGuestIsNative
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
+(cherry picked from commit ee4180bef124cbc08a702689dda6fd95b21b1387)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1470582
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
+---
+ src/qemu/qemu_capabilities.c | 2 +-
+ src/qemu/qemu_capabilities.h | 3 +++
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
+index eea57e4c9c..f22c11941c 100644
+--- a/src/qemu/qemu_capabilities.c
++++ b/src/qemu/qemu_capabilities.c
+@@ -491,7 +491,7 @@ static const char *virQEMUCapsArchToString(virArch arch)
+ 
+ /* Checks whether a domain with @guest arch can run natively on @host.
+  */
+-static bool
++bool
+ virQEMUCapsGuestIsNative(virArch host,
+                          virArch guest)
+ {
+diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
+index bbc6f6812f..c28c80d40a 100644
+--- a/src/qemu/qemu_capabilities.h
++++ b/src/qemu/qemu_capabilities.h
+@@ -569,4 +569,7 @@ int virQEMUCapsFillDomainCaps(virCapsPtr caps,
+                               virFirmwarePtr *firmwares,
+                               size_t nfirmwares);
+ 
++bool virQEMUCapsGuestIsNative(virArch host,
++                              virArch guest);
++
+ #endif /* __QEMU_CAPABILITIES_H__*/
+-- 
+2.13.2
+
diff --git a/SOURCES/libvirt-qemu-Fix-qemuDomainGetBlockInfo-allocation-value-setting.patch b/SOURCES/libvirt-qemu-Fix-qemuDomainGetBlockInfo-allocation-value-setting.patch
new file mode 100644
index 0000000..eb82b29
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Fix-qemuDomainGetBlockInfo-allocation-value-setting.patch
@@ -0,0 +1,46 @@
+From 0220b2fed9ab4b07f32e8ebe4ab048d64a27e948 Mon Sep 17 00:00:00 2001
+Message-Id: <0220b2fed9ab4b07f32e8ebe4ab048d64a27e948@dist-git>
+From: John Ferlan <jferlan@redhat.com>
+Date: Wed, 12 Jul 2017 16:31:10 +0200
+Subject: [PATCH] qemu: Fix qemuDomainGetBlockInfo allocation value setting
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1467826
+
+Commit id 'b9b1aa639' was supposed to add logic to set the allocation
+for sparse files when wr_highest_offset was zero; however, an unconditional
+setting was done just prior. For block devices, this means allocation is
+always returning 0 since 'actual-size' will be zero.
+
+Remove the unconditional setting and add the note about it being possible
+to still be zero for block devices. As soon as the guest starts writing to
+the volume, the allocation value will then be obtainable from qemu via
+the wr_highest_offset.
+
+(cherry picked from commit fde654be5307a570b7b0f31537e18e70a274cd50)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1470127 [7.4.z - 0day]
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/qemu/qemu_driver.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index a2fb41b91a..b6d72303ca 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -11715,10 +11715,9 @@ qemuDomainGetBlockInfo(virDomainPtr dom,
+      * Additionally, if qemu hasn't written to the file yet, then set the
+      * allocation to whatever qemu returned for physical (e.g. the "actual-
+      * size" from the json query) as that will match the expected allocation
+-     * value for this API. */
++     * value for this API. NB: May still be 0 for block. */
+     if (entry->physical == 0 || info->allocation == 0 ||
+         info->allocation == entry->physical) {
+-        info->allocation = entry->physical;
+         if (info->allocation == 0)
+             info->allocation = entry->physical;
+ 
+-- 
+2.13.3
+
diff --git a/SOURCES/libvirt-qemu-Move-qemuProcessReconnect-to-the-end-of-qemu_process.c.patch b/SOURCES/libvirt-qemu-Move-qemuProcessReconnect-to-the-end-of-qemu_process.c.patch
new file mode 100644
index 0000000..facaf96
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Move-qemuProcessReconnect-to-the-end-of-qemu_process.c.patch
@@ -0,0 +1,687 @@
+From 6f532f2e3615bb573a186cfcfddf8fcc1eec7efd Mon Sep 17 00:00:00 2001
+Message-Id: <6f532f2e3615bb573a186cfcfddf8fcc1eec7efd@dist-git>
+From: Jiri Denemark <jdenemar@redhat.com>
+Date: Tue, 11 Jul 2017 15:53:58 +0200
+Subject: [PATCH] qemu: Move qemuProcessReconnect to the end of qemu_process.c
+
+qemuProcessReconnect will need to call additional functions which were
+originally defined further in qemu_process.c.
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
+(cherry picked from commit aad362f93b4451e2f3c98923e5e44c4fe6d26d75)
+
+Conflicts:
+	src/qemu/qemu_process.c
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1470582
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
+---
+ src/qemu/qemu_process.c | 645 ++++++++++++++++++++++++------------------------
+ 1 file changed, 323 insertions(+), 322 deletions(-)
+
+diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
+index 9df463094e..e6f56dc484 100644
+--- a/src/qemu/qemu_process.c
++++ b/src/qemu/qemu_process.c
+@@ -3331,328 +3331,6 @@ qemuProcessBuildDestroyHugepagesPath(virQEMUDriverPtr driver,
+ }
+ 
+ 
+-struct qemuProcessReconnectData {
+-    virConnectPtr conn;
+-    virQEMUDriverPtr driver;
+-    virDomainObjPtr obj;
+-};
+-/*
+- * Open an existing VM's monitor, re-detect VCPU threads
+- * and re-reserve the security labels in use
+- *
+- * We own the virConnectPtr we are passed here - whoever started
+- * this thread function has increased the reference counter to it
+- * so that we now have to close it.
+- *
+- * This function also inherits a locked and ref'd domain object.
+- *
+- * This function needs to:
+- * 1. Enter job
+- * 1. just before monitor reconnect do lightweight MonitorEnter
+- *    (increase VM refcount and unlock VM)
+- * 2. reconnect to monitor
+- * 3. do lightweight MonitorExit (lock VM)
+- * 4. continue reconnect process
+- * 5. EndJob
+- *
+- * We can't do normal MonitorEnter & MonitorExit because these two lock the
+- * monitor lock, which does not exists in this early phase.
+- */
+-static void
+-qemuProcessReconnect(void *opaque)
+-{
+-    struct qemuProcessReconnectData *data = opaque;
+-    virQEMUDriverPtr driver = data->driver;
+-    virDomainObjPtr obj = data->obj;
+-    qemuDomainObjPrivatePtr priv;
+-    virConnectPtr conn = data->conn;
+-    struct qemuDomainJobObj oldjob;
+-    int state;
+-    int reason;
+-    virQEMUDriverConfigPtr cfg;
+-    size_t i;
+-    unsigned int stopFlags = 0;
+-    bool jobStarted = false;
+-    virCapsPtr caps = NULL;
+-
+-    VIR_FREE(data);
+-
+-    qemuDomainObjRestoreJob(obj, &oldjob);
+-    if (oldjob.asyncJob == QEMU_ASYNC_JOB_MIGRATION_IN)
+-        stopFlags |= VIR_QEMU_PROCESS_STOP_MIGRATED;
+-
+-    cfg = virQEMUDriverGetConfig(driver);
+-    priv = obj->privateData;
+-
+-    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+-        goto error;
+-
+-    if (qemuDomainObjBeginJob(driver, obj, QEMU_JOB_MODIFY) < 0)
+-        goto error;
+-    jobStarted = true;
+-
+-    /* XXX If we ever gonna change pid file pattern, come up with
+-     * some intelligence here to deal with old paths. */
+-    if (!(priv->pidfile = virPidFileBuildPath(cfg->stateDir, obj->def->name)))
+-        goto error;
+-
+-    /* Restore the masterKey */
+-    if (qemuDomainMasterKeyReadFile(priv) < 0)
+-        goto error;
+-
+-    virNWFilterReadLockFilterUpdates();
+-
+-    VIR_DEBUG("Reconnect monitor to %p '%s'", obj, obj->def->name);
+-
+-    /* XXX check PID liveliness & EXE path */
+-    if (qemuConnectMonitor(driver, obj, QEMU_ASYNC_JOB_NONE, NULL) < 0)
+-        goto error;
+-
+-    if (qemuHostdevUpdateActiveDomainDevices(driver, obj->def) < 0)
+-        goto error;
+-
+-    if (qemuConnectCgroup(driver, obj) < 0)
+-        goto error;
+-
+-    if (qemuDomainPerfRestart(obj) < 0)
+-        goto error;
+-
+-    /* XXX: Need to change as long as lock is introduced for
+-     * qemu_driver->sharedDevices.
+-     */
+-    for (i = 0; i < obj->def->ndisks; i++) {
+-        virDomainDeviceDef dev;
+-
+-        if (virStorageTranslateDiskSourcePool(conn, obj->def->disks[i]) < 0)
+-            goto error;
+-
+-        /* XXX we should be able to restore all data from XML in the future.
+-         * This should be the only place that calls qemuDomainDetermineDiskChain
+-         * with @report_broken == false to guarantee best-effort domain
+-         * reconnect */
+-        if (qemuDomainDetermineDiskChain(driver, obj, obj->def->disks[i],
+-                                         true, false) < 0)
+-            goto error;
+-
+-        dev.type = VIR_DOMAIN_DEVICE_DISK;
+-        dev.data.disk = obj->def->disks[i];
+-        if (qemuAddSharedDevice(driver, &dev, obj->def->name) < 0)
+-            goto error;
+-    }
+-
+-    if (qemuProcessUpdateState(driver, obj) < 0)
+-        goto error;
+-
+-    state = virDomainObjGetState(obj, &reason);
+-    if (state == VIR_DOMAIN_SHUTOFF ||
+-        (state == VIR_DOMAIN_PAUSED &&
+-         reason == VIR_DOMAIN_PAUSED_STARTING_UP)) {
+-        VIR_DEBUG("Domain '%s' wasn't fully started yet, killing it",
+-                  obj->def->name);
+-        goto error;
+-    }
+-
+-    /* If upgrading from old libvirtd we won't have found any
+-     * caps in the domain status, so re-query them
+-     */
+-    if (!priv->qemuCaps &&
+-        !(priv->qemuCaps = virQEMUCapsCacheLookupCopy(caps,
+-                                                      driver->qemuCapsCache,
+-                                                      obj->def->emulator,
+-                                                      obj->def->os.machine)))
+-        goto error;
+-
+-    /* In case the domain shutdown while we were not running,
+-     * we need to finish the shutdown process. And we need to do it after
+-     * we have virQEMUCaps filled in.
+-     */
+-    if (state == VIR_DOMAIN_SHUTDOWN ||
+-        (state == VIR_DOMAIN_PAUSED &&
+-         reason == VIR_DOMAIN_PAUSED_SHUTTING_DOWN)) {
+-        VIR_DEBUG("Finishing shutdown sequence for domain %s",
+-                  obj->def->name);
+-        qemuProcessShutdownOrReboot(driver, obj);
+-        goto cleanup;
+-    }
+-
+-    if (qemuProcessBuildDestroyHugepagesPath(driver, obj, true) < 0)
+-        goto error;
+-
+-    if ((qemuDomainAssignAddresses(obj->def, priv->qemuCaps,
+-                                   driver, obj, false)) < 0) {
+-        goto error;
+-    }
+-
+-    /* if domain requests security driver we haven't loaded, report error, but
+-     * do not kill the domain
+-     */
+-    ignore_value(qemuSecurityCheckAllLabel(driver->securityManager,
+-                                           obj->def));
+-
+-    if (qemuDomainRefreshVcpuInfo(driver, obj, QEMU_ASYNC_JOB_NONE, true) < 0)
+-        goto error;
+-
+-    qemuDomainVcpuPersistOrder(obj->def);
+-
+-    if (qemuSecurityReserveLabel(driver->securityManager, obj->def, obj->pid) < 0)
+-        goto error;
+-
+-    qemuProcessNotifyNets(obj->def);
+-
+-    if (qemuProcessFiltersInstantiate(obj->def))
+-        goto error;
+-
+-    if (qemuProcessRefreshDisks(driver, obj, QEMU_ASYNC_JOB_NONE) < 0)
+-        goto error;
+-
+-    if (qemuBlockNodeNamesDetect(driver, obj) < 0)
+-        goto error;
+-
+-    if (qemuRefreshVirtioChannelState(driver, obj, QEMU_ASYNC_JOB_NONE) < 0)
+-        goto error;
+-
+-    /* If querying of guest's RTC failed, report error, but do not kill the domain. */
+-    qemuRefreshRTC(driver, obj);
+-
+-    if (qemuProcessRefreshBalloonState(driver, obj, QEMU_ASYNC_JOB_NONE) < 0)
+-        goto error;
+-
+-    if (qemuProcessRecoverJob(driver, obj, conn, &oldjob, &stopFlags) < 0)
+-        goto error;
+-
+-    if (qemuProcessUpdateDevices(driver, obj) < 0)
+-        goto error;
+-
+-    qemuProcessReconnectCheckMemAliasOrderMismatch(obj);
+-
+-    if (qemuConnectAgent(driver, obj) < 0)
+-        goto error;
+-
+-    /* update domain state XML with possibly updated state in virDomainObj */
+-    if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, obj, driver->caps) < 0)
+-        goto error;
+-
+-    /* Run an hook to allow admins to do some magic */
+-    if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
+-        char *xml = qemuDomainDefFormatXML(driver, obj->def, 0);
+-        int hookret;
+-
+-        hookret = virHookCall(VIR_HOOK_DRIVER_QEMU, obj->def->name,
+-                              VIR_HOOK_QEMU_OP_RECONNECT, VIR_HOOK_SUBOP_BEGIN,
+-                              NULL, xml, NULL);
+-        VIR_FREE(xml);
+-
+-        /*
+-         * If the script raised an error abort the launch
+-         */
+-        if (hookret < 0)
+-            goto error;
+-    }
+-
+-    if (virAtomicIntInc(&driver->nactive) == 1 && driver->inhibitCallback)
+-        driver->inhibitCallback(true, driver->inhibitOpaque);
+-
+- cleanup:
+-    if (jobStarted)
+-        qemuDomainObjEndJob(driver, obj);
+-    if (!virDomainObjIsActive(obj))
+-        qemuDomainRemoveInactive(driver, obj);
+-    virDomainObjEndAPI(&obj);
+-    virObjectUnref(conn);
+-    virObjectUnref(cfg);
+-    virObjectUnref(caps);
+-    virNWFilterUnlockFilterUpdates();
+-    return;
+-
+- error:
+-    if (virDomainObjIsActive(obj)) {
+-        /* We can't get the monitor back, so must kill the VM
+-         * to remove danger of it ending up running twice if
+-         * user tries to start it again later
+-         */
+-        if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NO_SHUTDOWN)) {
+-            /* If we couldn't get the monitor and qemu supports
+-             * no-shutdown, we can safely say that the domain
+-             * crashed ... */
+-            state = VIR_DOMAIN_SHUTOFF_CRASHED;
+-        } else {
+-            /* ... but if it doesn't we can't say what the state
+-             * really is and FAILED means "failed to start" */
+-            state = VIR_DOMAIN_SHUTOFF_UNKNOWN;
+-        }
+-        /* If BeginJob failed, we jumped here without a job, let's hope another
+-         * thread didn't have a chance to start playing with the domain yet
+-         * (it's all we can do anyway).
+-         */
+-        qemuProcessStop(driver, obj, state, QEMU_ASYNC_JOB_NONE, stopFlags);
+-    }
+-    goto cleanup;
+-}
+-
+-static int
+-qemuProcessReconnectHelper(virDomainObjPtr obj,
+-                           void *opaque)
+-{
+-    virThread thread;
+-    struct qemuProcessReconnectData *src = opaque;
+-    struct qemuProcessReconnectData *data;
+-
+-    /* If the VM was inactive, we don't need to reconnect */
+-    if (!obj->pid)
+-        return 0;
+-
+-    if (VIR_ALLOC(data) < 0)
+-        return -1;
+-
+-    memcpy(data, src, sizeof(*data));
+-    data->obj = obj;
+-
+-    /* this lock and reference will be eventually transferred to the thread
+-     * that handles the reconnect */
+-    virObjectLock(obj);
+-    virObjectRef(obj);
+-
+-    /* Since we close the connection later on, we have to make sure that the
+-     * threads we start see a valid connection throughout their lifetime. We
+-     * simply increase the reference counter here.
+-     */
+-    virObjectRef(data->conn);
+-
+-    if (virThreadCreate(&thread, false, qemuProcessReconnect, data) < 0) {
+-        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+-                       _("Could not create thread. QEMU initialization "
+-                         "might be incomplete"));
+-        /* We can't spawn a thread and thus connect to monitor. Kill qemu.
+-         * It's safe to call qemuProcessStop without a job here since there
+-         * is no thread that could be doing anything else with the same domain
+-         * object.
+-         */
+-        qemuProcessStop(src->driver, obj, VIR_DOMAIN_SHUTOFF_FAILED,
+-                        QEMU_ASYNC_JOB_NONE, 0);
+-        qemuDomainRemoveInactive(src->driver, obj);
+-
+-        virDomainObjEndAPI(&obj);
+-        virObjectUnref(data->conn);
+-        VIR_FREE(data);
+-        return -1;
+-    }
+-
+-    return 0;
+-}
+-
+-/**
+- * qemuProcessReconnectAll
+- *
+- * Try to re-open the resources for live VMs that we care
+- * about.
+- */
+-void
+-qemuProcessReconnectAll(virConnectPtr conn, virQEMUDriverPtr driver)
+-{
+-    struct qemuProcessReconnectData data = {.conn = conn, .driver = driver};
+-    virDomainObjListForEach(driver->domains, qemuProcessReconnectHelper, &data);
+-}
+-
+ static int
+ qemuProcessVNCAllocatePorts(virQEMUDriverPtr driver,
+                             virDomainGraphicsDefPtr graphics,
+@@ -6958,3 +6636,326 @@ qemuProcessRefreshDisks(virQEMUDriverPtr driver,
+     virHashFree(table);
+     return ret;
+ }
++
++
++struct qemuProcessReconnectData {
++    virConnectPtr conn;
++    virQEMUDriverPtr driver;
++    virDomainObjPtr obj;
++};
++/*
++ * Open an existing VM's monitor, re-detect VCPU threads
++ * and re-reserve the security labels in use
++ *
++ * We own the virConnectPtr we are passed here - whoever started
++ * this thread function has increased the reference counter to it
++ * so that we now have to close it.
++ *
++ * This function also inherits a locked and ref'd domain object.
++ *
++ * This function needs to:
++ * 1. Enter job
++ * 1. just before monitor reconnect do lightweight MonitorEnter
++ *    (increase VM refcount and unlock VM)
++ * 2. reconnect to monitor
++ * 3. do lightweight MonitorExit (lock VM)
++ * 4. continue reconnect process
++ * 5. EndJob
++ *
++ * We can't do normal MonitorEnter & MonitorExit because these two lock the
++ * monitor lock, which does not exists in this early phase.
++ */
++static void
++qemuProcessReconnect(void *opaque)
++{
++    struct qemuProcessReconnectData *data = opaque;
++    virQEMUDriverPtr driver = data->driver;
++    virDomainObjPtr obj = data->obj;
++    qemuDomainObjPrivatePtr priv;
++    virConnectPtr conn = data->conn;
++    struct qemuDomainJobObj oldjob;
++    int state;
++    int reason;
++    virQEMUDriverConfigPtr cfg;
++    size_t i;
++    unsigned int stopFlags = 0;
++    bool jobStarted = false;
++    virCapsPtr caps = NULL;
++
++    VIR_FREE(data);
++
++    qemuDomainObjRestoreJob(obj, &oldjob);
++    if (oldjob.asyncJob == QEMU_ASYNC_JOB_MIGRATION_IN)
++        stopFlags |= VIR_QEMU_PROCESS_STOP_MIGRATED;
++
++    cfg = virQEMUDriverGetConfig(driver);
++    priv = obj->privateData;
++
++    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
++        goto error;
++
++    if (qemuDomainObjBeginJob(driver, obj, QEMU_JOB_MODIFY) < 0)
++        goto error;
++    jobStarted = true;
++
++    /* XXX If we ever gonna change pid file pattern, come up with
++     * some intelligence here to deal with old paths. */
++    if (!(priv->pidfile = virPidFileBuildPath(cfg->stateDir, obj->def->name)))
++        goto error;
++
++    /* Restore the masterKey */
++    if (qemuDomainMasterKeyReadFile(priv) < 0)
++        goto error;
++
++    virNWFilterReadLockFilterUpdates();
++
++    VIR_DEBUG("Reconnect monitor to %p '%s'", obj, obj->def->name);
++
++    /* XXX check PID liveliness & EXE path */
++    if (qemuConnectMonitor(driver, obj, QEMU_ASYNC_JOB_NONE, NULL) < 0)
++        goto error;
++
++    if (qemuHostdevUpdateActiveDomainDevices(driver, obj->def) < 0)
++        goto error;
++
++    if (qemuConnectCgroup(driver, obj) < 0)
++        goto error;
++
++    if (qemuDomainPerfRestart(obj) < 0)
++        goto error;
++
++    /* XXX: Need to change as long as lock is introduced for
++     * qemu_driver->sharedDevices.
++     */
++    for (i = 0; i < obj->def->ndisks; i++) {
++        virDomainDeviceDef dev;
++
++        if (virStorageTranslateDiskSourcePool(conn, obj->def->disks[i]) < 0)
++            goto error;
++
++        /* XXX we should be able to restore all data from XML in the future.
++         * This should be the only place that calls qemuDomainDetermineDiskChain
++         * with @report_broken == false to guarantee best-effort domain
++         * reconnect */
++        if (qemuDomainDetermineDiskChain(driver, obj, obj->def->disks[i],
++                                         true, false) < 0)
++            goto error;
++
++        dev.type = VIR_DOMAIN_DEVICE_DISK;
++        dev.data.disk = obj->def->disks[i];
++        if (qemuAddSharedDevice(driver, &dev, obj->def->name) < 0)
++            goto error;
++    }
++
++    if (qemuProcessUpdateState(driver, obj) < 0)
++        goto error;
++
++    state = virDomainObjGetState(obj, &reason);
++    if (state == VIR_DOMAIN_SHUTOFF ||
++        (state == VIR_DOMAIN_PAUSED &&
++         reason == VIR_DOMAIN_PAUSED_STARTING_UP)) {
++        VIR_DEBUG("Domain '%s' wasn't fully started yet, killing it",
++                  obj->def->name);
++        goto error;
++    }
++
++    /* If upgrading from old libvirtd we won't have found any
++     * caps in the domain status, so re-query them
++     */
++    if (!priv->qemuCaps &&
++        !(priv->qemuCaps = virQEMUCapsCacheLookupCopy(caps,
++                                                      driver->qemuCapsCache,
++                                                      obj->def->emulator,
++                                                      obj->def->os.machine)))
++        goto error;
++
++    /* In case the domain shutdown while we were not running,
++     * we need to finish the shutdown process. And we need to do it after
++     * we have virQEMUCaps filled in.
++     */
++    if (state == VIR_DOMAIN_SHUTDOWN ||
++        (state == VIR_DOMAIN_PAUSED &&
++         reason == VIR_DOMAIN_PAUSED_SHUTTING_DOWN)) {
++        VIR_DEBUG("Finishing shutdown sequence for domain %s",
++                  obj->def->name);
++        qemuProcessShutdownOrReboot(driver, obj);
++        goto cleanup;
++    }
++
++    if (qemuProcessBuildDestroyHugepagesPath(driver, obj, true) < 0)
++        goto error;
++
++    if ((qemuDomainAssignAddresses(obj->def, priv->qemuCaps,
++                                   driver, obj, false)) < 0) {
++        goto error;
++    }
++
++    /* if domain requests security driver we haven't loaded, report error, but
++     * do not kill the domain
++     */
++    ignore_value(qemuSecurityCheckAllLabel(driver->securityManager,
++                                           obj->def));
++
++    if (qemuDomainRefreshVcpuInfo(driver, obj, QEMU_ASYNC_JOB_NONE, true) < 0)
++        goto error;
++
++    qemuDomainVcpuPersistOrder(obj->def);
++
++    if (qemuSecurityReserveLabel(driver->securityManager, obj->def, obj->pid) < 0)
++        goto error;
++
++    qemuProcessNotifyNets(obj->def);
++
++    if (qemuProcessFiltersInstantiate(obj->def))
++        goto error;
++
++    if (qemuProcessRefreshDisks(driver, obj, QEMU_ASYNC_JOB_NONE) < 0)
++        goto error;
++
++    if (qemuBlockNodeNamesDetect(driver, obj) < 0)
++        goto error;
++
++    if (qemuRefreshVirtioChannelState(driver, obj, QEMU_ASYNC_JOB_NONE) < 0)
++        goto error;
++
++    /* If querying of guest's RTC failed, report error, but do not kill the domain. */
++    qemuRefreshRTC(driver, obj);
++
++    if (qemuProcessRefreshBalloonState(driver, obj, QEMU_ASYNC_JOB_NONE) < 0)
++        goto error;
++
++    if (qemuProcessRecoverJob(driver, obj, conn, &oldjob, &stopFlags) < 0)
++        goto error;
++
++    if (qemuProcessUpdateDevices(driver, obj) < 0)
++        goto error;
++
++    qemuProcessReconnectCheckMemAliasOrderMismatch(obj);
++
++    if (qemuConnectAgent(driver, obj) < 0)
++        goto error;
++
++    /* update domain state XML with possibly updated state in virDomainObj */
++    if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, obj, driver->caps) < 0)
++        goto error;
++
++    /* Run an hook to allow admins to do some magic */
++    if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
++        char *xml = qemuDomainDefFormatXML(driver, obj->def, 0);
++        int hookret;
++
++        hookret = virHookCall(VIR_HOOK_DRIVER_QEMU, obj->def->name,
++                              VIR_HOOK_QEMU_OP_RECONNECT, VIR_HOOK_SUBOP_BEGIN,
++                              NULL, xml, NULL);
++        VIR_FREE(xml);
++
++        /*
++         * If the script raised an error abort the launch
++         */
++        if (hookret < 0)
++            goto error;
++    }
++
++    if (virAtomicIntInc(&driver->nactive) == 1 && driver->inhibitCallback)
++        driver->inhibitCallback(true, driver->inhibitOpaque);
++
++ cleanup:
++    if (jobStarted)
++        qemuDomainObjEndJob(driver, obj);
++    if (!virDomainObjIsActive(obj))
++        qemuDomainRemoveInactive(driver, obj);
++    virDomainObjEndAPI(&obj);
++    virObjectUnref(conn);
++    virObjectUnref(cfg);
++    virObjectUnref(caps);
++    virNWFilterUnlockFilterUpdates();
++    return;
++
++ error:
++    if (virDomainObjIsActive(obj)) {
++        /* We can't get the monitor back, so must kill the VM
++         * to remove danger of it ending up running twice if
++         * user tries to start it again later
++         */
++        if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NO_SHUTDOWN)) {
++            /* If we couldn't get the monitor and qemu supports
++             * no-shutdown, we can safely say that the domain
++             * crashed ... */
++            state = VIR_DOMAIN_SHUTOFF_CRASHED;
++        } else {
++            /* ... but if it doesn't we can't say what the state
++             * really is and FAILED means "failed to start" */
++            state = VIR_DOMAIN_SHUTOFF_UNKNOWN;
++        }
++        /* If BeginJob failed, we jumped here without a job, let's hope another
++         * thread didn't have a chance to start playing with the domain yet
++         * (it's all we can do anyway).
++         */
++        qemuProcessStop(driver, obj, state, QEMU_ASYNC_JOB_NONE, stopFlags);
++    }
++    goto cleanup;
++}
++
++static int
++qemuProcessReconnectHelper(virDomainObjPtr obj,
++                           void *opaque)
++{
++    virThread thread;
++    struct qemuProcessReconnectData *src = opaque;
++    struct qemuProcessReconnectData *data;
++
++    /* If the VM was inactive, we don't need to reconnect */
++    if (!obj->pid)
++        return 0;
++
++    if (VIR_ALLOC(data) < 0)
++        return -1;
++
++    memcpy(data, src, sizeof(*data));
++    data->obj = obj;
++
++    /* this lock and reference will be eventually transferred to the thread
++     * that handles the reconnect */
++    virObjectLock(obj);
++    virObjectRef(obj);
++
++    /* Since we close the connection later on, we have to make sure that the
++     * threads we start see a valid connection throughout their lifetime. We
++     * simply increase the reference counter here.
++     */
++    virObjectRef(data->conn);
++
++    if (virThreadCreate(&thread, false, qemuProcessReconnect, data) < 0) {
++        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
++                       _("Could not create thread. QEMU initialization "
++                         "might be incomplete"));
++        /* We can't spawn a thread and thus connect to monitor. Kill qemu.
++         * It's safe to call qemuProcessStop without a job here since there
++         * is no thread that could be doing anything else with the same domain
++         * object.
++         */
++        qemuProcessStop(src->driver, obj, VIR_DOMAIN_SHUTOFF_FAILED,
++                        QEMU_ASYNC_JOB_NONE, 0);
++        qemuDomainRemoveInactive(src->driver, obj);
++
++        virDomainObjEndAPI(&obj);
++        virObjectUnref(data->conn);
++        VIR_FREE(data);
++        return -1;
++    }
++
++    return 0;
++}
++
++/**
++ * qemuProcessReconnectAll
++ *
++ * Try to re-open the resources for live VMs that we care
++ * about.
++ */
++void
++qemuProcessReconnectAll(virConnectPtr conn, virQEMUDriverPtr driver)
++{
++    struct qemuProcessReconnectData data = {.conn = conn, .driver = driver};
++    virDomainObjListForEach(driver->domains, qemuProcessReconnectHelper, &data);
++}
+-- 
+2.13.2
+
diff --git a/SOURCES/libvirt-qemu-Rename-qemuProcessUpdateLiveGuestCPU.patch b/SOURCES/libvirt-qemu-Rename-qemuProcessUpdateLiveGuestCPU.patch
new file mode 100644
index 0000000..b4d8e50
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Rename-qemuProcessUpdateLiveGuestCPU.patch
@@ -0,0 +1,47 @@
+From dfc345ac7bd7bc87c297fc9887453e8f3035191c Mon Sep 17 00:00:00 2001
+Message-Id: <dfc345ac7bd7bc87c297fc9887453e8f3035191c@dist-git>
+From: Jiri Denemark <jdenemar@redhat.com>
+Date: Tue, 11 Jul 2017 13:30:09 +0200
+Subject: [PATCH] qemu: Rename qemuProcessUpdateLiveGuestCPU
+
+In addition to updating a guest CPU definition the function verifies
+that all required features are provided to the guest. Let's make it
+obvious by calling it qemuProcessUpdateAndVerifyCPU.
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
+(cherry picked from commit e6ed55e4e9c9ec21ca87573b69225d2fafc54272)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1470582
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
+---
+ src/qemu/qemu_process.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
+index 3f7a9f4c02..1e7724e784 100644
+--- a/src/qemu/qemu_process.c
++++ b/src/qemu/qemu_process.c
+@@ -3971,7 +3971,7 @@ qemuProcessVerifyCPU(virDomainObjPtr vm,
+ 
+ 
+ static int
+-qemuProcessUpdateLiveGuestCPU(virQEMUDriverPtr driver,
++qemuProcessUpdateAndVerifyCPU(virQEMUDriverPtr driver,
+                               virDomainObjPtr vm,
+                               qemuDomainAsyncJob asyncJob)
+ {
+@@ -5875,7 +5875,7 @@ qemuProcessLaunch(virConnectPtr conn,
+         goto cleanup;
+ 
+     VIR_DEBUG("Verifying and updating provided guest CPU");
+-    if (qemuProcessUpdateLiveGuestCPU(driver, vm, asyncJob) < 0)
++    if (qemuProcessUpdateAndVerifyCPU(driver, vm, asyncJob) < 0)
+         goto cleanup;
+ 
+     VIR_DEBUG("Setting up post-init cgroup restrictions");
+-- 
+2.13.2
+
diff --git a/SOURCES/libvirt-qemu-Update-host-model-CPUs-on-reconnect.patch b/SOURCES/libvirt-qemu-Update-host-model-CPUs-on-reconnect.patch
new file mode 100644
index 0000000..9e5a0e9
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Update-host-model-CPUs-on-reconnect.patch
@@ -0,0 +1,94 @@
+From 9c2457dd94cf148dce04ee5fd3997003ca03a642 Mon Sep 17 00:00:00 2001
+Message-Id: <9c2457dd94cf148dce04ee5fd3997003ca03a642@dist-git>
+From: Jiri Denemark <jdenemar@redhat.com>
+Date: Tue, 11 Jul 2017 14:16:40 +0200
+Subject: [PATCH] qemu: Update host-model CPUs on reconnect
+
+When libvirt starts a new QEMU domain, it replaces host-model CPUs with
+the appropriate custom CPU definition. However, when reconnecting to a
+domain started by older libvirt (< 2.3), the domain would still have a
+host-model CPU in its active definition.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1463957
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
+(cherry picked from commit 7cf22b4879e819dee42e0a058f7ed149dc9d639a)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1470582
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
+---
+ src/qemu/qemu_process.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 48 insertions(+)
+
+diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
+index e6f56dc484..8fe9ef36d7 100644
+--- a/src/qemu/qemu_process.c
++++ b/src/qemu/qemu_process.c
+@@ -3718,6 +3718,30 @@ qemuProcessUpdateAndVerifyCPU(virQEMUDriverPtr driver,
+ 
+ 
+ static int
++qemuProcessUpdateCPU(virQEMUDriverPtr driver,
++                     virDomainObjPtr vm,
++                     qemuDomainAsyncJob asyncJob)
++{
++    virCPUDataPtr cpu = NULL;
++    virCPUDataPtr disabled = NULL;
++    int ret = -1;
++
++    if (qemuProcessFetchGuestCPU(driver, vm, asyncJob, &cpu, &disabled) < 0)
++        goto cleanup;
++
++    if (qemuProcessUpdateLiveGuestCPU(vm, cpu, disabled) < 0)
++        goto cleanup;
++
++    ret = 0;
++
++ cleanup:
++    virCPUDataFree(cpu);
++    virCPUDataFree(disabled);
++    return ret;
++}
++
++
++static int
+ qemuPrepareNVRAM(virQEMUDriverConfigPtr cfg,
+                  virDomainObjPtr vm)
+ {
+@@ -6796,6 +6820,30 @@ qemuProcessReconnect(void *opaque)
+     ignore_value(qemuSecurityCheckAllLabel(driver->securityManager,
+                                            obj->def));
+ 
++    /* If the domain with a host-model CPU was started by an old libvirt
++     * (< 2.3) which didn't replace the CPU with a custom one, let's do it now
++     * since the rest of our code does not really expect a host-model CPU in a
++     * running domain.
++     */
++    if (virQEMUCapsGuestIsNative(caps->host.arch, obj->def->os.arch) &&
++        caps->host.cpu &&
++        obj->def->cpu &&
++        obj->def->cpu->mode == VIR_CPU_MODE_HOST_MODEL) {
++        virCPUDefPtr host;
++
++        if (!(host = virCPUCopyMigratable(caps->host.cpu->arch, caps->host.cpu)))
++            goto error;
++
++        if (virCPUUpdate(obj->def->os.arch, obj->def->cpu, host) < 0) {
++            virCPUDefFree(host);
++            goto error;
++        }
++        virCPUDefFree(host);
++
++        if (qemuProcessUpdateCPU(driver, obj, QEMU_ASYNC_JOB_NONE) < 0)
++            goto error;
++    }
++
+     if (qemuDomainRefreshVcpuInfo(driver, obj, QEMU_ASYNC_JOB_NONE, true) < 0)
+         goto error;
+ 
+-- 
+2.13.2
+
diff --git a/SOURCES/libvirt-qemuDomainBuildNamespace-Handle-special-file-mount-points.patch b/SOURCES/libvirt-qemuDomainBuildNamespace-Handle-special-file-mount-points.patch
new file mode 100644
index 0000000..0191509
--- /dev/null
+++ b/SOURCES/libvirt-qemuDomainBuildNamespace-Handle-special-file-mount-points.patch
@@ -0,0 +1,54 @@
+From 4f54b2f401e4e1a443f6c889cbd2373aaa249d28 Mon Sep 17 00:00:00 2001
+Message-Id: <4f54b2f401e4e1a443f6c889cbd2373aaa249d28@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Mon, 17 Jul 2017 14:48:21 +0200
+Subject: [PATCH] qemuDomainBuildNamespace: Handle special file mount points
+
+RHEL-7.5: https://bugzilla.redhat.com/show_bug.cgi?id=1459592
+RHEL-7.4.z: https://bugzilla.redhat.com/show_bug.cgi?id=1471660
+
+In 290a00e41d I've tried to fix the process of building a
+qemu namespace when dealing with file mount points. What I
+haven't realized then is that we might be dealing not with just
+regular files but also special files (like sockets). Indeed, try
+the following:
+
+1) socat unix-listen:/tmp/soket stdio
+2) touch /dev/socket
+3) mount --bind /tmp/socket /dev/socket
+4) virsh start anyDomain
+
+Problem with my previous approach is that I wasn't creating the
+temporary location (where mount points under /dev are moved) for
+anything but directories and regular files.
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: John Ferlan <jferlan@redhat.com>
+(cherry picked from commit 7154917908d9f712a950a2716c4687e57ccb74e7)
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/qemu/qemu_domain.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index 6ccc9f6f5b..c9c668b892 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -8305,9 +8305,11 @@ qemuDomainBuildNamespace(virQEMUDriverConfigPtr cfg,
+             goto cleanup;
+         }
+ 
+-        /* At this point, devMountsPath is either a regular file or a directory. */
++        /* At this point, devMountsPath is either:
++         * a file (regular or special), or
++         * a directory. */
+         if ((S_ISDIR(sb.st_mode) && virFileMakePath(devMountsSavePath[i]) < 0) ||
+-            (S_ISREG(sb.st_mode) && virFileTouch(devMountsSavePath[i], sb.st_mode) < 0)) {
++            (!S_ISDIR(sb.st_mode) && virFileTouch(devMountsSavePath[i], sb.st_mode) < 0)) {
+             virReportSystemError(errno,
+                                  _("Failed to create %s"),
+                                  devMountsSavePath[i]);
+-- 
+2.13.3
+
diff --git a/SPECS/libvirt.spec b/SPECS/libvirt.spec
index 2ba76d4..6913178 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}%{?extra_release}
+Release: 14%{?dist}.2%{?extra_release}
 License: LGPLv2+
 Group: Development/Libraries
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
@@ -470,6 +470,17 @@ Patch227: libvirt-qemu-snapshot-Load-data-necessary-for-relative-block-commit-to
 Patch228: libvirt-util-storage-Make-backingFormat-optional-in-virStorageFileGetMetadataInternal.patch
 Patch229: libvirt-qemu-Change-coalesce-settings-on-hotplug-when-they-are-different.patch
 Patch230: libvirt-qemu-Do-not-skip-virCPUUpdateLive-if-priv-origCPU-is-set.patch
+Patch231: libvirt-qemu-Don-t-update-CPU-when-checking-ABI-stability.patch
+Patch232: libvirt-cpu_x86-Properly-disable-unknown-CPU-features.patch
+Patch233: libvirt-qemu-Add-qemuProcessFetchGuestCPU.patch
+Patch234: libvirt-qemu-Add-qemuProcessVerifyCPU.patch
+Patch235: libvirt-qemu-Rename-qemuProcessUpdateLiveGuestCPU.patch
+Patch236: libvirt-qemu-Add-qemuProcessUpdateLiveGuestCPU.patch
+Patch237: libvirt-qemu-Export-virQEMUCapsGuestIsNative.patch
+Patch238: libvirt-qemu-Move-qemuProcessReconnect-to-the-end-of-qemu_process.c.patch
+Patch239: libvirt-qemu-Update-host-model-CPUs-on-reconnect.patch
+Patch240: libvirt-qemu-Fix-qemuDomainGetBlockInfo-allocation-value-setting.patch
+Patch241: libvirt-qemuDomainBuildNamespace-Handle-special-file-mount-points.patch
 
 Requires: libvirt-daemon = %{version}-%{release}
 Requires: libvirt-daemon-config-network = %{version}-%{release}
@@ -2318,6 +2329,21 @@ exit 0
 
 
 %changelog
+* Tue Jul 18 2017 Jiri Denemark <jdenemar@redhat.com> - 3.2.0-14.el7_4.2
+- qemu: Fix qemuDomainGetBlockInfo allocation value setting (rhbz#1470127)
+- qemuDomainBuildNamespace: Handle special file mount points (rhbz#1471660)
+
+* Thu Jul 13 2017 Jiri Denemark <jdenemar@redhat.com> - 3.2.0-14.el7_4.1
+- qemu: Don't update CPU when checking ABI stability (rhbz#1470582)
+- cpu_x86: Properly disable unknown CPU features (rhbz#1470582)
+- qemu: Add qemuProcessFetchGuestCPU (rhbz#1470582)
+- qemu: Add qemuProcessVerifyCPU (rhbz#1470582)
+- qemu: Rename qemuProcessUpdateLiveGuestCPU (rhbz#1470582)
+- qemu: Add qemuProcessUpdateLiveGuestCPU (rhbz#1470582)
+- qemu: Export virQEMUCapsGuestIsNative (rhbz#1470582)
+- qemu: Move qemuProcessReconnect to the end of qemu_process.c (rhbz#1470582)
+- qemu: Update host-model CPUs on reconnect (rhbz#1470582)
+
 * Wed Jun 21 2017 Jiri Denemark <jdenemar@redhat.com> - 3.2.0-14
 - qemu: Do not skip virCPUUpdateLive if priv->origCPU is set (rhbz#1441662)