0f4c8a
From f05df8ca745a00a1c8bc783dcf25f648cbe5d508 Mon Sep 17 00:00:00 2001
0f4c8a
Message-Id: <f05df8ca745a00a1c8bc783dcf25f648cbe5d508@dist-git>
0f4c8a
From: Jiri Denemark <jdenemar@redhat.com>
0f4c8a
Date: Fri, 6 Oct 2017 13:23:36 +0200
0f4c8a
Subject: [PATCH] qemu: Filter CPU features when using host CPU
0f4c8a
0f4c8a
When reconnecting to a domain started with a host-model CPU which was
0f4c8a
started by old libvirt that did not replace host-model with the real CPU
0f4c8a
definition, libvirt replaces the host-model CPU with the CPU from
0f4c8a
capabilities (because this is what the old libvirt did when it started
0f4c8a
the domain). Without this patch libvirt could use features unknown to
0f4c8a
QEMU in the CPU definition which replaced the original host-model CPU.
0f4c8a
Such domain would keep running just fine, but any attempt to migrate it
0f4c8a
will fail and once the domain is saved or snapshotted, restoring it
0f4c8a
would fail too.
0f4c8a
0f4c8a
In other words whenever we want to use the CPU definition from host
0f4c8a
capabilities as a guest CPU definition, we have to filter the unknown
0f4c8a
features.
0f4c8a
0f4c8a
https://bugzilla.redhat.com/show_bug.cgi?id=1495171
0f4c8a
0f4c8a
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
0f4c8a
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
0f4c8a
(cherry picked from commit e26cc8f82ff346c9ec90409bac06581b64e42b20)
0f4c8a
0f4c8a
https://bugzilla.redhat.com/show_bug.cgi?id=1508549
0f4c8a
0f4c8a
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
0f4c8a
---
0f4c8a
 src/qemu/qemu_process.c | 10 +++++++++-
0f4c8a
 1 file changed, 9 insertions(+), 1 deletion(-)
0f4c8a
0f4c8a
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
0f4c8a
index 4a8c4421a3..0bed084381 100644
0f4c8a
--- a/src/qemu/qemu_process.c
0f4c8a
+++ b/src/qemu/qemu_process.c
0f4c8a
@@ -6668,6 +6668,7 @@ qemuProcessRefreshCPU(virQEMUDriverPtr driver,
0f4c8a
 {
0f4c8a
     virCapsPtr caps = virQEMUDriverGetCapabilities(driver, false);
0f4c8a
     virCPUDefPtr host = NULL;
0f4c8a
+    virCPUDefPtr cpu = NULL;
0f4c8a
     int ret = -1;
0f4c8a
 
0f4c8a
     if (!caps)
0f4c8a
@@ -6689,7 +6690,13 @@ qemuProcessRefreshCPU(virQEMUDriverPtr driver,
0f4c8a
         if (!(host = virCPUCopyMigratable(caps->host.cpu->arch, caps->host.cpu)))
0f4c8a
             goto cleanup;
0f4c8a
 
0f4c8a
-        if (virCPUUpdate(vm->def->os.arch, vm->def->cpu, host) < 0)
0f4c8a
+        if (!(cpu = virCPUDefCopyWithoutModel(host)) ||
0f4c8a
+            virCPUDefCopyModelFilter(cpu, host, false,
0f4c8a
+                                     virQEMUCapsCPUFilterFeatures,
0f4c8a
+                                     &caps->host.cpu->arch) < 0)
0f4c8a
+            goto cleanup;
0f4c8a
+
0f4c8a
+        if (virCPUUpdate(vm->def->os.arch, vm->def->cpu, cpu) < 0)
0f4c8a
             goto cleanup;
0f4c8a
 
0f4c8a
         if (qemuProcessUpdateCPU(driver, vm, QEMU_ASYNC_JOB_NONE) < 0)
0f4c8a
@@ -6699,6 +6706,7 @@ qemuProcessRefreshCPU(virQEMUDriverPtr driver,
0f4c8a
     ret = 0;
0f4c8a
 
0f4c8a
  cleanup:
0f4c8a
+    virCPUDefFree(cpu);
0f4c8a
     virCPUDefFree(host);
0f4c8a
     virObjectUnref(caps);
0f4c8a
     return ret;
0f4c8a
-- 
0f4c8a
2.15.0
0f4c8a