From nobody Mon Feb 9 05:22:46 2026 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 1714399920219407.1962587039942; Mon, 29 Apr 2024 07:12:00 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 3A0482368; Mon, 29 Apr 2024 10:11:59 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 1E3912263; Mon, 29 Apr 2024 10:03:17 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 8E96A1DA9; Mon, 29 Apr 2024 10:03:01 -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 9AABB1DC2 for ; Mon, 29 Apr 2024 10:03:00 -0400 (EDT) Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-2-vUKhS_77O2SmgxOziz9FmA-1; Mon, 29 Apr 2024 10:02:57 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) (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 59DC83C12823 for ; Mon, 29 Apr 2024 14:02:54 +0000 (UTC) Received: from orkuz (unknown [10.43.3.115]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1F8B140C6CB1 for ; Mon, 29 Apr 2024 14:02:54 +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.7 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 autolearn=unavailable autolearn_force=no version=3.4.4 X-MC-Unique: vUKhS_77O2SmgxOziz9FmA-1 From: Jiri Denemark To: devel@lists.libvirt.org Subject: [PATCH 3/4] qemu: Enable removing features from CPU models Date: Mon, 29 Apr 2024 16:02:47 +0200 Message-ID: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.2 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Message-ID-Hash: G2ABOQBWPPT3EA3RE7WHIWMCO2773BZX X-Message-ID-Hash: G2ABOQBWPPT3EA3RE7WHIWMCO2773BZX 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: 1714399921024100001 Features removed from a CPU model are marked with "removed=3D'yes'" attribute in the CPU map. Such features will always be present in a CPU definition produced by libvirt regardless on their state. In other words a running domain (even saved in a file) will always explicitly contain states of all features removed from the specified CPU model. This enables migration to older libvirt which would otherwise think the affected features should be enabled as they are still included in the CPU model in the older version of CPU map. Migration from an old libvirt to a new one would be broken as the new libvirt would think the removed features should be disabled (because they are not included in the CPU model anymore), which might not be the case on the source host. Thus we were refusing to remove CPU features unless they were never working and no domain could even be running with those features enabled. This patch removes the limitation. When handling CPU definitions with missing features marked as removed in the specified CPU model, we know whether it comes from a running domain, in which case it must have been created by older libvirt where the missing CPU features were not removed yet. This means the features must have been enabled on the source and we can automatically fix the definition by adding the missing features with correct states. We can safely remove any CPU feature from our CPU models now, but it should only be used for features removed from all versions of a given CPU model in QEMU because unversioned models correspond to v1. Signed-off-by: Jiri Denemark --- src/qemu/qemu_process.c | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index d5c5342966..d0f8176b2c 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -6270,6 +6270,7 @@ qemuProcessUpdateGuestCPU(virDomainDef *def, if (def->cpu->mode !=3D VIR_CPU_MODE_HOST_PASSTHROUGH && def->cpu->mode !=3D VIR_CPU_MODE_MAXIMUM) { g_autoptr(virDomainCapsCPUModels) cpuModels =3D NULL; + virCPUFeaturePolicy removedPolicy =3D VIR_CPU_FEATURE_DISABLE; =20 if (def->cpu->check =3D=3D VIR_CPU_CHECK_PARTIAL && !virQEMUCapsIsCPUUsable(qemuCaps, def->virtType, def->cpu) && @@ -6279,10 +6280,22 @@ qemuProcessUpdateGuestCPU(virDomainDef *def, def->cpu, true) < 0) return -1; =20 + /* When starting a fresh domain we disable all features removed fr= om + * the specified CPU model to make sure they are only used if + * explicitly requested. But when we are restoring a previously ru= nning + * domain (migration, snapshot, ...) all removed features were alr= eady + * explicitly listed in the CPU definition and if we found a remov= ed + * feature which is missing it must have been removed later and mu= st be + * enabled rather than disabled here match the state described by = older + * libvirt. + */ + if (!(flags & VIR_QEMU_PROCESS_START_NEW)) + removedPolicy =3D VIR_CPU_FEATURE_REQUIRE; + if (virCPUUpdate(def->os.arch, def->cpu, virQEMUCapsGetHostModel(qemuCaps, def->virtType, VIR_QEMU_CAPS_HOST_CPU_MI= GRATABLE), - VIR_CPU_FEATURE_DISABLE) < 0) + removedPolicy) < 0) return -1; =20 cpuModels =3D virQEMUCapsGetCPUModels(qemuCaps, def->virtType, NUL= L, NULL); @@ -8877,13 +8890,27 @@ qemuProcessRefreshCPU(virQEMUDriver *driver, g_autoptr(virCPUDef) host =3D NULL; g_autoptr(virCPUDef) hostmig =3D NULL; g_autoptr(virCPUDef) cpu =3D NULL; + virCPUFeaturePolicy removedPolicy; =20 - if (!virQEMUCapsGuestIsNative(driver->hostarch, vm->def->os.arch)) - return 0; + /* When reconnecting to a running domain, we know all features marked = as + * removed from a CPU model were already explicitly mentioned in the + * definition. If any removed features are missing, they must have been + * removed after the domain was started and thus they have to be enabl= ed + * (otherwise they would be explicitly listed as disabled). + */ + removedPolicy =3D VIR_CPU_FEATURE_REQUIRE; =20 if (!vm->def->cpu) return 0; =20 + if (vm->def->cpu->mode =3D=3D VIR_CPU_MODE_CUSTOM && + vm->def->cpu->model && + virCPUUpdate(vm->def->os.arch, vm->def->cpu, NULL, removedPolicy) = < 0) + return -1; + + if (!virQEMUCapsGuestIsNative(driver->hostarch, vm->def->os.arch)) + return 0; + if (qemuProcessRefreshCPUMigratability(vm, VIR_ASYNC_JOB_NONE) < 0) return -1; =20 @@ -8915,8 +8942,7 @@ qemuProcessRefreshCPU(virQEMUDriver *driver, virCPUDefCopyModelFilter(cpu, hostmig, false, virQEMUCapsCPUFilter= Features, &host->arch); =20 - if (virCPUUpdate(vm->def->os.arch, vm->def->cpu, cpu, - VIR_CPU_FEATURE_DISABLE) < 0) + if (virCPUUpdate(vm->def->os.arch, vm->def->cpu, cpu, removedPolic= y) < 0) return -1; =20 if (qemuProcessUpdateCPU(vm, VIR_ASYNC_JOB_NONE) < 0) --=20 2.44.0 _______________________________________________ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-leave@lists.libvirt.org