From nobody Mon Mar 30 00:45:31 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 149209044681851.39959781650771; Thu, 13 Apr 2017 06:34:06 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 4DBF4624BE; Thu, 13 Apr 2017 13:34:05 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 195847C74B; Thu, 13 Apr 2017 13:34:05 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id BCDA51853D1E; Thu, 13 Apr 2017 13:33:18 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v3DDXHSq013184 for ; Thu, 13 Apr 2017 09:33:17 -0400 Received: by smtp.corp.redhat.com (Postfix) id 69D647FB9E; Thu, 13 Apr 2017 13:33:17 +0000 (UTC) Received: from virval.usersys.redhat.com (dhcp129-92.brq.redhat.com [10.34.129.92]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 1A0497FB90 for ; Thu, 13 Apr 2017 13:33:05 +0000 (UTC) Received: by virval.usersys.redhat.com (Postfix, from userid 500) id C2B701041AF; Thu, 13 Apr 2017 15:32:59 +0200 (CEST) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 4DBF4624BE Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=libvir-list-bounces@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 4DBF4624BE From: Jiri Denemark To: libvir-list@redhat.com Date: Thu, 13 Apr 2017 15:32:58 +0200 Message-Id: <85ee43ef980f5b3dc7df336a2b4ac6f45e78152f.1492090347.git.jdenemar@redhat.com> In-Reply-To: References: In-Reply-To: References: Mail-Followup-To: libvir-list@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 9/9] qemu: Use more data for comparing CPUs X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Thu, 13 Apr 2017 13:34:06 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" With QEMU older than 2.9.0 libvirt uses CPUID instruction to determine what CPU features are supported on the host. This was later used when checking compatibility of guest CPUs. Since QEMU 2.9.0 we ask QEMU for the host CPU data. But the two methods we use usually provide disjoint sets of CPU features because QEMU/KVM does not support all features provided by the host CPU and on the other hand it can enable some feature even if the host CPU does not support them. So if there is a domain which requires a CPU features disabled by QEMU/KVM, libvirt will refuse to start it with QEMU > 2.9.0 as its guest CPU is incompatible with the host CPU data we got from QEMU. But such domain would happily start on older QEMU (of course, the features would be missing the guest CPU). To fix this regression, we need to combine both CPU feature sets when checking guest CPU compatibility. https://bugzilla.redhat.com/show_bug.cgi?id=3D1439933 Signed-off-by: Jiri Denemark --- src/qemu/qemu_capabilities.c | 35 +++++++++++++++++++++++++++++++++-- src/qemu/qemu_capabilities.h | 4 ++++ src/qemu/qemu_process.c | 2 +- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 1d95e67b3..531677865 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -386,6 +386,10 @@ struct _virQEMUCapsHostCPUData { virCPUDefPtr reported; /* Migratable host CPU definition used for updating guest CPU. */ virCPUDefPtr migratable; + /* CPU definition with features detected by libvirt using virCPUGetHost + * combined with features reported by QEMU. This is used for backward + * compatible comparison between a guest CPU and a host CPU. */ + virCPUDefPtr full; }; =20 /* @@ -2142,6 +2146,10 @@ virQEMUCapsHostCPUDataCopy(virQEMUCapsHostCPUDataPtr= dst, !(dst->migratable =3D virCPUDefCopy(src->migratable))) return -1; =20 + if (src->full && + !(dst->full =3D virCPUDefCopy(src->full))) + return -1; + return 0; } =20 @@ -2152,6 +2160,7 @@ virQEMUCapsHostCPUDataClear(virQEMUCapsHostCPUDataPtr= cpuData) qemuMonitorCPUModelInfoFree(cpuData->info); virCPUDefFree(cpuData->reported); virCPUDefFree(cpuData->migratable); + virCPUDefFree(cpuData->full); =20 memset(cpuData, '\0', sizeof(*cpuData)); } @@ -2493,6 +2502,11 @@ virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps, =20 case VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE: return cpuData->migratable; + + case VIR_QEMU_CAPS_HOST_CPU_FULL: + /* 'full' is non-NULL only if we have data from both QEMU and + * virCPUGetHost */ + return cpuData->full ? cpuData->full : cpuData->reported; } =20 return NULL; @@ -2503,12 +2517,14 @@ static void virQEMUCapsSetHostModel(virQEMUCapsPtr qemuCaps, virDomainVirtType type, virCPUDefPtr reported, - virCPUDefPtr migratable) + virCPUDefPtr migratable, + virCPUDefPtr full) { virQEMUCapsHostCPUDataPtr cpuData =3D virQEMUCapsGetHostCPUData(qemuCa= ps, type); =20 cpuData->reported =3D reported; cpuData->migratable =3D migratable; + cpuData->full =3D full; } =20 =20 @@ -3385,6 +3401,8 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps, virCPUDefPtr cpu =3D NULL; virCPUDefPtr migCPU =3D NULL; virCPUDefPtr hostCPU =3D NULL; + virCPUDefPtr fullCPU =3D NULL; + size_t i; int rc; =20 if (!caps || !virQEMUCapsGuestIsNative(caps->host.arch, qemuCaps->arch= )) @@ -3404,6 +3422,18 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps, virQEMUCapsCPUFilterFeatures, qemuCaps) < 0) goto error; + } else if (type =3D=3D VIR_DOMAIN_VIRT_KVM && + virCPUGetHostIsSupported(qemuCaps->arch)) { + if (!(fullCPU =3D virCPUGetHost(qemuCaps->arch, VIR_CPU_TYPE_GUEST, + NULL, NULL, 0))) + goto error; + + for (i =3D 0; i < cpu->nfeatures; i++) { + if (cpu->features[i].policy =3D=3D VIR_CPU_FEATURE_REQUIRE && + virCPUDefUpdateFeature(fullCPU, cpu->features[i].name, + VIR_CPU_FEATURE_REQUIRE) < 0) + goto error; + } } =20 if (!(migCPU =3D virQEMUCapsNewHostCPUModel())) @@ -3419,7 +3449,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps, goto error; } =20 - virQEMUCapsSetHostModel(qemuCaps, type, cpu, migCPU); + virQEMUCapsSetHostModel(qemuCaps, type, cpu, migCPU, fullCPU); =20 cleanup: virCPUDefFree(hostCPU); @@ -3428,6 +3458,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps, error: virCPUDefFree(cpu); virCPUDefFree(migCPU); + virCPUDefFree(fullCPU); virResetLastError(); goto cleanup; } diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index f04f74060..a7eec52a9 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -455,6 +455,10 @@ typedef enum { VIR_QEMU_CAPS_HOST_CPU_REPORTED, /* Migratable host CPU definition used for updating guest CPU. */ VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE, + /* CPU definition with features detected by libvirt using virCPUGetHost + * combined with features reported by QEMU. This is used for backward + * compatible comparison between a guest CPU and a host CPU. */ + VIR_QEMU_CAPS_HOST_CPU_FULL, } virQEMUCapsHostCPUType; =20 virCPUDefPtr virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps, diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 6b77a3969..53170d732 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -5305,7 +5305,7 @@ qemuProcessUpdateGuestCPU(virDomainDefPtr def, if (def->cpu->check =3D=3D VIR_CPU_CHECK_PARTIAL && virCPUCompare(caps->host.arch, virQEMUCapsGetHostModel(qemuCaps, def->virtType, - VIR_QEMU_CAPS_HOST_CPU_REPOR= TED), + VIR_QEMU_CAPS_HOST_CPU_FULL), def->cpu, true) < 0) return -1; =20 --=20 2.12.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list