From nobody Wed May 15 11:17:08 2024 Delivered-To: importer@patchew.org Received-SPF: none (zohomail.com: 8.43.85.245 is neither permitted nor denied by domain of lists.libvirt.org) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; spf=none (zohomail.com: 8.43.85.245 is neither permitted nor denied by domain of lists.libvirt.org) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1710263404220808.1840387882486; Tue, 12 Mar 2024 10:10:04 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id DFD1A1D9E; Tue, 12 Mar 2024 13:10:02 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id B7A421DDE; Tue, 12 Mar 2024 13:07:16 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 8E9351A7C; Tue, 12 Mar 2024 13:07:11 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id A39AE1A74 for ; Tue, 12 Mar 2024 13:07:08 -0400 (EDT) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-36-aoJv_tX-N6Kdo7aSJbik1g-1; Tue, 12 Mar 2024 13:07:06 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 2C43F803CEE for ; Tue, 12 Mar 2024 17:07:06 +0000 (UTC) Received: from orkuz (unknown [10.45.224.148]) by smtp.corp.redhat.com (Postfix) with ESMTP id E441D2024517 for ; Tue, 12 Mar 2024 17:07:05 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.4 X-MC-Unique: aoJv_tX-N6Kdo7aSJbik1g-1 From: Jiri Denemark To: devel@lists.libvirt.org Subject: [PATCH 01/22] cpu: x86: Add support for adding features to existing CPU models Date: Tue, 12 Mar 2024 18:06:41 +0100 Message-ID: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.4 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Message-ID-Hash: 3AZT3EPU7D754X5WIYGHSUQ45RGIDZK4 X-Message-ID-Hash: 3AZT3EPU7D754X5WIYGHSUQ45RGIDZK4 X-MailFrom: jdenemar@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1710263406043100001 This is not a good idea in general, but we can (and have to) do it in specific cases when a feature has always been part of a CPU model in hypervisor's definition, but we ignored it and did not include the feature in our definition. Blindly adding the features to the CPU map and not adding them to existing CPU models breaks migration between old and new libvirt in both directions. New libvirt would complain the features got unexpectedly enabled (as they were not mentioned in the incoming domain XML) even though they were also enabled on the source and the old libvirt just didn't know about them. On the other hand, old libvirt would refuse to accept incoming migration of a domain started by new libvirt because the domain XML would contain CPU features unknown to the old libvirt. This is exactly what happened when several vmx-* features were added a few releases back. Migration between libvirt releases before and after the addition is now broken. This patch adds support for added these features to existing CPU models by marking them with added=3D'yes'. The features will not be considered part of the CPU model and will be described explicitly via additional elements, but the compatibility check will not complain if they are enabled by the hypervisor even though they were not explicitly mentioned in the CPU definition and incoming migration from old libvirt will succeed. To fix outgoing migration to old libvirt, we also need to drop all those features from domain XML unless they were explicitly requested by the user. This will be handled by a later patch. Signed-off-by: Jiri Denemark Reviewed-by: Peter Krempa --- src/cpu/cpu_x86.c | 69 ++++++++++++++++++++++++++++++++++++++-- src/cpu/cpu_x86.h | 3 ++ src/libvirt_private.syms | 1 + 3 files changed, 70 insertions(+), 3 deletions(-) diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c index e8409ce616..b6193d84a7 100644 --- a/src/cpu/cpu_x86.c +++ b/src/cpu/cpu_x86.c @@ -148,6 +148,17 @@ struct _virCPUx86Model { virCPUx86Signatures *signatures; virCPUx86Data data; GStrv removedFeatures; + + /* Features added to the CPU model after its original version was rele= ased. + * Such features are not really considered part of the model, but the + * compatibility check will not complain if they are enabled by the + * hypervisor even though they were not explicitly mentioned in the CPU + * definition. This should only be used for features which were always + * included in the CPU model by the hypervisor, but libvirt didn't sup= port + * them when introducing the CPU model. In other words, they were enab= led, + * but we ignored them. + */ + GStrv addedFeatures; }; =20 typedef struct _virCPUx86Map virCPUx86Map; @@ -1276,6 +1287,7 @@ x86ModelFree(virCPUx86Model *model) virCPUx86SignaturesFree(model->signatures); virCPUx86DataClear(&model->data); g_strfreev(model->removedFeatures); + g_strfreev(model->addedFeatures); g_free(model); } G_DEFINE_AUTOPTR_CLEANUP_FUNC(virCPUx86Model, x86ModelFree); @@ -1291,6 +1303,7 @@ x86ModelCopy(virCPUx86Model *model) copy->signatures =3D virCPUx86SignaturesCopy(model->signatures); x86DataCopy(©->data, &model->data); copy->removedFeatures =3D g_strdupv(model->removedFeatures); + copy->addedFeatures =3D g_strdupv(model->addedFeatures); copy->vendor =3D model->vendor; =20 return g_steal_pointer(©); @@ -1596,17 +1609,20 @@ x86ModelParseFeatures(virCPUx86Model *model, g_autofree xmlNodePtr *nodes =3D NULL; size_t i; size_t nremoved =3D 0; + size_t nadded =3D 0; int n; =20 if ((n =3D virXPathNodeSet("./feature", ctxt, &nodes)) <=3D 0) return n; =20 model->removedFeatures =3D g_new0(char *, n + 1); + model->addedFeatures =3D g_new0(char *, n + 1); =20 for (i =3D 0; i < n; i++) { g_autofree char *ftname =3D NULL; virCPUx86Feature *feature; virTristateBool rem; + virTristateBool added; =20 if (!(ftname =3D virXMLPropString(nodes[i], "name"))) { virReportError(VIR_ERR_INTERNAL_ERROR, @@ -1632,10 +1648,21 @@ x86ModelParseFeatures(virCPUx86Model *model, continue; } =20 + if (virXMLPropTristateBool(nodes[i], "added", + VIR_XML_PROP_NONE, + &added) < 0) + return -1; + + if (added =3D=3D VIR_TRISTATE_BOOL_YES) { + model->addedFeatures[nadded++] =3D g_strdup(ftname); + continue; + } + x86DataAdd(&model->data, &feature->data); } =20 model->removedFeatures =3D g_renew(char *, model->removedFeatures, nre= moved + 1); + model->addedFeatures =3D g_renew(char *, model->addedFeatures, nadded = + 1); =20 return 0; } @@ -3030,11 +3057,13 @@ virCPUx86UpdateLive(virCPUDef *cpu, if (expected =3D=3D VIR_CPU_FEATURE_DISABLE && x86DataIsSubset(&enabled, &feature->data)) { VIR_DEBUG("Feature '%s' enabled by the hypervisor", feature->n= ame); - if (cpu->check =3D=3D VIR_CPU_CHECK_FULL) + if (cpu->check =3D=3D VIR_CPU_CHECK_FULL && + !g_strv_contains((const char **) model->addedFeatures, fea= ture->name)) { virBufferAsprintf(&bufAdded, "%s,", feature->name); - else if (virCPUDefUpdateFeature(cpu, feature->name, - VIR_CPU_FEATURE_REQUIRE) < 0) + } else if (virCPUDefUpdateFeature(cpu, feature->name, + VIR_CPU_FEATURE_REQUIRE) < 0= ) { return -1; + } } =20 if (x86DataIsSubset(&disabled, &feature->data) || @@ -3499,6 +3528,40 @@ virCPUx86FeatureFilterDropMSR(const char *name, } =20 =20 +/** + * virCPUx86GetAddedFeatures: + * @modelName: CPU model + * @features: where to store a pointer to the list of added features + * + * Gets a list of features added to a specified CPU model after its origin= al + * version was already released. The @features will be set to NULL if the = list + * is empty or it will point to internal structures and thus it must not be + * freed or modified by the caller. The pointer is valid for the whole lif= etime + * of the process. + * + * Returns 0 on success, -1 otherwise. + */ +int +virCPUx86GetAddedFeatures(const char *modelName, + const char * const **features) +{ + virCPUx86Map *map; + virCPUx86Model *model; + + if (!(map =3D virCPUx86GetMap())) + return -1; + + if (!(model =3D x86ModelFind(map, modelName))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("unknown CPU model %1$s"), modelName); + return -1; + } + + *features =3D (const char **) model->addedFeatures; + return 0; +} + + struct cpuArchDriver cpuDriverX86 =3D { .name =3D "x86", .arch =3D archs, diff --git a/src/cpu/cpu_x86.h b/src/cpu/cpu_x86.h index 2721fc9097..2cd965fea4 100644 --- a/src/cpu/cpu_x86.h +++ b/src/cpu/cpu_x86.h @@ -48,3 +48,6 @@ bool virCPUx86FeatureFilterSelectMSR(const char *name, bool virCPUx86FeatureFilterDropMSR(const char *name, virCPUFeaturePolicy policy, void *opaque); + +int virCPUx86GetAddedFeatures(const char *modelName, + const char * const **features); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 887659784a..98a925933e 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1544,6 +1544,7 @@ virCPUx86DataSetSignature; virCPUx86DataSetVendor; virCPUx86FeatureFilterDropMSR; virCPUx86FeatureFilterSelectMSR; +virCPUx86GetAddedFeatures; =20 # datatypes.h virConnectClass; --=20 2.44.0 _______________________________________________ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-leave@lists.libvirt.org From nobody Wed May 15 11:17:08 2024 Delivered-To: importer@patchew.org Received-SPF: none (zohomail.com: 8.43.85.245 is neither permitted nor denied by domain of lists.libvirt.org) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; spf=none (zohomail.com: 8.43.85.245 is neither permitted nor denied by domain of lists.libvirt.org) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1710263459565167.40638054958026; Tue, 12 Mar 2024 10:10:59 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 72B6619E9; Tue, 12 Mar 2024 13:10:58 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 520DC1E8F; Tue, 12 Mar 2024 13:07:21 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id D9F681A74; Tue, 12 Mar 2024 13:07:11 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 36BD01A98 for ; Tue, 12 Mar 2024 13:07:09 -0400 (EDT) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-8-MmrFqBAtOWKREC1OOlkEkA-1; Tue, 12 Mar 2024 13:07:07 -0400 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 24F258007AB for ; Tue, 12 Mar 2024 17:07:07 +0000 (UTC) Received: from orkuz (unknown [10.45.224.148]) by smtp.corp.redhat.com (Postfix) with ESMTP id DD6AF1C060CE for ; Tue, 12 Mar 2024 17:07:06 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.4 X-MC-Unique: MmrFqBAtOWKREC1OOlkEkA-1 From: Jiri Denemark To: devel@lists.libvirt.org Subject: [PATCH 02/22] qemu: domain: Check arch in qemuDomainMakeCPUMigratable Date: Tue, 12 Mar 2024 18:06:42 +0100 Message-ID: <413c7b8d6e52c6dcdada845798a133f152af55bb.1710262622.git.jdenemar@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.7 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Message-ID-Hash: BQOWY4GU7PGLCFALAIH5JJLQ62H26SQ3 X-Message-ID-Hash: BQOWY4GU7PGLCFALAIH5JJLQ62H26SQ3 X-MailFrom: jdenemar@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1710263460059100001 The content is arch specific and checking for Icelake-Server CPU model on non-x86 architectures does not make sense. Signed-off-by: Jiri Denemark Reviewed-by: Peter Krempa --- src/qemu/qemu_domain.c | 14 ++++++++++---- src/qemu/qemu_domain.h | 3 ++- src/qemu/qemu_migration_cookie.c | 2 +- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 8c85446c3d..31a6509166 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -6644,10 +6644,15 @@ qemuDomainDefCopy(virQEMUDriver *driver, =20 =20 int -qemuDomainMakeCPUMigratable(virCPUDef *cpu) +qemuDomainMakeCPUMigratable(virArch arch, + virCPUDef *cpu) { - if (cpu->mode =3D=3D VIR_CPU_MODE_CUSTOM && - STREQ_NULLABLE(cpu->model, "Icelake-Server")) { + if (cpu->mode !=3D VIR_CPU_MODE_CUSTOM || + !cpu->model || + !ARCH_IS_X86(arch)) + return 0; + + if (STREQ(cpu->model, "Icelake-Server")) { /* Originally Icelake-Server CPU model contained pconfig CPU featu= re. * It was never actually enabled and thus it was removed. To enable * migration to QEMU 3.1.0 (with both new and old libvirt), we @@ -6837,7 +6842,8 @@ qemuDomainDefFormatBufInternal(virQEMUDriver *driver, return -1; } =20 - if (def->cpu && qemuDomainMakeCPUMigratable(def->cpu) < 0) + if (def->cpu && + qemuDomainMakeCPUMigratable(def->os.arch, def->cpu) < 0) return -1; =20 /* Old libvirt doesn't understand