diff --git a/libvirt-Add-VIR_MIGRATE_ZEROCOPY-flag.patch b/libvirt-Add-VIR_MIGRATE_ZEROCOPY-flag.patch new file mode 100644 index 0000000..b65e479 --- /dev/null +++ b/libvirt-Add-VIR_MIGRATE_ZEROCOPY-flag.patch @@ -0,0 +1,49 @@ +From 9c2fd182a02d64004e30900c52e3fcdb550de0bd Mon Sep 17 00:00:00 2001 +Message-Id: <9c2fd182a02d64004e30900c52e3fcdb550de0bd@dist-git> +From: Jiri Denemark +Date: Wed, 22 Jun 2022 16:35:50 +0200 +Subject: [PATCH] Add VIR_MIGRATE_ZEROCOPY flag +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The flag can be used to enable zero-copy mechanism for migrating memory +pages. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 8744beecb36600e773c8a8c4823db2bf4b3e262d) + +https://bugzilla.redhat.com/show_bug.cgi?id=2089433 + +Conflicts: + include/libvirt/libvirt-domain.h + - post-copy recovery not backported + +Signed-off-by: Jiri Denemark +--- + include/libvirt/libvirt-domain.h | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h +index 5f0a9b7572..792973ce2d 100644 +--- a/include/libvirt/libvirt-domain.h ++++ b/include/libvirt/libvirt-domain.h +@@ -860,6 +860,14 @@ typedef enum { + */ + VIR_MIGRATE_NON_SHARED_SYNCHRONOUS_WRITES = (1 << 18), + ++ /* Use zero-copy mechanism for migrating memory pages. For QEMU/KVM this ++ * means QEMU will be temporarily allowed to lock all guest pages in host's ++ * memory, although only those that are queued for transfer will be locked ++ * at the same time. ++ * ++ * Since: 8.5.0 ++ */ ++ VIR_MIGRATE_ZEROCOPY = (1 << 20), + } virDomainMigrateFlags; + + +-- +2.35.1 + diff --git a/libvirt-RHEL-qemu_migration-Fix-restoring-memlock-limit-on-destination.patch b/libvirt-RHEL-qemu_migration-Fix-restoring-memlock-limit-on-destination.patch new file mode 100644 index 0000000..985f693 --- /dev/null +++ b/libvirt-RHEL-qemu_migration-Fix-restoring-memlock-limit-on-destination.patch @@ -0,0 +1,52 @@ +From b6c1f9ca8eb0ca8f7603ab205c7dc95b9f07b5a0 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Mon, 18 Jul 2022 16:01:20 +0200 +Subject: [PATCH] RHEL: qemu_migration: Fix restoring memlock limit on + destination + +Restoring memory locking limit on the destination host only makes sense +when migration succeeded as otherwise the QEMU process will be killed +anyway. Specifically if the migration fails because the process died, +touching the limit would produce rather unhelpful error message instead +of the real issue: + + cannot get locked memory limit of process -1: No such file or + directory + +This patch is RHEL-only caused by misplacing the call to +qemuDomainSetMaxMemLock when the "qemu_migration: Restore original +memory locking limit" upstream patch was backported to an older code +base. + +https://bugzilla.redhat.com/show_bug.cgi?id=2107954 + +Signed-off-by: Jiri Denemark +--- + src/qemu/qemu_migration.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c +index db5163e993..11f87296d6 100644 +--- a/src/qemu/qemu_migration.c ++++ b/src/qemu/qemu_migration.c +@@ -5895,6 +5895,8 @@ qemuMigrationDstFinish(virQEMUDriver *driver, + */ + if (inPostCopy) + g_clear_pointer(&priv->job.completed, qemuDomainJobInfoFree); ++ ++ qemuDomainSetMaxMemLock(vm, 0, &priv->preMigrationMemlock); + } + + qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN, +@@ -5907,7 +5909,6 @@ qemuMigrationDstFinish(virQEMUDriver *driver, + cleanup: + g_clear_pointer(&jobInfo, qemuDomainJobInfoFree); + virPortAllocatorRelease(port); +- qemuDomainSetMaxMemLock(vm, 0, &priv->preMigrationMemlock); + if (priv->mon) + qemuMonitorSetDomainLog(priv->mon, NULL, NULL, NULL); + VIR_FREE(priv->origname); +-- +2.35.1 + diff --git a/libvirt-build-Only-install-libvirt-guests-when-building-libvirtd.patch b/libvirt-build-Only-install-libvirt-guests-when-building-libvirtd.patch new file mode 100644 index 0000000..c02569a --- /dev/null +++ b/libvirt-build-Only-install-libvirt-guests-when-building-libvirtd.patch @@ -0,0 +1,75 @@ +From b0fb5cbba2e03fbca8471487bf78931b3090b108 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jim Fehlig +Date: Mon, 10 Jan 2022 11:42:58 -0700 +Subject: [PATCH] build: Only install libvirt-guests when building libvirtd + +libvirt-guests was already moved to the libvirt daemon package in commit +d800c50349. It only needs to be installed when building libvirtd. + +Signed-off-by: Jim Fehlig +Reviewed-by: Andrea Bolognani +(cherry picked from commit 3be5ba11a2c6fcb2dfdffa03ab4f847113f36b85) +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2153688 +Signed-off-by: Michal Privoznik +--- + tools/meson.build | 38 ++++++++++++++++++++------------------ + 1 file changed, 20 insertions(+), 18 deletions(-) + +diff --git a/tools/meson.build b/tools/meson.build +index 22fa3604ba..2d0aecb90b 100644 +--- a/tools/meson.build ++++ b/tools/meson.build +@@ -297,29 +297,31 @@ if conf.has('WITH_SANLOCK') + ) + endif + +-configure_file( +- input: 'libvirt-guests.sh.in', +- output: '@BASENAME@', +- configuration: tools_conf, +- install: true, +- install_dir: libexecdir, +- install_mode: 'rwxrwxr-x', +-) +- +-if init_script == 'systemd' +- install_data( +- 'libvirt-guests.sysconf', +- install_dir: sysconfdir / 'sysconfig', +- rename: 'libvirt-guests', +- ) +- ++if conf.has('WITH_LIBVIRTD') + configure_file( +- input: 'libvirt-guests.service.in', ++ input: 'libvirt-guests.sh.in', + output: '@BASENAME@', + configuration: tools_conf, + install: true, +- install_dir: prefix / 'lib' / 'systemd' / 'system', ++ install_dir: libexecdir, ++ install_mode: 'rwxrwxr-x', + ) ++ ++ if init_script == 'systemd' ++ install_data( ++ 'libvirt-guests.sysconf', ++ install_dir: sysconfdir / 'sysconfig', ++ rename: 'libvirt-guests', ++ ) ++ ++ configure_file( ++ input: 'libvirt-guests.service.in', ++ output: '@BASENAME@', ++ configuration: tools_conf, ++ install: true, ++ install_dir: prefix / 'lib' / 'systemd' / 'system', ++ ) ++ endif + endif + + if bash_completion_dep.found() +-- +2.39.0 + diff --git a/libvirt-conf-Move-virDomainObj-originalMemlock-into-qemuDomainObjPrivate.patch b/libvirt-conf-Move-virDomainObj-originalMemlock-into-qemuDomainObjPrivate.patch new file mode 100644 index 0000000..4edd02b --- /dev/null +++ b/libvirt-conf-Move-virDomainObj-originalMemlock-into-qemuDomainObjPrivate.patch @@ -0,0 +1,91 @@ +From 00c5cab2b92b653edbf491d9ef60359578c3d59a Mon Sep 17 00:00:00 2001 +Message-Id: <00c5cab2b92b653edbf491d9ef60359578c3d59a@dist-git> +From: Michal Privoznik +Date: Wed, 11 May 2022 16:27:18 +0200 +Subject: [PATCH] conf: Move virDomainObj::originalMemlock into + qemuDomainObjPrivate + +Since v1.3.0-90-gafbe1d4c56 the original value of memlock limit +is stored inside virDomainObj struct directly (under +originalMemlock member). This is needless because the value is +used only inside QEMU driver and thus can reside in +qemuDomainObjPrivate struct. + +Signed-off-by: Michal Privoznik +Reviewed-by: Peter Krempa +(cherry picked from commit 75df6d2c291c48d65c1e54dd93e3d2d3cb0712e7) + +https://bugzilla.redhat.com/show_bug.cgi?id=2089433 + +Signed-off-by: Jiri Denemark +--- + src/conf/domain_conf.h | 3 --- + src/qemu/qemu_domain.c | 9 +++++---- + src/qemu/qemu_domain.h | 3 +++ + 3 files changed, 8 insertions(+), 7 deletions(-) + +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index d0d0fdc815..45976beb2b 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -3031,9 +3031,6 @@ struct _virDomainObj { + int taint; + size_t ndeprecations; + char **deprecations; +- +- unsigned long long originalMemlock; /* Original RLIMIT_MEMLOCK, zero if no +- * restore will be required later */ + }; + + G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainObj, virObjectUnref); +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index 40fe9985e6..86d673dafa 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -9269,6 +9269,7 @@ int + qemuDomainAdjustMaxMemLock(virDomainObj *vm, + bool forceVFIO) + { ++ qemuDomainObjPrivate *priv = vm->privateData; + unsigned long long currentMemLock = 0; + unsigned long long desiredMemLock = 0; + +@@ -9281,8 +9282,8 @@ qemuDomainAdjustMaxMemLock(virDomainObj *vm, + /* If this is the first time adjusting the limit, save the current + * value so that we can restore it once memory locking is no longer + * required */ +- if (vm->originalMemlock == 0) { +- vm->originalMemlock = currentMemLock; ++ if (priv->originalMemlock == 0) { ++ priv->originalMemlock = currentMemLock; + } + } else { + /* If the limit is already high enough, we can assume +@@ -9295,8 +9296,8 @@ qemuDomainAdjustMaxMemLock(virDomainObj *vm, + } else { + /* Once memory locking is no longer required, we can restore the + * original, usually very low, limit */ +- desiredMemLock = vm->originalMemlock; +- vm->originalMemlock = 0; ++ desiredMemLock = priv->originalMemlock; ++ priv->originalMemlock = 0; + } + + if (desiredMemLock > 0 && +diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h +index e5046367e3..e9497d20de 100644 +--- a/src/qemu/qemu_domain.h ++++ b/src/qemu/qemu_domain.h +@@ -241,6 +241,9 @@ struct _qemuDomainObjPrivate { + GSList *dbusVMStateIds; + /* true if -object dbus-vmstate was added */ + bool dbusVMState; ++ ++ unsigned long long originalMemlock; /* Original RLIMIT_MEMLOCK, zero if no ++ * restore will be required later */ + }; + + #define QEMU_DOMAIN_PRIVATE(vm) \ +-- +2.35.1 + diff --git a/libvirt-conf-virtiofs-add-thread_pool-element.patch b/libvirt-conf-virtiofs-add-thread_pool-element.patch new file mode 100644 index 0000000..e03c66d --- /dev/null +++ b/libvirt-conf-virtiofs-add-thread_pool-element.patch @@ -0,0 +1,151 @@ +From 0c09e4225c511ce1b0ebe22e45962f83d5145e66 Mon Sep 17 00:00:00 2001 +Message-Id: <0c09e4225c511ce1b0ebe22e45962f83d5145e66@dist-git> +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +Date: Fri, 10 Jun 2022 15:10:29 +0200 +Subject: [PATCH] conf: virtiofs: add thread_pool element +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add an element to configure the thread pool size: + +... + + + +... + +https://bugzilla.redhat.com/show_bug.cgi?id=2072905 + +Signed-off-by: Ján Tomko +Reviewed-by: Michal Privoznik +(cherry picked from commit 0df2e7df80452f81edbfeb0ee355235b533346a9) +Signed-off-by: Ján Tomko + +https://bugzilla.redhat.com/show_bug.cgi?id=2079582 +--- + docs/formatdomain.rst | 6 ++++++ + docs/schemas/domaincommon.rng | 9 +++++++++ + src/conf/domain_conf.c | 15 +++++++++++++++ + src/conf/domain_conf.h | 1 + + .../qemuxml2argvdata/vhost-user-fs-fd-memory.xml | 1 + + 5 files changed, 32 insertions(+) + +diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst +index 17e89a0c0d..e6cf2ec083 100644 +--- a/docs/formatdomain.rst ++++ b/docs/formatdomain.rst +@@ -3316,6 +3316,7 @@ A directory on the host that can be accessed directly from the guest. + + + ++ + + + +@@ -3449,6 +3450,11 @@ A directory on the host that can be accessed directly from the guest. + ``chroot``, see the + `virtiofsd documentation `__ + for more details. ( :since:`Since 7.2.0` ) ++ Element ``thread_pool`` accepts one attribute ``size`` which defines the ++ maximum thread pool size. A value of "0" disables the pool. ++ The thread pool helps increase the number of requests in flight when used with ++ storage that has a higher latency. However, it has an overhead, and so for ++ fast, low latency filesystems, it may be best to turn it off. ( :since:`Since 8.5.0` ) + ``source`` + The resource on the host that is being accessed in the guest. The ``name`` + attribute must be used with ``type='template'``, and the ``dir`` attribute +diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng +index c9c1529979..79c8979410 100644 +--- a/docs/schemas/domaincommon.rng ++++ b/docs/schemas/domaincommon.rng +@@ -3064,6 +3064,15 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 92510973e6..95afd9226e 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -2447,6 +2447,8 @@ virDomainFSDefNew(virDomainXMLOption *xmlopt) + + ret->src = virStorageSourceNew(); + ++ ret->thread_pool_size = -1; ++ + if (xmlopt && + xmlopt->privateData.fsNew && + !(ret->privateData = xmlopt->privateData.fsNew())) +@@ -9869,6 +9871,7 @@ virDomainFSDefParseXML(virDomainXMLOption *xmlopt, + if (def->fsdriver == VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS) { + g_autofree char *queue_size = virXPathString("string(./driver/@queue)", ctxt); + g_autofree char *binary = virXPathString("string(./binary/@path)", ctxt); ++ g_autofree char *thread_pool_size = virXPathString("string(./binary/thread_pool/@size)", ctxt); + g_autofree char *xattr = virXPathString("string(./binary/@xattr)", ctxt); + g_autofree char *cache = virXPathString("string(./binary/cache/@mode)", ctxt); + g_autofree char *sandbox = virXPathString("string(./binary/sandbox/@mode)", ctxt); +@@ -9883,6 +9886,14 @@ virDomainFSDefParseXML(virDomainXMLOption *xmlopt, + goto error; + } + ++ if (thread_pool_size && ++ virStrToLong_i(thread_pool_size, NULL, 10, &def->thread_pool_size) < 0) { ++ virReportError(VIR_ERR_XML_ERROR, ++ _("cannot parse thread pool size '%s' for virtiofs"), ++ queue_size); ++ goto error; ++ } ++ + if (binary) + def->binary = virFileSanitizePath(binary); + +@@ -24205,6 +24216,10 @@ virDomainFSDefFormat(virBuffer *buf, + } + + virXMLFormatElement(&binaryBuf, "lock", &lockAttrBuf, NULL); ++ ++ if (def->thread_pool_size >= 0) ++ virBufferAsprintf(&binaryBuf, "\n", def->thread_pool_size); ++ + } + + virDomainVirtioOptionsFormat(&driverAttrBuf, def->virtio); +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index 10af94e2e4..d0d0fdc815 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -892,6 +892,7 @@ struct _virDomainFSDef { + virTristateSwitch posix_lock; + virTristateSwitch flock; + virDomainFSSandboxMode sandbox; ++ int thread_pool_size; + virDomainVirtioOptions *virtio; + virObject *privateData; + }; +diff --git a/tests/qemuxml2argvdata/vhost-user-fs-fd-memory.xml b/tests/qemuxml2argvdata/vhost-user-fs-fd-memory.xml +index abddf0870b..81de8c0dd7 100644 +--- a/tests/qemuxml2argvdata/vhost-user-fs-fd-memory.xml ++++ b/tests/qemuxml2argvdata/vhost-user-fs-fd-memory.xml +@@ -32,6 +32,7 @@ + + + ++ + + + +-- +2.35.1 + diff --git a/libvirt-cpu_map-Disable-cpu64-rhel-for-host-model-and-baseline.patch b/libvirt-cpu_map-Disable-cpu64-rhel-for-host-model-and-baseline.patch new file mode 100644 index 0000000..7711d3b --- /dev/null +++ b/libvirt-cpu_map-Disable-cpu64-rhel-for-host-model-and-baseline.patch @@ -0,0 +1,60 @@ +From 46f4cfe513f0f893c862dca7f02ed7d7932b2115 Mon Sep 17 00:00:00 2001 +Message-Id: <46f4cfe513f0f893c862dca7f02ed7d7932b2115@dist-git> +From: Jiri Denemark +Date: Tue, 26 Apr 2022 12:50:41 +0200 +Subject: [PATCH] cpu_map: Disable cpu64-rhel* for host-model and baseline + +These ancient RHEL-only CPU models should not really be used by any CPU +definition created by libvirt. We keep them just for backwards +compatibility with domains which might still be using them. + +Signed-off-by: Jiri Denemark +Reviewed-by: Michal Privoznik +(cherry picked from commit d2e4d66be35cd04da72e5f5129a8a4da6a931505) + +https://bugzilla.redhat.com/show_bug.cgi?id=1851227 + +Signed-off-by: Jiri Denemark +--- + src/cpu_map/x86_cpu64-rhel5.xml | 2 +- + src/cpu_map/x86_cpu64-rhel6.xml | 2 +- + tests/cputestdata/x86_64-baseline-no-vendor-result.xml | 3 ++- + 3 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/cpu_map/x86_cpu64-rhel5.xml b/src/cpu_map/x86_cpu64-rhel5.xml +index be6bcdb7a6..7402b7603c 100644 +--- a/src/cpu_map/x86_cpu64-rhel5.xml ++++ b/src/cpu_map/x86_cpu64-rhel5.xml +@@ -1,6 +1,6 @@ + + +- ++ + + + +diff --git a/src/cpu_map/x86_cpu64-rhel6.xml b/src/cpu_map/x86_cpu64-rhel6.xml +index c62b1b5575..061939c733 100644 +--- a/src/cpu_map/x86_cpu64-rhel6.xml ++++ b/src/cpu_map/x86_cpu64-rhel6.xml +@@ -1,6 +1,6 @@ + + +- ++ + + + +diff --git a/tests/cputestdata/x86_64-baseline-no-vendor-result.xml b/tests/cputestdata/x86_64-baseline-no-vendor-result.xml +index 00e03b2152..4b4921cf93 100644 +--- a/tests/cputestdata/x86_64-baseline-no-vendor-result.xml ++++ b/tests/cputestdata/x86_64-baseline-no-vendor-result.xml +@@ -1,3 +1,4 @@ + +- cpu64-rhel6 ++ kvm64 ++ + +-- +2.35.1 + diff --git a/libvirt-cpu_x86-Consolidate-signature-match-in-x86DecodeUseCandidate.patch b/libvirt-cpu_x86-Consolidate-signature-match-in-x86DecodeUseCandidate.patch new file mode 100644 index 0000000..2e9660e --- /dev/null +++ b/libvirt-cpu_x86-Consolidate-signature-match-in-x86DecodeUseCandidate.patch @@ -0,0 +1,75 @@ +From 99a298a4a0575bf0072f504c4b8e4551400c44c0 Mon Sep 17 00:00:00 2001 +Message-Id: <99a298a4a0575bf0072f504c4b8e4551400c44c0@dist-git> +From: Jiri Denemark +Date: Tue, 26 Apr 2022 11:58:07 +0200 +Subject: [PATCH] cpu_x86: Consolidate signature match in x86DecodeUseCandidate + +Checking the signature in two different places makes no sense since the +code in between can only mark the candidate as the best option so far, +which is what the second signature match does as well. + +Signed-off-by: Jiri Denemark +Reviewed-by: Michal Privoznik +(cherry picked from commit 35ce086667e68e8f546cf36473591dd7c19c72eb) + +https://bugzilla.redhat.com/show_bug.cgi?id=1851227 + +Signed-off-by: Jiri Denemark +--- + src/cpu/cpu_x86.c | 31 ++++++++++++++----------------- + 1 file changed, 14 insertions(+), 17 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index 5cb9caef8a..f007487824 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -2020,15 +2020,22 @@ x86DecodeUseCandidate(virCPUx86Model *current, + } + + /* Ideally we want to select a model with family/model equal to +- * family/model of the real CPU. Once we found such model, we only ++ * family/model of the real CPU and once we found such model, we only + * consider candidates with matching family/model. + */ +- if (signature && +- virCPUx86SignaturesMatch(current->signatures, signature) && +- !virCPUx86SignaturesMatch(candidate->signatures, signature)) { +- VIR_DEBUG("%s differs in signature from matching %s", +- cpuCandidate->model, cpuCurrent->model); +- return 0; ++ if (signature) { ++ if (virCPUx86SignaturesMatch(current->signatures, signature) && ++ !virCPUx86SignaturesMatch(candidate->signatures, signature)) { ++ VIR_DEBUG("%s differs in signature from matching %s", ++ cpuCandidate->model, cpuCurrent->model); ++ return 0; ++ } ++ ++ if (!virCPUx86SignaturesMatch(current->signatures, signature) && ++ virCPUx86SignaturesMatch(candidate->signatures, signature)) { ++ VIR_DEBUG("%s provides matching signature", cpuCandidate->model); ++ return 1; ++ } + } + + if (cpuCurrent->nfeatures > cpuCandidate->nfeatures) { +@@ -2037,16 +2044,6 @@ x86DecodeUseCandidate(virCPUx86Model *current, + return 1; + } + +- /* Prefer a candidate with matching signature even though it would +- * result in longer list of features. +- */ +- if (signature && +- virCPUx86SignaturesMatch(candidate->signatures, signature) && +- !virCPUx86SignaturesMatch(current->signatures, signature)) { +- VIR_DEBUG("%s provides matching signature", cpuCandidate->model); +- return 1; +- } +- + VIR_DEBUG("%s does not result in shorter feature list than %s", + cpuCandidate->model, cpuCurrent->model); + return 0; +-- +2.35.1 + diff --git a/libvirt-cpu_x86-Ignore-enabled-features-for-input-models-in-x86DecodeUseCandidate.patch b/libvirt-cpu_x86-Ignore-enabled-features-for-input-models-in-x86DecodeUseCandidate.patch new file mode 100644 index 0000000..e1b8a79 --- /dev/null +++ b/libvirt-cpu_x86-Ignore-enabled-features-for-input-models-in-x86DecodeUseCandidate.patch @@ -0,0 +1,272 @@ +From 752c74eeae67d41e7550991cb3bbe289984ec9d3 Mon Sep 17 00:00:00 2001 +Message-Id: <752c74eeae67d41e7550991cb3bbe289984ec9d3@dist-git> +From: Jiri Denemark +Date: Fri, 29 Apr 2022 10:35:02 +0200 +Subject: [PATCH] cpu_x86: Ignore enabled features for input models in + x86DecodeUseCandidate + +While we don't want to aim for the shortest list of disabled features in +the baseline result (it would select a very old model), we want to do so +while looking at any of the input models for which we're trying to +compute a baseline CPU model. Given a set of input models, we always +want to take the least capable one of them (i.e., the one with shortest +list of disabled features) or a better model which is not one of the +input models. + +So when considering an input model, we just check whether its list of +disabled features is shorter than the currently best one. When looking +at other models we check both enabled and disabled features while +penalizing disabled features as implemented by the previous patch. + +Signed-off-by: Jiri Denemark +Reviewed-by: Michal Privoznik +(cherry picked from commit bb6cedd2082599323257ee0df18c93a6e0551b0b) + +https://bugzilla.redhat.com/show_bug.cgi?id=1851227 + +Signed-off-by: Jiri Denemark +--- + src/cpu/cpu_x86.c | 66 ++++++++++++------- + ...4-baseline-Westmere+Nehalem-migratable.xml | 8 ++- + ...86_64-baseline-Westmere+Nehalem-result.xml | 8 ++- + ...-cpuid-baseline-Cooperlake+Cascadelake.xml | 13 ++-- + 4 files changed, 64 insertions(+), 31 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index ebcd96edb1..7b59dad8bf 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -1975,7 +1975,8 @@ virCPUx86Compare(virCPUDef *host, + + static int + virCPUx86CompareCandidateFeatureList(virCPUDef *cpuCurrent, +- virCPUDef *cpuCandidate) ++ virCPUDef *cpuCandidate, ++ bool isPreferred) + { + size_t current = cpuCurrent->nfeatures; + size_t enabledCurrent = current; +@@ -2017,6 +2018,14 @@ virCPUx86CompareCandidateFeatureList(virCPUDef *cpuCurrent, + return 1; + } + ++ if (isPreferred && disabled < disabledCurrent) { ++ VIR_DEBUG("%s is in the list of preferred models and provides fewer " ++ "disabled features than %s: %zu < %zu", ++ cpuCandidate->model, cpuCurrent->model, ++ disabled, disabledCurrent); ++ return 1; ++ } ++ + VIR_DEBUG("%s is not better than %s: %zu (%zu, %zu) >= %zu (%zu, %zu)", + cpuCandidate->model, cpuCurrent->model, + candidate, enabled, disabled, +@@ -2039,8 +2048,10 @@ x86DecodeUseCandidate(virCPUx86Model *current, + virCPUx86Model *candidate, + virCPUDef *cpuCandidate, + uint32_t signature, +- const char *preferred) ++ const char **preferred) + { ++ bool isPreferred = false; ++ + if (cpuCandidate->type == VIR_CPU_TYPE_HOST && + !candidate->decodeHost) { + VIR_DEBUG("%s is not supposed to be used for host CPU definition", +@@ -2064,9 +2075,13 @@ x86DecodeUseCandidate(virCPUx86Model *current, + } + } + +- if (preferred && STREQ(cpuCandidate->model, preferred)) { +- VIR_DEBUG("%s is the preferred model", cpuCandidate->model); +- return 2; ++ if (preferred) { ++ isPreferred = g_strv_contains(preferred, cpuCandidate->model); ++ ++ if (isPreferred && !preferred[1]) { ++ VIR_DEBUG("%s is the preferred model", cpuCandidate->model); ++ return 2; ++ } + } + + if (!cpuCurrent) { +@@ -2093,7 +2108,8 @@ x86DecodeUseCandidate(virCPUx86Model *current, + } + } + +- return virCPUx86CompareCandidateFeatureList(cpuCurrent, cpuCandidate); ++ return virCPUx86CompareCandidateFeatureList(cpuCurrent, cpuCandidate, ++ isPreferred); + } + + +@@ -2136,7 +2152,7 @@ static int + x86Decode(virCPUDef *cpu, + const virCPUx86Data *cpuData, + virDomainCapsCPUModels *models, +- const char *preferred, ++ const char **preferred, + bool migratable) + { + virCPUx86Map *map; +@@ -2169,6 +2185,9 @@ x86Decode(virCPUDef *cpu, + + x86DataFilterTSX(&data, vendor, map); + ++ if (preferred && !preferred[0]) ++ preferred = NULL; ++ + /* Walk through the CPU models in reverse order to check newest + * models first. + */ +@@ -2176,16 +2195,18 @@ x86Decode(virCPUDef *cpu, + candidate = map->models[i]; + if (models && + !(hvModel = virDomainCapsCPUModelsGet(models, candidate->name))) { +- if (preferred && STREQ(candidate->name, preferred)) { ++ if (preferred && ++ !preferred[1] && ++ STREQ(candidate->name, preferred[0])) { + if (cpu->fallback != VIR_CPU_FALLBACK_ALLOW) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("CPU model %s is not supported by hypervisor"), +- preferred); ++ preferred[0]); + return -1; + } else { + VIR_WARN("Preferred CPU model %s not allowed by" + " hypervisor; closest supported model will be" +- " used", preferred); ++ " used", preferred[0]); + } + } else { + VIR_DEBUG("CPU model %s not allowed by hypervisor; ignoring", +@@ -2793,8 +2814,8 @@ virCPUx86Baseline(virCPUDef **cpus, + size_t i; + virCPUx86Vendor *vendor = NULL; + bool outputVendor = true; +- const char *modelName; +- bool matchingNames = true; ++ g_autofree char **modelNames = NULL; ++ size_t namesLen = 0; + g_autoptr(virCPUData) featData = NULL; + + if (!(map = virCPUx86GetMap())) +@@ -2816,19 +2837,17 @@ virCPUx86Baseline(virCPUDef **cpus, + return NULL; + } + +- modelName = cpus[0]->model; ++ modelNames = g_new0(char *, ncpus + 1); ++ if (cpus[0]->model) ++ modelNames[namesLen++] = cpus[0]->model; ++ + for (i = 1; i < ncpus; i++) { + g_autoptr(virCPUx86Model) model = NULL; + const char *vn = NULL; + +- if (matchingNames && cpus[i]->model) { +- if (!modelName) { +- modelName = cpus[i]->model; +- } else if (STRNEQ(modelName, cpus[i]->model)) { +- modelName = NULL; +- matchingNames = false; +- } +- } ++ if (cpus[i]->model && ++ !g_strv_contains((const char **) modelNames, cpus[i]->model)) ++ modelNames[namesLen++] = cpus[i]->model; + + if (!(model = x86ModelFromCPU(cpus[i], map, -1))) + return NULL; +@@ -2891,10 +2910,11 @@ virCPUx86Baseline(virCPUDef **cpus, + virCPUx86DataAddItem(&base_model->data, &vendor->data) < 0) + return NULL; + +- if (x86Decode(cpu, &base_model->data, models, modelName, migratable) < 0) ++ if (x86Decode(cpu, &base_model->data, models, ++ (const char **) modelNames, migratable) < 0) + return NULL; + +- if (STREQ_NULLABLE(cpu->model, modelName)) ++ if (namesLen == 1 && STREQ(cpu->model, modelNames[0])) + cpu->fallback = VIR_CPU_FALLBACK_FORBID; + + if (!outputVendor) +diff --git a/tests/cputestdata/x86_64-baseline-Westmere+Nehalem-migratable.xml b/tests/cputestdata/x86_64-baseline-Westmere+Nehalem-migratable.xml +index 775a27de2e..f5846b1619 100644 +--- a/tests/cputestdata/x86_64-baseline-Westmere+Nehalem-migratable.xml ++++ b/tests/cputestdata/x86_64-baseline-Westmere+Nehalem-migratable.xml +@@ -1,10 +1,14 @@ + +- SandyBridge ++ Westmere + Intel + + ++ + ++ ++ ++ + ++ + +- + +diff --git a/tests/cputestdata/x86_64-baseline-Westmere+Nehalem-result.xml b/tests/cputestdata/x86_64-baseline-Westmere+Nehalem-result.xml +index cafca97d62..166833276c 100644 +--- a/tests/cputestdata/x86_64-baseline-Westmere+Nehalem-result.xml ++++ b/tests/cputestdata/x86_64-baseline-Westmere+Nehalem-result.xml +@@ -1,11 +1,15 @@ + +- SandyBridge ++ Westmere + Intel + + ++ + ++ ++ ++ + ++ + + +- + +diff --git a/tests/cputestdata/x86_64-cpuid-baseline-Cooperlake+Cascadelake.xml b/tests/cputestdata/x86_64-cpuid-baseline-Cooperlake+Cascadelake.xml +index 46c32c996f..ecac749b97 100644 +--- a/tests/cputestdata/x86_64-cpuid-baseline-Cooperlake+Cascadelake.xml ++++ b/tests/cputestdata/x86_64-cpuid-baseline-Cooperlake+Cascadelake.xml +@@ -1,17 +1,22 @@ + +- Cooperlake ++ Cascadelake-Server + Intel + + + + +- + ++ + ++ ++ + + + ++ ++ ++ ++ ++ + +- +- + +-- +2.35.1 + diff --git a/libvirt-cpu_x86-Penalize-disabled-features-when-computing-CPU-model.patch b/libvirt-cpu_x86-Penalize-disabled-features-when-computing-CPU-model.patch new file mode 100644 index 0000000..a778c81 --- /dev/null +++ b/libvirt-cpu_x86-Penalize-disabled-features-when-computing-CPU-model.patch @@ -0,0 +1,1229 @@ +From 5db9a525e3cec267544580d43554b2cf5779b6b9 Mon Sep 17 00:00:00 2001 +Message-Id: <5db9a525e3cec267544580d43554b2cf5779b6b9@dist-git> +From: Jiri Denemark +Date: Tue, 26 Apr 2022 15:06:30 +0200 +Subject: [PATCH] cpu_x86: Penalize disabled features when computing CPU model + +For finding the best matching CPU model for a given set of features +while we don't know the CPU signature (i.e., when computing a baseline +CPU model) we've been using a "shortest list of features" heuristics. +This works well if new CPU models are supersets of older models, but +that's not always the case. As a result it may actually select a new CPU +model as a baseline while removing some features from it to make it +compatible with older models. This is in general worse than using an old +CPU model with a bunch of added features as a guest OS or apps may crash +when using features that were disabled. + +On the other hand we don't want to end up with a very old model which +would guarantee no disabled features as it could stop a guest OS or apps +from using some features provided by the CPU because they would not +expect them on such an old CPU. + +This patch changes the heuristics to something in between. Enabled and +disabled features are counted separately so that a CPU model requiring +some features to be disabled looks worse than a model with fewer +disabled features even if its complete list of features is longer. The +penalty given for each additional disabled feature gets bigger to make +longer list of disabled features look even worse. + +https://bugzilla.redhat.com/show_bug.cgi?id=1851227 + +Signed-off-by: Jiri Denemark +Reviewed-by: Michal Privoznik +(cherry picked from commit 48341b025acdd04a66696a709c7b09b3bfd42acf) + +Conflicts: + tests/domaincapsdata/qemu_2.9.0-tcg.x86_64.xml + tests/domaincapsdata/qemu_2.11.0-tcg.x86_64.xml + tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml + tests/domaincapsdata/qemu_3.0.0-tcg.x86_64.xml + - not supported upstream anymore + +Signed-off-by: Jiri Denemark +--- + src/cpu/cpu_x86.c | 44 ++++++++++++++++--- + .../x86_64-cpuid-Atom-D510-guest.xml | 5 ++- + .../x86_64-cpuid-Atom-N450-guest.xml | 5 ++- + .../x86_64-cpuid-Phenom-B95-json.xml | 21 +++++---- + ...id-baseline-Broadwell-IBRS+Cascadelake.xml | 11 +++-- + ..._64-cpuid-baseline-Cascadelake+Icelake.xml | 13 +++--- + ...puid-baseline-Cascadelake+Skylake-IBRS.xml | 5 ++- + ...6_64-cpuid-baseline-Cooperlake+Icelake.xml | 13 +++--- + .../x86_64-host+guest,models-result.xml | 10 +++-- + .../domaincapsdata/qemu_2.11.0-tcg.x86_64.xml | 34 ++++++++------ + .../domaincapsdata/qemu_2.12.0-tcg.x86_64.xml | 34 ++++++++------ + .../domaincapsdata/qemu_2.9.0-tcg.x86_64.xml | 16 ++++--- + .../domaincapsdata/qemu_3.0.0-tcg.x86_64.xml | 35 +++++++++------ + .../domaincapsdata/qemu_3.1.0-tcg.x86_64.xml | 35 +++++++++------ + .../domaincapsdata/qemu_4.0.0-tcg.x86_64.xml | 36 ++++++++------- + .../domaincapsdata/qemu_4.1.0-tcg.x86_64.xml | 37 +++++++++------- + .../domaincapsdata/qemu_4.2.0-tcg.x86_64.xml | 37 +++++++++------- + .../domaincapsdata/qemu_5.0.0-tcg.x86_64.xml | 36 +++++++++------ + .../domaincapsdata/qemu_5.1.0-tcg.x86_64.xml | 36 +++++++++------ + .../domaincapsdata/qemu_5.2.0-tcg.x86_64.xml | 36 +++++++++------ + .../domaincapsdata/qemu_6.0.0-tcg.x86_64.xml | 36 +++++++++------ + .../domaincapsdata/qemu_6.1.0-tcg.x86_64.xml | 36 +++++++++------ + .../domaincapsdata/qemu_6.2.0-tcg.x86_64.xml | 36 +++++++++------ + tests/qemuxml2argvdata/cpu-fallback.args | 2 +- + .../cpu-host-model-cmt.x86_64-4.0.0.args | 2 +- + .../cpu-host-model-fallback.args | 2 +- + 26 files changed, 382 insertions(+), 231 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index 81c2441b8b..ebcd96edb1 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -1970,23 +1970,57 @@ virCPUx86Compare(virCPUDef *host, + } + + ++/* Base penalty for disabled features. */ ++#define BASE_PENALTY 2 ++ + static int + virCPUx86CompareCandidateFeatureList(virCPUDef *cpuCurrent, + virCPUDef *cpuCandidate) + { + size_t current = cpuCurrent->nfeatures; ++ size_t enabledCurrent = current; ++ size_t disabledCurrent = 0; + size_t candidate = cpuCandidate->nfeatures; ++ size_t enabled = candidate; ++ size_t disabled = 0; ++ ++ if (cpuCandidate->type != VIR_CPU_TYPE_HOST) { ++ size_t i; ++ int penalty = BASE_PENALTY; ++ ++ for (i = 0; i < enabledCurrent; i++) { ++ if (cpuCurrent->features[i].policy == VIR_CPU_FEATURE_DISABLE) { ++ enabledCurrent--; ++ disabledCurrent += penalty; ++ penalty++; ++ } ++ } ++ current = enabledCurrent + disabledCurrent; ++ ++ penalty = BASE_PENALTY; ++ for (i = 0; i < enabled; i++) { ++ if (cpuCandidate->features[i].policy == VIR_CPU_FEATURE_DISABLE) { ++ enabled--; ++ disabled += penalty; ++ penalty++; ++ } ++ } ++ candidate = enabled + disabled; ++ } + +- if (candidate < current) { +- VIR_DEBUG("%s is better than %s: %zu < %zu", ++ if (candidate < current || ++ (candidate == current && disabled < disabledCurrent)) { ++ VIR_DEBUG("%s is better than %s: %zu (%zu, %zu) < %zu (%zu, %zu)", + cpuCandidate->model, cpuCurrent->model, +- candidate, current); ++ candidate, enabled, disabled, ++ current, enabledCurrent, disabledCurrent); + return 1; + } + +- VIR_DEBUG("%s is not better than %s: %zu >= %zu", ++ VIR_DEBUG("%s is not better than %s: %zu (%zu, %zu) >= %zu (%zu, %zu)", + cpuCandidate->model, cpuCurrent->model, +- candidate, current); ++ candidate, enabled, disabled, ++ current, enabledCurrent, disabledCurrent); + return 0; + } + +diff --git a/tests/cputestdata/x86_64-cpuid-Atom-D510-guest.xml b/tests/cputestdata/x86_64-cpuid-Atom-D510-guest.xml +index caa0bfd53b..d2f7a79074 100644 +--- a/tests/cputestdata/x86_64-cpuid-Atom-D510-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-Atom-D510-guest.xml +@@ -1,6 +1,7 @@ + +- core2duo ++ n270 + Intel ++ + + + +@@ -14,6 +15,6 @@ + + + ++ + +- + +diff --git a/tests/cputestdata/x86_64-cpuid-Atom-N450-guest.xml b/tests/cputestdata/x86_64-cpuid-Atom-N450-guest.xml +index e8f5c93881..779faf6cef 100644 +--- a/tests/cputestdata/x86_64-cpuid-Atom-N450-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-Atom-N450-guest.xml +@@ -1,5 +1,5 @@ + +- core2duo ++ n270 + Intel + + +@@ -15,6 +15,7 @@ + + + ++ ++ + +- + +diff --git a/tests/cputestdata/x86_64-cpuid-Phenom-B95-json.xml b/tests/cputestdata/x86_64-cpuid-Phenom-B95-json.xml +index b4198f66a5..7f6289c6d7 100644 +--- a/tests/cputestdata/x86_64-cpuid-Phenom-B95-json.xml ++++ b/tests/cputestdata/x86_64-cpuid-Phenom-B95-json.xml +@@ -1,22 +1,25 @@ + +- Opteron_G3 ++ athlon + AMD +- ++ ++ ++ ++ + ++ + +- ++ + + +- +- ++ ++ + + ++ ++ ++ + + + + +- +- +- +- + +diff --git a/tests/cputestdata/x86_64-cpuid-baseline-Broadwell-IBRS+Cascadelake.xml b/tests/cputestdata/x86_64-cpuid-baseline-Broadwell-IBRS+Cascadelake.xml +index 4e3f253e9b..99bce8db87 100644 +--- a/tests/cputestdata/x86_64-cpuid-baseline-Broadwell-IBRS+Cascadelake.xml ++++ b/tests/cputestdata/x86_64-cpuid-baseline-Broadwell-IBRS+Cascadelake.xml +@@ -1,11 +1,14 @@ + +- Skylake-Client-IBRS ++ Broadwell-IBRS + Intel ++ + ++ ++ + ++ + ++ + +- +- +- ++ + +diff --git a/tests/cputestdata/x86_64-cpuid-baseline-Cascadelake+Icelake.xml b/tests/cputestdata/x86_64-cpuid-baseline-Cascadelake+Icelake.xml +index e372a3e446..071c799ba2 100644 +--- a/tests/cputestdata/x86_64-cpuid-baseline-Cascadelake+Icelake.xml ++++ b/tests/cputestdata/x86_64-cpuid-baseline-Cascadelake+Icelake.xml +@@ -1,14 +1,15 @@ + +- Cooperlake ++ Cascadelake-Server + Intel + + + +- + ++ ++ ++ + +- +- +- +- ++ ++ ++ + +diff --git a/tests/cputestdata/x86_64-cpuid-baseline-Cascadelake+Skylake-IBRS.xml b/tests/cputestdata/x86_64-cpuid-baseline-Cascadelake+Skylake-IBRS.xml +index e559e01583..5e42876b39 100644 +--- a/tests/cputestdata/x86_64-cpuid-baseline-Cascadelake+Skylake-IBRS.xml ++++ b/tests/cputestdata/x86_64-cpuid-baseline-Cascadelake+Skylake-IBRS.xml +@@ -1,12 +1,13 @@ + +- Cascadelake-Server ++ Skylake-Server-IBRS + Intel + + + ++ + + ++ + + +- + +diff --git a/tests/cputestdata/x86_64-cpuid-baseline-Cooperlake+Icelake.xml b/tests/cputestdata/x86_64-cpuid-baseline-Cooperlake+Icelake.xml +index e372a3e446..071c799ba2 100644 +--- a/tests/cputestdata/x86_64-cpuid-baseline-Cooperlake+Icelake.xml ++++ b/tests/cputestdata/x86_64-cpuid-baseline-Cooperlake+Icelake.xml +@@ -1,14 +1,15 @@ + +- Cooperlake ++ Cascadelake-Server + Intel + + + +- + ++ ++ ++ + +- +- +- +- ++ ++ ++ + +diff --git a/tests/cputestdata/x86_64-host+guest,models-result.xml b/tests/cputestdata/x86_64-host+guest,models-result.xml +index 0dd6955898..42664a48b4 100644 +--- a/tests/cputestdata/x86_64-host+guest,models-result.xml ++++ b/tests/cputestdata/x86_64-host+guest,models-result.xml +@@ -1,17 +1,19 @@ + +- Nehalem ++ qemu64 + + + ++ + + ++ + +- ++ + + +- + +- + + ++ ++ + +diff --git a/tests/domaincapsdata/qemu_2.11.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_2.11.0-tcg.x86_64.xml +index cccc6830f9..4a92b5bead 100644 +--- a/tests/domaincapsdata/qemu_2.11.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_2.11.0-tcg.x86_64.xml +@@ -36,34 +36,42 @@ + + + +- EPYC ++ Opteron_G3 + AMD + + ++ + ++ ++ ++ ++ ++ ++ + ++ ++ ++ ++ ++ + + ++ ++ + ++ + + + + ++ ++ ++ ++ + + +- +- +- +- +- +- +- +- +- +- ++ + +- +- + + + qemu64 +diff --git a/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml +index 575506d852..7799a6a7a6 100644 +--- a/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml +@@ -36,34 +36,42 @@ + + + +- EPYC ++ Opteron_G3 + AMD + + ++ + ++ ++ ++ ++ ++ ++ + ++ ++ ++ ++ ++ + + ++ ++ + ++ + + + + ++ ++ ++ ++ + + +- +- +- +- +- +- +- +- +- +- ++ + +- +- + + + qemu64 +diff --git a/tests/domaincapsdata/qemu_2.9.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_2.9.0-tcg.x86_64.xml +index b47c426f1b..fe12641fbe 100644 +--- a/tests/domaincapsdata/qemu_2.9.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_2.9.0-tcg.x86_64.xml +@@ -36,12 +36,19 @@ + + + +- Opteron_G4 ++ Opteron_G3 + AMD + + ++ + ++ ++ ++ + ++ ++ ++ + + + +@@ -61,14 +68,13 @@ + + + ++ + + + +- ++ ++ + +- +- +- + + + qemu64 +diff --git a/tests/domaincapsdata/qemu_3.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_3.0.0-tcg.x86_64.xml +index 301101095c..daccacba0e 100644 +--- a/tests/domaincapsdata/qemu_3.0.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_3.0.0-tcg.x86_64.xml +@@ -36,35 +36,42 @@ + + + +- EPYC ++ Opteron_G3 + AMD + + ++ + ++ ++ ++ ++ ++ ++ + ++ ++ ++ ++ ++ + + ++ ++ + ++ + + + ++ ++ ++ ++ + + ++ + +- +- +- +- +- +- +- +- +- +- + +- +- +- + + + qemu64 +diff --git a/tests/domaincapsdata/qemu_3.1.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_3.1.0-tcg.x86_64.xml +index 1a5bc25b99..2a65cb0ad9 100644 +--- a/tests/domaincapsdata/qemu_3.1.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_3.1.0-tcg.x86_64.xml +@@ -36,35 +36,42 @@ + + + +- EPYC ++ Opteron_G3 + AMD + + ++ + ++ ++ ++ ++ ++ ++ + ++ ++ ++ ++ ++ + + ++ ++ + ++ + + + ++ ++ ++ ++ + + ++ + +- +- +- +- +- +- +- +- +- +- + +- +- +- + + + qemu64 +diff --git a/tests/domaincapsdata/qemu_4.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_4.0.0-tcg.x86_64.xml +index e744ac27ac..a4dc7bafc9 100644 +--- a/tests/domaincapsdata/qemu_4.0.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_4.0.0-tcg.x86_64.xml +@@ -36,36 +36,42 @@ + + + +- EPYC ++ Opteron_G3 + AMD + + ++ + ++ ++ ++ ++ ++ ++ + ++ ++ ++ ++ ++ + + ++ ++ + ++ + + + ++ ++ ++ ++ + + ++ + +- +- +- +- +- +- +- +- +- +- + +- +- +- +- + + + qemu64 +diff --git a/tests/domaincapsdata/qemu_4.1.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_4.1.0-tcg.x86_64.xml +index 80b1ce8ef9..b20c02cb68 100644 +--- a/tests/domaincapsdata/qemu_4.1.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_4.1.0-tcg.x86_64.xml +@@ -36,36 +36,43 @@ + + + +- EPYC-IBPB ++ Opteron_G3 + AMD + + ++ + ++ ++ ++ ++ ++ ++ ++ + ++ ++ ++ ++ ++ + + ++ ++ + ++ + + + ++ ++ ++ ++ + + ++ + +- +- +- +- +- +- +- +- +- + +- +- +- +- +- + + + qemu64 +diff --git a/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml +index 91b3ed6f80..d0ee3f7b7a 100644 +--- a/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml +@@ -36,36 +36,43 @@ + + + +- EPYC-IBPB ++ Opteron_G3 + AMD + + ++ + ++ ++ ++ ++ ++ ++ ++ + ++ ++ ++ ++ ++ + + ++ ++ + ++ + + + ++ ++ ++ ++ + + ++ + +- +- +- +- +- +- +- +- +- + +- +- +- +- +- + + + qemu64 +diff --git a/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml +index b8737613e9..d277c96426 100644 +--- a/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml +@@ -36,35 +36,43 @@ + + + +- EPYC ++ Opteron_G3 + AMD + + ++ + ++ ++ ++ ++ ++ ++ ++ + ++ ++ ++ ++ ++ + + ++ ++ + ++ + + + ++ ++ ++ ++ + + ++ + +- +- +- +- +- +- +- +- +- + +- +- +- +- + + + qemu64 +diff --git a/tests/domaincapsdata/qemu_5.1.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_5.1.0-tcg.x86_64.xml +index 034036ca96..4f1ffbb2ba 100644 +--- a/tests/domaincapsdata/qemu_5.1.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_5.1.0-tcg.x86_64.xml +@@ -36,35 +36,43 @@ + + + +- EPYC ++ Opteron_G3 + AMD + + ++ + ++ ++ ++ ++ ++ ++ ++ + ++ ++ ++ ++ ++ + + ++ ++ + ++ + + + ++ ++ ++ ++ + + ++ + +- +- +- +- +- +- +- +- +- + +- +- +- +- + + + qemu64 +diff --git a/tests/domaincapsdata/qemu_5.2.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_5.2.0-tcg.x86_64.xml +index d3a4b01234..6cff0f815e 100644 +--- a/tests/domaincapsdata/qemu_5.2.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_5.2.0-tcg.x86_64.xml +@@ -36,35 +36,43 @@ + + + +- EPYC ++ Opteron_G3 + AMD + + ++ + ++ ++ ++ ++ ++ ++ ++ + ++ ++ ++ ++ ++ + + ++ ++ + ++ + + + ++ ++ ++ ++ + + ++ + +- +- +- +- +- +- +- +- +- + +- +- +- +- + + + qemu64 +diff --git a/tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml +index 6b85c9c45a..65f4459bcb 100644 +--- a/tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml +@@ -36,35 +36,43 @@ + + + +- EPYC ++ Opteron_G3 + AMD + + ++ + ++ ++ ++ ++ ++ ++ ++ + ++ ++ ++ ++ ++ + + ++ ++ + ++ + + + ++ ++ ++ ++ + + ++ + +- +- +- +- +- +- +- +- +- + +- +- +- +- + + + qemu64 +diff --git a/tests/domaincapsdata/qemu_6.1.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_6.1.0-tcg.x86_64.xml +index 2c761fc1af..40bc875e3c 100644 +--- a/tests/domaincapsdata/qemu_6.1.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_6.1.0-tcg.x86_64.xml +@@ -36,35 +36,43 @@ + + + +- EPYC ++ Opteron_G3 + AMD + + ++ + ++ ++ ++ ++ ++ ++ ++ + ++ ++ ++ ++ ++ + + ++ ++ + ++ + + + ++ ++ ++ ++ + + ++ + +- +- +- +- +- +- +- +- +- + +- +- +- +- + + + qemu64 +diff --git a/tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml +index 8db840faac..a439dda190 100644 +--- a/tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml +@@ -36,36 +36,44 @@ + + + +- EPYC ++ Opteron_G3 + AMD + + ++ + ++ ++ ++ ++ ++ ++ ++ + ++ ++ ++ ++ ++ + + ++ ++ + ++ + + + ++ ++ ++ ++ + + ++ + + +- +- +- +- +- +- +- +- +- + +- +- +- +- + + + qemu64 +diff --git a/tests/qemuxml2argvdata/cpu-fallback.args b/tests/qemuxml2argvdata/cpu-fallback.args +index 1b1769d420..53667dfa3a 100644 +--- a/tests/qemuxml2argvdata/cpu-fallback.args ++++ b/tests/qemuxml2argvdata/cpu-fallback.args +@@ -13,7 +13,7 @@ QEMU_AUDIO_DRV=none \ + -object secret,id=masterKey0,format=raw,file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \ + -machine pc,usb=off,dump-guest-core=off \ + -accel kvm \ +--cpu Penryn,sse4.1=off,sse4.2=off,popcnt=off,aes=off \ ++-cpu Conroe,cx16=on,sse4.1=off,sse4.2=off,popcnt=off,aes=off \ + -m 214 \ + -realtime mlock=off \ + -smp 6,sockets=6,cores=1,threads=1 \ +diff --git a/tests/qemuxml2argvdata/cpu-host-model-cmt.x86_64-4.0.0.args b/tests/qemuxml2argvdata/cpu-host-model-cmt.x86_64-4.0.0.args +index 3ff226a289..0de09e1d88 100644 +--- a/tests/qemuxml2argvdata/cpu-host-model-cmt.x86_64-4.0.0.args ++++ b/tests/qemuxml2argvdata/cpu-host-model-cmt.x86_64-4.0.0.args +@@ -13,7 +13,7 @@ QEMU_AUDIO_DRV=none \ + -object secret,id=masterKey0,format=raw,file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \ + -machine pc-i440fx-4.0,usb=off,dump-guest-core=off \ + -accel tcg \ +--cpu EPYC,acpi=on,ss=on,monitor=on,hypervisor=on,erms=on,mpx=on,pcommit=on,clwb=on,pku=on,la57=on,3dnowext=on,3dnow=on,npt=on,vme=off,fma=off,avx=off,f16c=off,rdrand=off,avx2=off,rdseed=off,sha-ni=off,xsavec=off,fxsr-opt=off,misalignsse=off,3dnowprefetch=off,osvw=off,topoext=off,nrip-save=off \ ++-cpu Opteron_G3,acpi=on,ss=on,pclmulqdq=on,monitor=on,ssse3=on,sse4.1=on,sse4.2=on,movbe=on,aes=on,xsave=on,hypervisor=on,arat=on,fsgsbase=on,bmi1=on,smep=on,bmi2=on,erms=on,mpx=on,adx=on,smap=on,pcommit=on,clflushopt=on,clwb=on,pku=on,la57=on,xsaveopt=on,xgetbv1=on,mmxext=on,pdpe1gb=on,3dnowext=on,3dnow=on,cr8legacy=on,npt=on,misalignsse=off \ + -m 214 \ + -overcommit mem-lock=off \ + -smp 6,sockets=6,cores=1,threads=1 \ +diff --git a/tests/qemuxml2argvdata/cpu-host-model-fallback.args b/tests/qemuxml2argvdata/cpu-host-model-fallback.args +index e90b781da4..763e630120 100644 +--- a/tests/qemuxml2argvdata/cpu-host-model-fallback.args ++++ b/tests/qemuxml2argvdata/cpu-host-model-fallback.args +@@ -13,7 +13,7 @@ QEMU_AUDIO_DRV=none \ + -object secret,id=masterKey0,format=raw,file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \ + -machine pc,usb=off,dump-guest-core=off \ + -accel tcg \ +--cpu Penryn,vme=on,ds=on,acpi=on,ss=on,ht=on,tm=on,pbe=on,monitor=on,ds-cpl=on,vmx=on,est=on,tm2=on,xtpr=on,sse4.1=off,cx16=on,lahf-lm=on \ ++-cpu Conroe,vme=on,ds=on,acpi=on,ss=on,ht=on,tm=on,pbe=on,monitor=on,ds-cpl=on,vmx=on,est=on,tm2=on,cx16=on,xtpr=on,lahf-lm=on \ + -m 214 \ + -realtime mlock=off \ + -smp 6,sockets=6,cores=1,threads=1 \ +-- +2.35.1 + diff --git a/libvirt-cpu_x86-Refactor-feature-list-comparison-in-x86DecodeUseCandidate.patch b/libvirt-cpu_x86-Refactor-feature-list-comparison-in-x86DecodeUseCandidate.patch new file mode 100644 index 0000000..24591e6 --- /dev/null +++ b/libvirt-cpu_x86-Refactor-feature-list-comparison-in-x86DecodeUseCandidate.patch @@ -0,0 +1,73 @@ +From 3d7a4041d31e403dc9e762b34f7faf36f7f20a28 Mon Sep 17 00:00:00 2001 +Message-Id: <3d7a4041d31e403dc9e762b34f7faf36f7f20a28@dist-git> +From: Jiri Denemark +Date: Tue, 26 Apr 2022 15:02:51 +0200 +Subject: [PATCH] cpu_x86: Refactor feature list comparison in + x86DecodeUseCandidate + +It will become more complicated and so it deserves to be separated into +a new function. + +Signed-off-by: Jiri Denemark +Reviewed-by: Michal Privoznik +(cherry picked from commit 1d6ca40ac23c039abc4392b668f256d0eda33280) + +https://bugzilla.redhat.com/show_bug.cgi?id=1851227 + +Signed-off-by: Jiri Denemark +--- + src/cpu/cpu_x86.c | 31 ++++++++++++++++++++++--------- + 1 file changed, 22 insertions(+), 9 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index f007487824..81c2441b8b 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -1970,6 +1970,27 @@ virCPUx86Compare(virCPUDef *host, + } + + ++static int ++virCPUx86CompareCandidateFeatureList(virCPUDef *cpuCurrent, ++ virCPUDef *cpuCandidate) ++{ ++ size_t current = cpuCurrent->nfeatures; ++ size_t candidate = cpuCandidate->nfeatures; ++ ++ if (candidate < current) { ++ VIR_DEBUG("%s is better than %s: %zu < %zu", ++ cpuCandidate->model, cpuCurrent->model, ++ candidate, current); ++ return 1; ++ } ++ ++ VIR_DEBUG("%s is not better than %s: %zu >= %zu", ++ cpuCandidate->model, cpuCurrent->model, ++ candidate, current); ++ return 0; ++} ++ ++ + /* + * Checks whether a candidate model is a better fit for the CPU data than the + * current model. +@@ -2038,15 +2059,7 @@ x86DecodeUseCandidate(virCPUx86Model *current, + } + } + +- if (cpuCurrent->nfeatures > cpuCandidate->nfeatures) { +- VIR_DEBUG("%s results in shorter feature list than %s", +- cpuCandidate->model, cpuCurrent->model); +- return 1; +- } +- +- VIR_DEBUG("%s does not result in shorter feature list than %s", +- cpuCandidate->model, cpuCurrent->model); +- return 0; ++ return virCPUx86CompareCandidateFeatureList(cpuCurrent, cpuCandidate); + } + + +-- +2.35.1 + diff --git a/libvirt-cputest-Add-some-real-world-baseline-tests.patch b/libvirt-cputest-Add-some-real-world-baseline-tests.patch new file mode 100644 index 0000000..6007a0f --- /dev/null +++ b/libvirt-cputest-Add-some-real-world-baseline-tests.patch @@ -0,0 +1,498 @@ +From b37a398da4323407de24d19afac937eac80170cc Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Thu, 21 Apr 2022 18:25:15 +0200 +Subject: [PATCH] cputest: Add some real world baseline tests + +Signed-off-by: Jiri Denemark +Reviewed-by: Michal Privoznik +(cherry picked from commit 63d633b9a4fc42da7e2acaf45501914607d968a5) + +https://bugzilla.redhat.com/show_bug.cgi?id=1851227 + +Signed-off-by: Jiri Denemark +--- + tests/cputest.c | 118 +++++++++++++++--- + ...id-baseline-Broadwell-IBRS+Cascadelake.xml | 11 ++ + ..._64-cpuid-baseline-Cascadelake+Icelake.xml | 14 +++ + ...puid-baseline-Cascadelake+Skylake-IBRS.xml | 12 ++ + ..._64-cpuid-baseline-Cascadelake+Skylake.xml | 8 ++ + ...-cpuid-baseline-Cooperlake+Cascadelake.xml | 17 +++ + ...6_64-cpuid-baseline-Cooperlake+Icelake.xml | 14 +++ + .../x86_64-cpuid-baseline-EPYC+Rome.xml | 13 ++ + .../x86_64-cpuid-baseline-Haswell+Skylake.xml | 14 +++ + ...-baseline-Haswell-noTSX-IBRS+Broadwell.xml | 14 +++ + ...seline-Haswell-noTSX-IBRS+Skylake-IBRS.xml | 14 +++ + ...id-baseline-Haswell-noTSX-IBRS+Skylake.xml | 14 +++ + .../x86_64-cpuid-baseline-Ryzen+Rome.xml | 13 ++ + ...4-cpuid-baseline-Skylake-Client+Server.xml | 9 ++ + 14 files changed, 271 insertions(+), 14 deletions(-) + create mode 100644 tests/cputestdata/x86_64-cpuid-baseline-Broadwell-IBRS+Cascadelake.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-baseline-Cascadelake+Icelake.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-baseline-Cascadelake+Skylake-IBRS.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-baseline-Cascadelake+Skylake.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-baseline-Cooperlake+Cascadelake.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-baseline-Cooperlake+Icelake.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-baseline-EPYC+Rome.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-baseline-Haswell+Skylake.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-baseline-Haswell-noTSX-IBRS+Broadwell.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-baseline-Haswell-noTSX-IBRS+Skylake-IBRS.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-baseline-Haswell-noTSX-IBRS+Skylake.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-baseline-Ryzen+Rome.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-baseline-Skylake-Client+Server.xml + +diff --git a/tests/cputest.c b/tests/cputest.c +index b939e20718..b39ec7e18b 100644 +--- a/tests/cputest.c ++++ b/tests/cputest.c +@@ -58,6 +58,8 @@ struct data { + const char *name; + virDomainCapsCPUModels *models; + const char *modelsName; ++ const char **cpus; ++ int ncpus; + unsigned int flags; + int result; + }; +@@ -561,6 +563,60 @@ cpuTestCPUID(bool guest, const void *arg) + } + + ++static int ++cpuTestCPUIDBaseline(const void *arg) ++{ ++ const struct data *data = arg; ++ int ret = -1; ++ virCPUDef **cpus = NULL; ++ virCPUDef *baseline = NULL; ++ g_autofree char *result = NULL; ++ size_t i; ++ ++ cpus = g_new0(virCPUDef *, data->ncpus); ++ for (i = 0; i < data->ncpus; i++) { ++ g_autofree char *name = NULL; ++ ++ name = g_strdup_printf("cpuid-%s-json", data->cpus[i]); ++ if (!(cpus[i] = cpuTestLoadXML(data->arch, name))) ++ goto cleanup; ++ } ++ ++ baseline = virCPUBaseline(data->arch, cpus, data->ncpus, NULL, NULL, false); ++ if (!baseline) ++ goto cleanup; ++ ++ result = g_strdup_printf("cpuid-baseline-%s", data->name); ++ ++ if (cpuTestCompareXML(data->arch, baseline, result) < 0) ++ goto cleanup; ++ ++ for (i = 0; i < data->ncpus; i++) { ++ virCPUCompareResult cmp; ++ ++ cmp = virCPUCompare(data->arch, cpus[i], baseline, false); ++ if (cmp != VIR_CPU_COMPARE_SUPERSET && ++ cmp != VIR_CPU_COMPARE_IDENTICAL) { ++ VIR_TEST_VERBOSE("\nbaseline CPU is incompatible with CPU %zu", i); ++ VIR_TEST_VERBOSE("%74s", "... "); ++ ret = -1; ++ goto cleanup; ++ } ++ } ++ ++ ret = 0; ++ ++ cleanup: ++ if (cpus) { ++ for (i = 0; i < data->ncpus; i++) ++ virCPUDefFree(cpus[i]); ++ VIR_FREE(cpus); ++ } ++ virCPUDefFree(baseline); ++ return ret; ++} ++ ++ + static int + cpuTestHostCPUID(const void *arg) + { +@@ -888,13 +944,13 @@ mymain(void) + goto cleanup; + } + +-#define DO_TEST(arch, api, name, host, cpu, \ ++#define DO_TEST(arch, api, name, host, cpu, cpus, ncpus, \ + models, flags, result) \ + do { \ + struct data data = { \ + arch, host, cpu, models, \ + models == NULL ? NULL : #models, \ +- flags, result \ ++ cpus, ncpus, flags, result \ + }; \ + g_autofree char *testLabel = NULL; \ + \ +@@ -907,12 +963,12 @@ mymain(void) + #define DO_TEST_COMPARE(arch, host, cpu, result) \ + DO_TEST(arch, cpuTestCompare, \ + host "/" cpu " (" #result ")", \ +- host, cpu, NULL, 0, result) ++ host, cpu, NULL, 0, NULL, 0, result) + + #define DO_TEST_UPDATE_ONLY(arch, host, cpu) \ + DO_TEST(arch, cpuTestUpdate, \ + cpu " on " host, \ +- host, cpu, NULL, 0, 0) ++ host, cpu, NULL, 0, NULL, 0, 0) + + #define DO_TEST_UPDATE(arch, host, cpu, result) \ + do { \ +@@ -930,31 +986,31 @@ mymain(void) + suffix = " (migratable)"; \ + label = g_strdup_printf("%s%s", name, suffix); \ + DO_TEST(arch, cpuTestBaseline, label, NULL, \ +- "baseline-" name, NULL, flags, result); \ ++ "baseline-" name, NULL, 0, NULL, flags, result); \ + } while (0) + + #define DO_TEST_HASFEATURE(arch, host, feature, result) \ + DO_TEST(arch, cpuTestHasFeature, \ + host "/" feature " (" #result ")", \ +- host, feature, NULL, 0, result) ++ host, feature, NULL, 0, NULL, 0, result) + + #define DO_TEST_GUESTCPU(arch, host, cpu, models, result) \ + DO_TEST(arch, cpuTestGuestCPU, \ + host "/" cpu " (" #models ")", \ +- host, cpu, models, 0, result) ++ host, cpu, NULL, 0, models, 0, result) + + #if WITH_QEMU + # define DO_TEST_JSON(arch, host, json) \ + do { \ + if (json == JSON_MODELS) { \ + DO_TEST(arch, cpuTestGuestCPUID, host, host, \ +- NULL, NULL, 0, 0); \ ++ NULL, NULL, 0, NULL, 0, 0); \ + } \ + if (json != JSON_NONE) { \ + DO_TEST(arch, cpuTestJSONCPUID, host, host, \ +- NULL, NULL, json, 0); \ ++ NULL, NULL, 0, NULL, json, 0); \ + DO_TEST(arch, cpuTestJSONSignature, host, host, \ +- NULL, NULL, 0, 0); \ ++ NULL, NULL, 0, NULL, 0, 0); \ + } \ + } while (0) + #else +@@ -964,18 +1020,26 @@ mymain(void) + #define DO_TEST_CPUID(arch, host, json) \ + do { \ + DO_TEST(arch, cpuTestHostCPUID, host, host, \ +- NULL, NULL, 0, 0); \ ++ NULL, NULL, 0, NULL, 0, 0); \ + DO_TEST(arch, cpuTestGuestCPUID, host, host, \ +- NULL, NULL, json, 0); \ ++ NULL, NULL, 0, NULL, json, 0); \ + DO_TEST(arch, cpuTestCPUIDSignature, host, host, \ +- NULL, NULL, 0, 0); \ ++ NULL, NULL, 0, NULL, 0, 0); \ + DO_TEST_JSON(arch, host, json); \ + if (json != JSON_NONE) { \ + DO_TEST(arch, cpuTestUpdateLive, host, host, \ +- NULL, NULL, json, 0); \ ++ NULL, NULL, 0, NULL, json, 0); \ + } \ + } while (0) + ++#define DO_TEST_CPUID_BASELINE(arch, label, cpu1, cpu2) \ ++ do { \ ++ const char *cpus[] = {cpu1, cpu2}; \ ++ DO_TEST(arch, cpuTestCPUIDBaseline, \ ++ label " (" cpu1 ", " cpu2 ")", \ ++ NULL, label, cpus, 2, NULL, 0, 0); \ ++ } while (0) ++ + /* host to host comparison */ + DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "host", VIR_CPU_COMPARE_IDENTICAL); + DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "host-better", VIR_CPU_COMPARE_INCOMPATIBLE); +@@ -1157,6 +1221,32 @@ mymain(void) + DO_TEST_CPUID(VIR_ARCH_X86_64, "Ice-Lake-Server", JSON_MODELS); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Cooperlake", JSON_MODELS); + ++ DO_TEST_CPUID_BASELINE(VIR_ARCH_X86_64, "Ryzen+Rome", ++ "Ryzen-7-1800X-Eight-Core", "Ryzen-9-3900X-12-Core"); ++ DO_TEST_CPUID_BASELINE(VIR_ARCH_X86_64, "EPYC+Rome", ++ "EPYC-7601-32-Core", "EPYC-7502-32-Core"); ++ DO_TEST_CPUID_BASELINE(VIR_ARCH_X86_64, "Haswell-noTSX-IBRS+Skylake", ++ "Xeon-E5-2609-v3", "Xeon-Gold-6148"); ++ DO_TEST_CPUID_BASELINE(VIR_ARCH_X86_64, "Haswell-noTSX-IBRS+Skylake-IBRS", ++ "Xeon-E5-2609-v3", "Xeon-Gold-6130"); ++ DO_TEST_CPUID_BASELINE(VIR_ARCH_X86_64, "Broadwell-IBRS+Cascadelake", ++ "Xeon-E5-2623-v4", "Xeon-Platinum-8268"); ++ DO_TEST_CPUID_BASELINE(VIR_ARCH_X86_64, "Cascadelake+Skylake-IBRS", ++ "Xeon-Platinum-8268", "Xeon-Gold-6130"); ++ DO_TEST_CPUID_BASELINE(VIR_ARCH_X86_64, "Cascadelake+Skylake", ++ "Xeon-Platinum-9242", "Xeon-Gold-6148"); ++ DO_TEST_CPUID_BASELINE(VIR_ARCH_X86_64, "Cascadelake+Icelake", ++ "Xeon-Platinum-9242", "Ice-Lake-Server"); ++ DO_TEST_CPUID_BASELINE(VIR_ARCH_X86_64, "Cooperlake+Icelake", ++ "Cooperlake", "Ice-Lake-Server"); ++ DO_TEST_CPUID_BASELINE(VIR_ARCH_X86_64, "Cooperlake+Cascadelake", ++ "Cooperlake", "Xeon-Platinum-9242"); ++ DO_TEST_CPUID_BASELINE(VIR_ARCH_X86_64, "Skylake-Client+Server", ++ "Core-i5-6600", "Xeon-Gold-6148"); ++ DO_TEST_CPUID_BASELINE(VIR_ARCH_X86_64, "Haswell-noTSX-IBRS+Broadwell", ++ "Xeon-E5-2609-v3", "Xeon-E5-2650-v4"); ++ DO_TEST_CPUID_BASELINE(VIR_ARCH_X86_64, "Haswell+Skylake", ++ "Xeon-E7-8890-v3", "Xeon-Gold-5115"); + cleanup: + #if WITH_QEMU + qemuTestDriverFree(&driver); +diff --git a/tests/cputestdata/x86_64-cpuid-baseline-Broadwell-IBRS+Cascadelake.xml b/tests/cputestdata/x86_64-cpuid-baseline-Broadwell-IBRS+Cascadelake.xml +new file mode 100644 +index 0000000000..4e3f253e9b +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-baseline-Broadwell-IBRS+Cascadelake.xml +@@ -0,0 +1,11 @@ ++ ++ Skylake-Client-IBRS ++ Intel ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-baseline-Cascadelake+Icelake.xml b/tests/cputestdata/x86_64-cpuid-baseline-Cascadelake+Icelake.xml +new file mode 100644 +index 0000000000..e372a3e446 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-baseline-Cascadelake+Icelake.xml +@@ -0,0 +1,14 @@ ++ ++ Cooperlake ++ Intel ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-baseline-Cascadelake+Skylake-IBRS.xml b/tests/cputestdata/x86_64-cpuid-baseline-Cascadelake+Skylake-IBRS.xml +new file mode 100644 +index 0000000000..e559e01583 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-baseline-Cascadelake+Skylake-IBRS.xml +@@ -0,0 +1,12 @@ ++ ++ Cascadelake-Server ++ Intel ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-baseline-Cascadelake+Skylake.xml b/tests/cputestdata/x86_64-cpuid-baseline-Cascadelake+Skylake.xml +new file mode 100644 +index 0000000000..906259df0b +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-baseline-Cascadelake+Skylake.xml +@@ -0,0 +1,8 @@ ++ ++ Skylake-Server ++ Intel ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-baseline-Cooperlake+Cascadelake.xml b/tests/cputestdata/x86_64-cpuid-baseline-Cooperlake+Cascadelake.xml +new file mode 100644 +index 0000000000..46c32c996f +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-baseline-Cooperlake+Cascadelake.xml +@@ -0,0 +1,17 @@ ++ ++ Cooperlake ++ Intel ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-baseline-Cooperlake+Icelake.xml b/tests/cputestdata/x86_64-cpuid-baseline-Cooperlake+Icelake.xml +new file mode 100644 +index 0000000000..e372a3e446 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-baseline-Cooperlake+Icelake.xml +@@ -0,0 +1,14 @@ ++ ++ Cooperlake ++ Intel ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-baseline-EPYC+Rome.xml b/tests/cputestdata/x86_64-cpuid-baseline-EPYC+Rome.xml +new file mode 100644 +index 0000000000..e1984b2890 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-baseline-EPYC+Rome.xml +@@ -0,0 +1,13 @@ ++ ++ EPYC ++ AMD ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-baseline-Haswell+Skylake.xml b/tests/cputestdata/x86_64-cpuid-baseline-Haswell+Skylake.xml +new file mode 100644 +index 0000000000..e687a679b3 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-baseline-Haswell+Skylake.xml +@@ -0,0 +1,14 @@ ++ ++ Haswell ++ Intel ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-baseline-Haswell-noTSX-IBRS+Broadwell.xml b/tests/cputestdata/x86_64-cpuid-baseline-Haswell-noTSX-IBRS+Broadwell.xml +new file mode 100644 +index 0000000000..651457b17a +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-baseline-Haswell-noTSX-IBRS+Broadwell.xml +@@ -0,0 +1,14 @@ ++ ++ Haswell-noTSX ++ Intel ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-baseline-Haswell-noTSX-IBRS+Skylake-IBRS.xml b/tests/cputestdata/x86_64-cpuid-baseline-Haswell-noTSX-IBRS+Skylake-IBRS.xml +new file mode 100644 +index 0000000000..8bda1c02e2 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-baseline-Haswell-noTSX-IBRS+Skylake-IBRS.xml +@@ -0,0 +1,14 @@ ++ ++ Haswell-noTSX-IBRS ++ Intel ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-baseline-Haswell-noTSX-IBRS+Skylake.xml b/tests/cputestdata/x86_64-cpuid-baseline-Haswell-noTSX-IBRS+Skylake.xml +new file mode 100644 +index 0000000000..651457b17a +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-baseline-Haswell-noTSX-IBRS+Skylake.xml +@@ -0,0 +1,14 @@ ++ ++ Haswell-noTSX ++ Intel ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-baseline-Ryzen+Rome.xml b/tests/cputestdata/x86_64-cpuid-baseline-Ryzen+Rome.xml +new file mode 100644 +index 0000000000..051402b9d5 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-baseline-Ryzen+Rome.xml +@@ -0,0 +1,13 @@ ++ ++ EPYC ++ AMD ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-baseline-Skylake-Client+Server.xml b/tests/cputestdata/x86_64-cpuid-baseline-Skylake-Client+Server.xml +new file mode 100644 +index 0000000000..d46ff26eeb +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-baseline-Skylake-Client+Server.xml +@@ -0,0 +1,9 @@ ++ ++ Skylake-Client ++ Intel ++ ++ ++ ++ ++ ++ +-- +2.35.1 + diff --git a/libvirt-cputest-Drop-some-old-artificial-baseline-tests.patch b/libvirt-cputest-Drop-some-old-artificial-baseline-tests.patch new file mode 100644 index 0000000..997dad8 --- /dev/null +++ b/libvirt-cputest-Drop-some-old-artificial-baseline-tests.patch @@ -0,0 +1,334 @@ +From 50d94f13286ca19ef1f457be72debdbf77547df6 Mon Sep 17 00:00:00 2001 +Message-Id: <50d94f13286ca19ef1f457be72debdbf77547df6@dist-git> +From: Jiri Denemark +Date: Wed, 4 May 2022 16:21:38 +0200 +Subject: [PATCH] cputest: Drop some old artificial baseline tests + +Signed-off-by: Jiri Denemark +Reviewed-by: Michal Privoznik +(cherry picked from commit 6aff36019bbaf643f451779621c6c88cab0e64a7) + +https://bugzilla.redhat.com/show_bug.cgi?id=1851227 + +Signed-off-by: Jiri Denemark +--- + tests/cputest.c | 6 --- + .../cputestdata/x86_64-baseline-1-result.xml | 5 -- + tests/cputestdata/x86_64-baseline-1.xml | 20 -------- + .../cputestdata/x86_64-baseline-2-result.xml | 4 -- + tests/cputestdata/x86_64-baseline-2.xml | 22 --------- + .../x86_64-baseline-5-expanded.xml | 47 ------------------- + .../cputestdata/x86_64-baseline-5-result.xml | 10 ---- + tests/cputestdata/x86_64-baseline-5.xml | 35 -------------- + .../cputestdata/x86_64-baseline-7-result.xml | 4 -- + tests/cputestdata/x86_64-baseline-7.xml | 24 ---------- + .../cputestdata/x86_64-baseline-8-result.xml | 4 -- + tests/cputestdata/x86_64-baseline-8.xml | 28 ----------- + 12 files changed, 209 deletions(-) + delete mode 100644 tests/cputestdata/x86_64-baseline-1-result.xml + delete mode 100644 tests/cputestdata/x86_64-baseline-1.xml + delete mode 100644 tests/cputestdata/x86_64-baseline-2-result.xml + delete mode 100644 tests/cputestdata/x86_64-baseline-2.xml + delete mode 100644 tests/cputestdata/x86_64-baseline-5-expanded.xml + delete mode 100644 tests/cputestdata/x86_64-baseline-5-result.xml + delete mode 100644 tests/cputestdata/x86_64-baseline-5.xml + delete mode 100644 tests/cputestdata/x86_64-baseline-7-result.xml + delete mode 100644 tests/cputestdata/x86_64-baseline-7.xml + delete mode 100644 tests/cputestdata/x86_64-baseline-8-result.xml + delete mode 100644 tests/cputestdata/x86_64-baseline-8.xml + +diff --git a/tests/cputest.c b/tests/cputest.c +index 0f0621292a..20d56836be 100644 +--- a/tests/cputest.c ++++ b/tests/cputest.c +@@ -1051,18 +1051,12 @@ mymain(void) + DO_TEST_BASELINE(VIR_ARCH_X86_64, "incompatible-vendors", 0, -1); + DO_TEST_BASELINE(VIR_ARCH_X86_64, "no-vendor", 0, 0); + DO_TEST_BASELINE(VIR_ARCH_X86_64, "some-vendors", 0, 0); +- DO_TEST_BASELINE(VIR_ARCH_X86_64, "1", 0, 0); +- DO_TEST_BASELINE(VIR_ARCH_X86_64, "2", 0, 0); + DO_TEST_BASELINE(VIR_ARCH_X86_64, "3", 0, 0); + DO_TEST_BASELINE(VIR_ARCH_X86_64, "3", VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES, 0); + DO_TEST_BASELINE(VIR_ARCH_X86_64, "4", 0, 0); + DO_TEST_BASELINE(VIR_ARCH_X86_64, "4", VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES, 0); +- DO_TEST_BASELINE(VIR_ARCH_X86_64, "5", 0, 0); +- DO_TEST_BASELINE(VIR_ARCH_X86_64, "5", VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES, 0); + DO_TEST_BASELINE(VIR_ARCH_X86_64, "6", 0, 0); + DO_TEST_BASELINE(VIR_ARCH_X86_64, "6", VIR_CONNECT_BASELINE_CPU_MIGRATABLE, 0); +- DO_TEST_BASELINE(VIR_ARCH_X86_64, "7", 0, 0); +- DO_TEST_BASELINE(VIR_ARCH_X86_64, "8", 0, 0); + + DO_TEST_BASELINE(VIR_ARCH_PPC64, "incompatible-vendors", 0, -1); + DO_TEST_BASELINE(VIR_ARCH_PPC64, "no-vendor", 0, 0); +diff --git a/tests/cputestdata/x86_64-baseline-1-result.xml b/tests/cputestdata/x86_64-baseline-1-result.xml +deleted file mode 100644 +index 96c4f43b3d..0000000000 +--- a/tests/cputestdata/x86_64-baseline-1-result.xml ++++ /dev/null +@@ -1,5 +0,0 @@ +- +- Conroe +- Intel +- +- +diff --git a/tests/cputestdata/x86_64-baseline-1.xml b/tests/cputestdata/x86_64-baseline-1.xml +deleted file mode 100644 +index 509e6a85d2..0000000000 +--- a/tests/cputestdata/x86_64-baseline-1.xml ++++ /dev/null +@@ -1,20 +0,0 @@ +- +- +- x86_64 +- Penryn +- Intel +- +- +- +- x86_64 +- Conroe +- Intel +- +- +- +- x86_64 +- core2duo +- Intel +- +- +- +diff --git a/tests/cputestdata/x86_64-baseline-2-result.xml b/tests/cputestdata/x86_64-baseline-2-result.xml +deleted file mode 100644 +index a11352d0b1..0000000000 +--- a/tests/cputestdata/x86_64-baseline-2-result.xml ++++ /dev/null +@@ -1,4 +0,0 @@ +- +- core2duo +- +- +diff --git a/tests/cputestdata/x86_64-baseline-2.xml b/tests/cputestdata/x86_64-baseline-2.xml +deleted file mode 100644 +index 055223fd34..0000000000 +--- a/tests/cputestdata/x86_64-baseline-2.xml ++++ /dev/null +@@ -1,22 +0,0 @@ +- +- +- x86_64 +- core2duo +- +- +- +- x86_64 +- pentiumpro +- +- +- +- +- +- +- +- +- +- +- +- +- +diff --git a/tests/cputestdata/x86_64-baseline-5-expanded.xml b/tests/cputestdata/x86_64-baseline-5-expanded.xml +deleted file mode 100644 +index 2c1b400150..0000000000 +--- a/tests/cputestdata/x86_64-baseline-5-expanded.xml ++++ /dev/null +@@ -1,47 +0,0 @@ +- +- SandyBridge +- Intel +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +diff --git a/tests/cputestdata/x86_64-baseline-5-result.xml b/tests/cputestdata/x86_64-baseline-5-result.xml +deleted file mode 100644 +index 775a27de2e..0000000000 +--- a/tests/cputestdata/x86_64-baseline-5-result.xml ++++ /dev/null +@@ -1,10 +0,0 @@ +- +- SandyBridge +- Intel +- +- +- +- +- +- +- +diff --git a/tests/cputestdata/x86_64-baseline-5.xml b/tests/cputestdata/x86_64-baseline-5.xml +deleted file mode 100644 +index 80cd533ca4..0000000000 +--- a/tests/cputestdata/x86_64-baseline-5.xml ++++ /dev/null +@@ -1,35 +0,0 @@ +- +- +- x86_64 +- Westmere +- Intel +- +- +- +- +- +- +- +- +- +- +- +- +- +- x86_64 +- Nehalem +- Intel +- +- +- +- +- +- +- +- +- +- +- +- +- +- +diff --git a/tests/cputestdata/x86_64-baseline-7-result.xml b/tests/cputestdata/x86_64-baseline-7-result.xml +deleted file mode 100644 +index 2af549e77a..0000000000 +--- a/tests/cputestdata/x86_64-baseline-7-result.xml ++++ /dev/null +@@ -1,4 +0,0 @@ +- +- Haswell-noTSX +- Intel +- +diff --git a/tests/cputestdata/x86_64-baseline-7.xml b/tests/cputestdata/x86_64-baseline-7.xml +deleted file mode 100644 +index b7e61b160c..0000000000 +--- a/tests/cputestdata/x86_64-baseline-7.xml ++++ /dev/null +@@ -1,24 +0,0 @@ +- +- +- x86_64 +- SandyBridge +- Intel +- +- +- +- +- +- +- +- +- +- +- +- +- +- x86_64 +- Haswell-noTSX +- Intel +- +- +- +diff --git a/tests/cputestdata/x86_64-baseline-8-result.xml b/tests/cputestdata/x86_64-baseline-8-result.xml +deleted file mode 100644 +index 88226b3dab..0000000000 +--- a/tests/cputestdata/x86_64-baseline-8-result.xml ++++ /dev/null +@@ -1,4 +0,0 @@ +- +- Broadwell-noTSX +- Intel +- +diff --git a/tests/cputestdata/x86_64-baseline-8.xml b/tests/cputestdata/x86_64-baseline-8.xml +deleted file mode 100644 +index f1ee67d542..0000000000 +--- a/tests/cputestdata/x86_64-baseline-8.xml ++++ /dev/null +@@ -1,28 +0,0 @@ +- +- +- x86_64 +- SandyBridge +- Intel +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- x86_64 +- Broadwell-noTSX +- Intel +- +- +- +-- +2.35.1 + diff --git a/libvirt-cputest-Give-better-names-to-baseline-tests.patch b/libvirt-cputest-Give-better-names-to-baseline-tests.patch new file mode 100644 index 0000000..ece2b12 --- /dev/null +++ b/libvirt-cputest-Give-better-names-to-baseline-tests.patch @@ -0,0 +1,97 @@ +From 6cf9cd8f6d9e90eadd58d8a37129e7401876e4e8 Mon Sep 17 00:00:00 2001 +Message-Id: <6cf9cd8f6d9e90eadd58d8a37129e7401876e4e8@dist-git> +From: Jiri Denemark +Date: Wed, 4 May 2022 16:28:03 +0200 +Subject: [PATCH] cputest: Give better names to baseline tests + +Signed-off-by: Jiri Denemark +Reviewed-by: Michal Privoznik +(cherry picked from commit 3daa68e26514dc114d71f4c44f7d728e93a53cd0) + +https://bugzilla.redhat.com/show_bug.cgi?id=1851227 + +Signed-off-by: Jiri Denemark +--- + tests/cputest.c | 12 ++++++------ + ... x86_64-baseline-Westmere+Nehalem-migratable.xml} | 0 + ...l => x86_64-baseline-Westmere+Nehalem-result.xml} | 0 + ...ne-6.xml => x86_64-baseline-Westmere+Nehalem.xml} | 0 + ...ded.xml => x86_64-baseline-features-expanded.xml} | 0 + ...esult.xml => x86_64-baseline-features-result.xml} | 0 + ...4-baseline-4.xml => x86_64-baseline-features.xml} | 0 + ...anded.xml => x86_64-baseline-simple-expanded.xml} | 0 + ...-result.xml => x86_64-baseline-simple-result.xml} | 0 + ..._64-baseline-3.xml => x86_64-baseline-simple.xml} | 0 + 10 files changed, 6 insertions(+), 6 deletions(-) + rename tests/cputestdata/{x86_64-baseline-6-migratable.xml => x86_64-baseline-Westmere+Nehalem-migratable.xml} (100%) + rename tests/cputestdata/{x86_64-baseline-6-result.xml => x86_64-baseline-Westmere+Nehalem-result.xml} (100%) + rename tests/cputestdata/{x86_64-baseline-6.xml => x86_64-baseline-Westmere+Nehalem.xml} (100%) + rename tests/cputestdata/{x86_64-baseline-4-expanded.xml => x86_64-baseline-features-expanded.xml} (100%) + rename tests/cputestdata/{x86_64-baseline-4-result.xml => x86_64-baseline-features-result.xml} (100%) + rename tests/cputestdata/{x86_64-baseline-4.xml => x86_64-baseline-features.xml} (100%) + rename tests/cputestdata/{x86_64-baseline-3-expanded.xml => x86_64-baseline-simple-expanded.xml} (100%) + rename tests/cputestdata/{x86_64-baseline-3-result.xml => x86_64-baseline-simple-result.xml} (100%) + rename tests/cputestdata/{x86_64-baseline-3.xml => x86_64-baseline-simple.xml} (100%) + +diff --git a/tests/cputest.c b/tests/cputest.c +index 20d56836be..b939e20718 100644 +--- a/tests/cputest.c ++++ b/tests/cputest.c +@@ -1051,12 +1051,12 @@ mymain(void) + DO_TEST_BASELINE(VIR_ARCH_X86_64, "incompatible-vendors", 0, -1); + DO_TEST_BASELINE(VIR_ARCH_X86_64, "no-vendor", 0, 0); + DO_TEST_BASELINE(VIR_ARCH_X86_64, "some-vendors", 0, 0); +- DO_TEST_BASELINE(VIR_ARCH_X86_64, "3", 0, 0); +- DO_TEST_BASELINE(VIR_ARCH_X86_64, "3", VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES, 0); +- DO_TEST_BASELINE(VIR_ARCH_X86_64, "4", 0, 0); +- DO_TEST_BASELINE(VIR_ARCH_X86_64, "4", VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES, 0); +- DO_TEST_BASELINE(VIR_ARCH_X86_64, "6", 0, 0); +- DO_TEST_BASELINE(VIR_ARCH_X86_64, "6", VIR_CONNECT_BASELINE_CPU_MIGRATABLE, 0); ++ DO_TEST_BASELINE(VIR_ARCH_X86_64, "simple", 0, 0); ++ DO_TEST_BASELINE(VIR_ARCH_X86_64, "simple", VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES, 0); ++ DO_TEST_BASELINE(VIR_ARCH_X86_64, "features", 0, 0); ++ DO_TEST_BASELINE(VIR_ARCH_X86_64, "features", VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES, 0); ++ DO_TEST_BASELINE(VIR_ARCH_X86_64, "Westmere+Nehalem", 0, 0); ++ DO_TEST_BASELINE(VIR_ARCH_X86_64, "Westmere+Nehalem", VIR_CONNECT_BASELINE_CPU_MIGRATABLE, 0); + + DO_TEST_BASELINE(VIR_ARCH_PPC64, "incompatible-vendors", 0, -1); + DO_TEST_BASELINE(VIR_ARCH_PPC64, "no-vendor", 0, 0); +diff --git a/tests/cputestdata/x86_64-baseline-6-migratable.xml b/tests/cputestdata/x86_64-baseline-Westmere+Nehalem-migratable.xml +similarity index 100% +rename from tests/cputestdata/x86_64-baseline-6-migratable.xml +rename to tests/cputestdata/x86_64-baseline-Westmere+Nehalem-migratable.xml +diff --git a/tests/cputestdata/x86_64-baseline-6-result.xml b/tests/cputestdata/x86_64-baseline-Westmere+Nehalem-result.xml +similarity index 100% +rename from tests/cputestdata/x86_64-baseline-6-result.xml +rename to tests/cputestdata/x86_64-baseline-Westmere+Nehalem-result.xml +diff --git a/tests/cputestdata/x86_64-baseline-6.xml b/tests/cputestdata/x86_64-baseline-Westmere+Nehalem.xml +similarity index 100% +rename from tests/cputestdata/x86_64-baseline-6.xml +rename to tests/cputestdata/x86_64-baseline-Westmere+Nehalem.xml +diff --git a/tests/cputestdata/x86_64-baseline-4-expanded.xml b/tests/cputestdata/x86_64-baseline-features-expanded.xml +similarity index 100% +rename from tests/cputestdata/x86_64-baseline-4-expanded.xml +rename to tests/cputestdata/x86_64-baseline-features-expanded.xml +diff --git a/tests/cputestdata/x86_64-baseline-4-result.xml b/tests/cputestdata/x86_64-baseline-features-result.xml +similarity index 100% +rename from tests/cputestdata/x86_64-baseline-4-result.xml +rename to tests/cputestdata/x86_64-baseline-features-result.xml +diff --git a/tests/cputestdata/x86_64-baseline-4.xml b/tests/cputestdata/x86_64-baseline-features.xml +similarity index 100% +rename from tests/cputestdata/x86_64-baseline-4.xml +rename to tests/cputestdata/x86_64-baseline-features.xml +diff --git a/tests/cputestdata/x86_64-baseline-3-expanded.xml b/tests/cputestdata/x86_64-baseline-simple-expanded.xml +similarity index 100% +rename from tests/cputestdata/x86_64-baseline-3-expanded.xml +rename to tests/cputestdata/x86_64-baseline-simple-expanded.xml +diff --git a/tests/cputestdata/x86_64-baseline-3-result.xml b/tests/cputestdata/x86_64-baseline-simple-result.xml +similarity index 100% +rename from tests/cputestdata/x86_64-baseline-3-result.xml +rename to tests/cputestdata/x86_64-baseline-simple-result.xml +diff --git a/tests/cputestdata/x86_64-baseline-3.xml b/tests/cputestdata/x86_64-baseline-simple.xml +similarity index 100% +rename from tests/cputestdata/x86_64-baseline-3.xml +rename to tests/cputestdata/x86_64-baseline-simple.xml +-- +2.35.1 + diff --git a/libvirt-domain_validate-Split-out-validation-of-disk-startup-policy.patch b/libvirt-domain_validate-Split-out-validation-of-disk-startup-policy.patch new file mode 100644 index 0000000..f9c61bb --- /dev/null +++ b/libvirt-domain_validate-Split-out-validation-of-disk-startup-policy.patch @@ -0,0 +1,111 @@ +From 296343c5a950668d790f9cd5ebd7b466e8156d03 Mon Sep 17 00:00:00 2001 +Message-Id: <296343c5a950668d790f9cd5ebd7b466e8156d03@dist-git> +From: Peter Krempa +Date: Tue, 14 Jun 2022 13:23:29 +0200 +Subject: [PATCH] domain_validate: Split out validation of disk startup policy +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Move the code into 'virDomainDiskDefValidateStartupPolicy' which will be +later reused in the qemu driver. + +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +(cherry picked from commit 3603a18bcec18842cedecbd8329723062b87795c) +https://bugzilla.redhat.com/show_bug.cgi?id=2095758 +--- + src/conf/domain_validate.c | 45 ++++++++++++++++++++++++-------------- + src/conf/domain_validate.h | 2 ++ + src/libvirt_private.syms | 1 + + 3 files changed, 31 insertions(+), 17 deletions(-) + +diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c +index 452742e67c..bfff7339ef 100644 +--- a/src/conf/domain_validate.c ++++ b/src/conf/domain_validate.c +@@ -598,6 +598,32 @@ virDomainDiskDefSourceLUNValidate(const virStorageSource *src) + } + + ++int ++virDomainDiskDefValidateStartupPolicy(const virDomainDiskDef *disk) ++{ ++ if (disk->startupPolicy == VIR_DOMAIN_STARTUP_POLICY_DEFAULT) ++ return 0; ++ ++ if (disk->src->type == VIR_STORAGE_TYPE_NETWORK) { ++ virReportError(VIR_ERR_XML_ERROR, ++ _("disk startupPolicy '%s' is not allowed for disk of '%s' type"), ++ virDomainStartupPolicyTypeToString(disk->startupPolicy), ++ virStorageTypeToString(disk->src->type)); ++ return -1; ++ } ++ ++ if (disk->device != VIR_DOMAIN_DISK_DEVICE_CDROM && ++ disk->device != VIR_DOMAIN_DISK_DEVICE_FLOPPY && ++ disk->startupPolicy == VIR_DOMAIN_STARTUP_POLICY_REQUISITE) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("disk startupPolicy 'requisite' is allowed only for cdrom or floppy")); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ + static int + virDomainDiskDefValidate(const virDomainDef *def, + const virDomainDiskDef *disk) +@@ -775,23 +801,8 @@ virDomainDiskDefValidate(const virDomainDef *def, + return -1; + } + +- if (disk->startupPolicy != VIR_DOMAIN_STARTUP_POLICY_DEFAULT) { +- if (disk->src->type == VIR_STORAGE_TYPE_NETWORK) { +- virReportError(VIR_ERR_XML_ERROR, +- _("disk startupPolicy '%s' is not allowed for disk of '%s' type"), +- virDomainStartupPolicyTypeToString(disk->startupPolicy), +- virStorageTypeToString(disk->src->type)); +- return -1; +- } +- +- if (disk->device != VIR_DOMAIN_DISK_DEVICE_CDROM && +- disk->device != VIR_DOMAIN_DISK_DEVICE_FLOPPY && +- disk->startupPolicy == VIR_DOMAIN_STARTUP_POLICY_REQUISITE) { +- virReportError(VIR_ERR_XML_ERROR, "%s", +- _("disk startupPolicy 'requisite' is allowed only for cdrom or floppy")); +- return -1; +- } +- } ++ if (virDomainDiskDefValidateStartupPolicy(disk) < 0) ++ return -1; + + if (disk->wwn && !virValidateWWN(disk->wwn)) + return -1; +diff --git a/src/conf/domain_validate.h b/src/conf/domain_validate.h +index 430d61fd3c..07b99195e3 100644 +--- a/src/conf/domain_validate.h ++++ b/src/conf/domain_validate.h +@@ -41,4 +41,6 @@ int virDomainDeviceDefValidate(const virDomainDeviceDef *dev, + + int virDomainDiskDefValidateSource(const virStorageSource *src); + ++int virDomainDiskDefValidateStartupPolicy(const virDomainDiskDef *disk); ++ + int virDomainDiskDefSourceLUNValidate(const virStorageSource *src); +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 2c42e2a5e8..5b7a056151 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -777,6 +777,7 @@ virDomainActualNetDefValidate; + virDomainDefValidate; + virDomainDeviceValidateAliasForHotplug; + virDomainDiskDefSourceLUNValidate; ++virDomainDiskDefValidateStartupPolicy; + + + # conf/interface_conf.h +-- +2.35.1 + diff --git a/libvirt-nwfilter-fix-crash-when-counting-number-of-network-filters.patch b/libvirt-nwfilter-fix-crash-when-counting-number-of-network-filters.patch new file mode 100644 index 0000000..3e5c4f3 --- /dev/null +++ b/libvirt-nwfilter-fix-crash-when-counting-number-of-network-filters.patch @@ -0,0 +1,55 @@ +From dc6ab8b51ff53ba22abfb84f24641aa87320038a Mon Sep 17 00:00:00 2001 +Message-Id: +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Tue, 8 Mar 2022 17:28:38 +0000 +Subject: [PATCH] nwfilter: fix crash when counting number of network filters +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The virNWFilterObjListNumOfNWFilters method iterates over the +driver->nwfilters, accessing virNWFilterObj instances. As such +it needs to be protected against concurrent modification of +the driver->nwfilters object. + +This API allows unprivileged users to connect, so users with +read-only access to libvirt can cause a denial of service +crash if they are able to race with a call of virNWFilterUndefine. +Since network filters are usually statically defined, this is +considered a low severity problem. + +This is assigned CVE-2022-0897. + +Reviewed-by: Eric Blake +Signed-off-by: Daniel P. Berrangé +(cherry picked from commit a4947e8f63c3e6b7b067b444f3d6cf674c0d7f36) +https://bugzilla.redhat.com/show_bug.cgi?id=2063902 +--- + src/nwfilter/nwfilter_driver.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/nwfilter/nwfilter_driver.c b/src/nwfilter/nwfilter_driver.c +index 200451d6b1..956aca6421 100644 +--- a/src/nwfilter/nwfilter_driver.c ++++ b/src/nwfilter/nwfilter_driver.c +@@ -478,11 +478,15 @@ nwfilterLookupByName(virConnectPtr conn, + static int + nwfilterConnectNumOfNWFilters(virConnectPtr conn) + { ++ int ret; + if (virConnectNumOfNWFiltersEnsureACL(conn) < 0) + return -1; + +- return virNWFilterObjListNumOfNWFilters(driver->nwfilters, conn, +- virConnectNumOfNWFiltersCheckACL); ++ nwfilterDriverLock(); ++ ret = virNWFilterObjListNumOfNWFilters(driver->nwfilters, conn, ++ virConnectNumOfNWFiltersCheckACL); ++ nwfilterDriverUnlock(); ++ return ret; + } + + +-- +2.35.1 + diff --git a/libvirt-qemu-Add-qemuDomainSetMaxMemLock-helper.patch b/libvirt-qemu-Add-qemuDomainSetMaxMemLock-helper.patch new file mode 100644 index 0000000..1bb549c --- /dev/null +++ b/libvirt-qemu-Add-qemuDomainSetMaxMemLock-helper.patch @@ -0,0 +1,155 @@ +From 2595c7716b19214b2729b41b86656f96a2cd18bc Mon Sep 17 00:00:00 2001 +Message-Id: <2595c7716b19214b2729b41b86656f96a2cd18bc@dist-git> +From: Jiri Denemark +Date: Wed, 22 Jun 2022 15:21:30 +0200 +Subject: [PATCH] qemu: Add qemuDomainSetMaxMemLock helper +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +qemuDomainAdjustMaxMemLock combined computing the desired limit with +applying it. This patch separates the code to apply a memory locking +limit to a new qemuDomainSetMaxMemLock helper for better reusability. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit dff51c7f5760ded8235076f55d082fe4363f2f78) + +https://bugzilla.redhat.com/show_bug.cgi?id=2089433 + +Signed-off-by: Jiri Denemark +--- + src/qemu/qemu_domain.c | 95 ++++++++++++++++++++++++++---------------- + src/qemu/qemu_domain.h | 3 ++ + 2 files changed, 61 insertions(+), 37 deletions(-) + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index ee7d310903..a81789f194 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -9261,6 +9261,61 @@ qemuDomainGetMemLockLimitBytes(virDomainDef *def, + } + + ++/** ++ * qemuDomainSetMaxMemLock: ++ * @vm: domain ++ * @limit: the desired memory locking limit ++ * @origPtr: where to store (or load from) the original value of the limit ++ * ++ * Set the memory locking limit for @vm unless it's already big enough. If ++ * @origPtr is non-NULL, the original value of the limit will be store there ++ * and can be restored by calling this function with @limit == 0. ++ * ++ * Returns: 0 on success, -1 otherwise. ++ */ ++int ++qemuDomainSetMaxMemLock(virDomainObj *vm, ++ unsigned long long limit, ++ unsigned long long *origPtr) ++{ ++ unsigned long long current = 0; ++ ++ if (virProcessGetMaxMemLock(vm->pid, ¤t) < 0) ++ return -1; ++ ++ if (limit > 0) { ++ VIR_DEBUG("Requested memory lock limit: %llu", limit); ++ /* If the limit is already high enough, we can assume ++ * that some external process is taking care of managing ++ * process limits and we shouldn't do anything ourselves: ++ * we're probably running in a containerized environment ++ * where we don't have enough privilege anyway */ ++ if (current >= limit) { ++ VIR_DEBUG("Current limit %llu is big enough", current); ++ return 0; ++ } ++ ++ /* If this is the first time adjusting the limit, save the current ++ * value so that we can restore it once memory locking is no longer ++ * required */ ++ if (origPtr && *origPtr == 0) ++ *origPtr = current; ++ } else { ++ /* Once memory locking is no longer required, we can restore the ++ * original, usually very low, limit. But only if we actually stored ++ * the original limit before. */ ++ if (!origPtr || *origPtr == 0) ++ return 0; ++ ++ limit = *origPtr; ++ *origPtr = 0; ++ VIR_DEBUG("Resetting memory lock limit back to %llu", limit); ++ } ++ ++ return virProcessSetMaxMemLock(vm->pid, limit); ++} ++ ++ + /** + * qemuDomainAdjustMaxMemLock: + * @vm: domain +@@ -9282,43 +9337,9 @@ int + qemuDomainAdjustMaxMemLock(virDomainObj *vm, + bool forceVFIO) + { +- qemuDomainObjPrivate *priv = vm->privateData; +- unsigned long long currentMemLock = 0; +- unsigned long long desiredMemLock = 0; +- +- desiredMemLock = qemuDomainGetMemLockLimitBytes(vm->def, forceVFIO); +- if (virProcessGetMaxMemLock(vm->pid, ¤tMemLock) < 0) +- return -1; +- +- if (desiredMemLock > 0) { +- if (currentMemLock < desiredMemLock) { +- /* If this is the first time adjusting the limit, save the current +- * value so that we can restore it once memory locking is no longer +- * required */ +- if (priv->originalMemlock == 0) { +- priv->originalMemlock = currentMemLock; +- } +- } else { +- /* If the limit is already high enough, we can assume +- * that some external process is taking care of managing +- * process limits and we shouldn't do anything ourselves: +- * we're probably running in a containerized environment +- * where we don't have enough privilege anyway */ +- desiredMemLock = 0; +- } +- } else { +- /* Once memory locking is no longer required, we can restore the +- * original, usually very low, limit */ +- desiredMemLock = priv->originalMemlock; +- priv->originalMemlock = 0; +- } +- +- if (desiredMemLock > 0 && +- virProcessSetMaxMemLock(vm->pid, desiredMemLock) < 0) { +- return -1; +- } +- +- return 0; ++ return qemuDomainSetMaxMemLock(vm, ++ qemuDomainGetMemLockLimitBytes(vm->def, forceVFIO), ++ &QEMU_DOMAIN_PRIVATE(vm)->originalMemlock); + } + + +diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h +index e9497d20de..6d1d23439a 100644 +--- a/src/qemu/qemu_domain.h ++++ b/src/qemu/qemu_domain.h +@@ -789,6 +789,9 @@ int qemuDomainAdjustMaxMemLock(virDomainObj *vm, + bool forceVFIO); + int qemuDomainAdjustMaxMemLockHostdev(virDomainObj *vm, + virDomainHostdevDef *hostdev); ++int qemuDomainSetMaxMemLock(virDomainObj *vm, ++ unsigned long long limit, ++ unsigned long long *origPtr); + + int qemuDomainDefValidateMemoryHotplug(const virDomainDef *def, + const virDomainMemoryDef *mem); +-- +2.35.1 + diff --git a/libvirt-qemu-Ignore-missing-vm.unprivileged_userfaultfd-sysctl.patch b/libvirt-qemu-Ignore-missing-vm.unprivileged_userfaultfd-sysctl.patch new file mode 100644 index 0000000..0113c82 --- /dev/null +++ b/libvirt-qemu-Ignore-missing-vm.unprivileged_userfaultfd-sysctl.patch @@ -0,0 +1,38 @@ +From 08fef741d85ecfb3493c47f5f1334f91c30e3233 Mon Sep 17 00:00:00 2001 +Message-Id: <08fef741d85ecfb3493c47f5f1334f91c30e3233@dist-git> +From: Jiri Denemark +Date: Wed, 9 Feb 2022 11:08:42 +0100 +Subject: [PATCH] qemu: Ignore missing vm.unprivileged_userfaultfd sysctl +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Older kernels did not support this sysctl, but they did not restrict +userfaultfd in any way so everything worked as if +vm.unprivileged_userfaultfd was set to 1. Thus we can safely ignore +errors when setting the value. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 558f00397a0d46ad22bf53a22a40ed6fc4fdb5eb) + +https://bugzilla.redhat.com/show_bug.cgi?id=2148578 + +Signed-off-by: Jiri Denemark +--- + src/qemu/postcopy-migration.sysctl | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/qemu/postcopy-migration.sysctl b/src/qemu/postcopy-migration.sysctl +index aa8f015ae0..db3f11e49f 100644 +--- a/src/qemu/postcopy-migration.sysctl ++++ b/src/qemu/postcopy-migration.sysctl +@@ -3,4 +3,4 @@ + # privileged processes. + # It can be safely overridden by a file in /etc/sysctl.d/ in case post-copy + # migration is not used on the host. +-vm.unprivileged_userfaultfd = 1 ++-vm.unprivileged_userfaultfd = 1 +-- +2.39.0 + diff --git a/libvirt-qemu-gpu-Get-pid-without-binary-validation.patch b/libvirt-qemu-gpu-Get-pid-without-binary-validation.patch new file mode 100644 index 0000000..9b31b4b --- /dev/null +++ b/libvirt-qemu-gpu-Get-pid-without-binary-validation.patch @@ -0,0 +1,67 @@ +From c70b1a8d8a4bc34bcbf9ef4bccac678257b8c494 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Vasiliy Ulyanov +Date: Wed, 2 Feb 2022 17:28:17 +0100 +Subject: [PATCH] qemu: gpu: Get pid without binary validation + +The binary validation in virPidFileReadPathIfAlive may fail with EACCES +if the calling process does not have CAP_SYS_PTRACE capability. +Therefore instead do only the check that the pidfile is locked by the +correct process. + +Fixes the same issue as with swtpm. + +Signed-off-by: Vasiliy Ulyanov +Signed-off-by: Michal Privoznik +Reviewed-by: Michal Privoznik +(cherry picked from commit e3dfa52d260da8a41a0ec35767d08e37c825824a) +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2152188 +Signed-off-by: Michal Privoznik +--- + src/qemu/qemu_vhost_user_gpu.c | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +diff --git a/src/qemu/qemu_vhost_user_gpu.c b/src/qemu/qemu_vhost_user_gpu.c +index ef198a4820..f7d444e851 100644 +--- a/src/qemu/qemu_vhost_user_gpu.c ++++ b/src/qemu/qemu_vhost_user_gpu.c +@@ -54,7 +54,6 @@ qemuVhostUserGPUCreatePidFilename(const char *stateDir, + + /* + * qemuVhostUserGPUGetPid: +- * @binpath: path of executable associated with the pidfile + * @stateDir: the directory where vhost-user-gpu writes the pidfile into + * @shortName: short name of the domain + * @alias: video device alias +@@ -65,8 +64,7 @@ qemuVhostUserGPUCreatePidFilename(const char *stateDir, + * set to -1; + */ + static int +-qemuVhostUserGPUGetPid(const char *binPath, +- const char *stateDir, ++qemuVhostUserGPUGetPid(const char *stateDir, + const char *shortName, + const char *alias, + pid_t *pid) +@@ -76,7 +74,7 @@ qemuVhostUserGPUGetPid(const char *binPath, + if (!(pidfile = qemuVhostUserGPUCreatePidFilename(stateDir, shortName, alias))) + return -1; + +- if (virPidFileReadPathIfAlive(pidfile, pid, binPath) < 0) ++ if (virPidFileReadPathIfLocked(pidfile, pid) < 0) + return -1; + + return 0; +@@ -253,8 +251,7 @@ qemuExtVhostUserGPUSetupCgroup(virQEMUDriver *driver, + if (!shortname) + return -1; + +- rc = qemuVhostUserGPUGetPid(video->driver->vhost_user_binary, +- cfg->stateDir, shortname, video->info.alias, &pid); ++ rc = qemuVhostUserGPUGetPid(cfg->stateDir, shortname, video->info.alias, &pid); + if (rc < 0 || (rc == 0 && pid == (pid_t)-1)) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not get process id of vhost-user-gpu")); +-- +2.39.0 + diff --git a/libvirt-qemu-tpm-Get-swtpm-pid-without-binary-validation.patch b/libvirt-qemu-tpm-Get-swtpm-pid-without-binary-validation.patch new file mode 100644 index 0000000..35c8459 --- /dev/null +++ b/libvirt-qemu-tpm-Get-swtpm-pid-without-binary-validation.patch @@ -0,0 +1,219 @@ +From e3487aab5319df05c5a06a83e4d3e4a87c1e51a9 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Vasiliy Ulyanov +Date: Wed, 2 Feb 2022 17:28:16 +0100 +Subject: [PATCH] qemu: tpm: Get swtpm pid without binary validation + +Access to /proc/[pid]/exe may be restricted in certain environments (e.g. +in containers) and any attempt to stat(2) or readlink(2) the file will +result in 'permission denied' error if the calling process does not have +CAP_SYS_PTRACE capability. According to proc(5) manpage: + +Permission to dereference or read (readlink(2)) this symbolic link is +governed by a ptrace access mode PTRACE_MODE_READ_FSCREDS check; see +ptrace(2). + +The binary validation in virPidFileReadPathIfAlive may fail with EACCES. +Therefore instead do only the check that the pidfile is locked by the +correct process. To ensure this is always the case the daemonization and +pidfile handling of the swtpm command is now controlled by libvirt. + +Signed-off-by: Vasiliy Ulyanov +Signed-off-by: Michal Privoznik +Reviewed-by: Michal Privoznik +(cherry picked from commit a9c500d2b50c5c041a1bb6ae9724402cf1cec8fe) +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2152188 +Signed-off-by: Michal Privoznik +--- + src/qemu/qemu_tpm.c | 94 ++++++++++++++++++++++++++------------------- + 1 file changed, 54 insertions(+), 40 deletions(-) + +diff --git a/src/qemu/qemu_tpm.c b/src/qemu/qemu_tpm.c +index 7e7b01768e..9c5d1ffed4 100644 +--- a/src/qemu/qemu_tpm.c ++++ b/src/qemu/qemu_tpm.c +@@ -44,6 +44,7 @@ + #include "qemu_tpm.h" + #include "virtpm.h" + #include "virsecret.h" ++#include "virtime.h" + + #define VIR_FROM_THIS VIR_FROM_NONE + +@@ -258,13 +259,13 @@ qemuTPMEmulatorGetPid(const char *swtpmStateDir, + const char *shortName, + pid_t *pid) + { +- g_autofree char *swtpm = virTPMGetSwtpm(); + g_autofree char *pidfile = qemuTPMEmulatorCreatePidFilename(swtpmStateDir, + shortName); ++ + if (!pidfile) + return -1; + +- if (virPidFileReadPathIfAlive(pidfile, pid, swtpm) < 0) ++ if (virPidFileReadPathIfLocked(pidfile, pid) < 0) + return -1; + + return 0; +@@ -660,9 +661,6 @@ qemuTPMEmulatorReconfigure(const char *storagepath, + * @privileged: whether we are running in privileged mode + * @swtpm_user: The uid for the swtpm to run as (drop privileges to from root) + * @swtpm_group: The gid for the swtpm to run as +- * @swtpmStateDir: the directory where swtpm writes the pid file and creates the +- * Unix socket +- * @shortName: the short name of the VM + * @incomingMigration: whether we have an incoming migration + * + * Create the virCommand use for starting the emulator +@@ -676,13 +674,10 @@ qemuTPMEmulatorBuildCommand(virDomainTPMDef *tpm, + bool privileged, + uid_t swtpm_user, + gid_t swtpm_group, +- const char *swtpmStateDir, +- const char *shortName, + bool incomingMigration) + { + g_autoptr(virCommand) cmd = NULL; + bool created = false; +- g_autofree char *pidfile = NULL; + g_autofree char *swtpm = virTPMGetSwtpm(); + int pwdfile_fd = -1; + int migpwdfile_fd = -1; +@@ -721,7 +716,7 @@ qemuTPMEmulatorBuildCommand(virDomainTPMDef *tpm, + + virCommandClearCaps(cmd); + +- virCommandAddArgList(cmd, "socket", "--daemon", "--ctrl", NULL); ++ virCommandAddArgList(cmd, "socket", "--ctrl", NULL); + virCommandAddArgFormat(cmd, "type=unixio,path=%s,mode=0600", + tpm->data.emulator.source->data.nix.path); + +@@ -748,12 +743,6 @@ qemuTPMEmulatorBuildCommand(virDomainTPMDef *tpm, + break; + } + +- if (!(pidfile = qemuTPMEmulatorCreatePidFilename(swtpmStateDir, shortName))) +- goto error; +- +- virCommandAddArg(cmd, "--pid"); +- virCommandAddArgFormat(cmd, "file=%s", pidfile); +- + if (tpm->data.emulator.hassecretuuid) { + if (!virTPMSwtpmCapsGet(VIR_TPM_SWTPM_FEATURE_CMDARG_PWD_FD)) { + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, +@@ -904,12 +893,14 @@ qemuExtTPMStartEmulator(virQEMUDriver *driver, + bool incomingMigration) + { + g_autoptr(virCommand) cmd = NULL; +- int exitstatus = 0; +- g_autofree char *errbuf = NULL; ++ VIR_AUTOCLOSE errfd = -1; + g_autoptr(virQEMUDriverConfig) cfg = NULL; + g_autofree char *shortName = virDomainDefGetShortName(vm->def); +- int cmdret = 0, timeout, rc; +- pid_t pid; ++ g_autofree char *pidfile = NULL; ++ virTimeBackOffVar timebackoff; ++ const unsigned long long timeout = 1000; /* ms */ ++ int cmdret = 0; ++ pid_t pid = -1; + + if (!shortName) + return -1; +@@ -923,48 +914,71 @@ qemuExtTPMStartEmulator(virQEMUDriver *driver, + driver->privileged, + cfg->swtpm_user, + cfg->swtpm_group, +- cfg->swtpmStateDir, shortName, + incomingMigration))) + return -1; + + if (qemuExtDeviceLogCommand(driver, vm, cmd, "TPM Emulator") < 0) + return -1; + +- virCommandSetErrorBuffer(cmd, &errbuf); ++ if (!(pidfile = qemuTPMEmulatorCreatePidFilename(cfg->swtpmStateDir, shortName))) ++ return -1; ++ ++ virCommandDaemonize(cmd); ++ virCommandSetPidFile(cmd, pidfile); ++ virCommandSetErrorFD(cmd, &errfd); + + if (qemuSecurityStartTPMEmulator(driver, vm, cmd, + cfg->swtpm_user, cfg->swtpm_group, +- &exitstatus, &cmdret) < 0) ++ NULL, &cmdret) < 0) + return -1; + +- if (cmdret < 0 || exitstatus != 0) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Could not start 'swtpm'. exitstatus: %d, " +- "error: %s"), exitstatus, errbuf); +- return -1; ++ if (cmdret < 0) { ++ /* virCommandRun() hidden in qemuSecurityStartTPMEmulator() ++ * already reported error. */ ++ goto error; + } + +- /* check that the swtpm has written its pid into the file */ +- timeout = 1000; /* ms */ +- while (timeout > 0) { +- rc = qemuTPMEmulatorGetPid(cfg->swtpmStateDir, shortName, &pid); +- if (rc < 0) { +- timeout -= 50; +- g_usleep(50 * 1000); ++ if (virPidFileReadPath(pidfile, &pid) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("swtpm didn't show up")); ++ goto error; ++ } ++ ++ if (virTimeBackOffStart(&timebackoff, 1, timeout) < 0) ++ goto error; ++ while (virTimeBackOffWait(&timebackoff)) { ++ char errbuf[1024] = { 0 }; ++ ++ if (virFileExists(tpm->data.emulator.source->data.nix.path)) ++ break; ++ ++ if (virProcessKill(pid, 0) == 0) + continue; ++ ++ if (saferead(errfd, errbuf, sizeof(errbuf) - 1) < 0) { ++ virReportSystemError(errno, "%s", ++ _("swtpm died unexpectedly")); ++ } else { ++ virReportError(VIR_ERR_OPERATION_FAILED, ++ _("swtpm died and reported: %s"), errbuf); + } +- if (rc == 0 && pid == (pid_t)-1) +- goto error; +- break; ++ goto error; + } +- if (timeout <= 0) ++ ++ if (!virFileExists(tpm->data.emulator.source->data.nix.path)) { ++ virReportError(VIR_ERR_OPERATION_TIMEOUT, "%s", ++ _("swtpm socket did not show up")); + goto error; ++ } + + return 0; + + error: +- virReportError(VIR_ERR_INTERNAL_ERROR, "%s", +- _("swtpm failed to start")); ++ virCommandAbort(cmd); ++ if (pid >= 0) ++ virProcessKillPainfully(pid, true); ++ if (pidfile) ++ unlink(pidfile); + return -1; + } + +-- +2.39.0 + diff --git a/libvirt-qemu-virtiofs-format-thread-pool-size.patch b/libvirt-qemu-virtiofs-format-thread-pool-size.patch new file mode 100644 index 0000000..afda4b8 --- /dev/null +++ b/libvirt-qemu-virtiofs-format-thread-pool-size.patch @@ -0,0 +1,37 @@ +From 44f83782ba882f9eb037a54fb75231c305d98712 Mon Sep 17 00:00:00 2001 +Message-Id: <44f83782ba882f9eb037a54fb75231c305d98712@dist-git> +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +Date: Fri, 10 Jun 2022 15:25:00 +0200 +Subject: [PATCH] qemu: virtiofs: format --thread-pool-size +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +https://bugzilla.redhat.com/show_bug.cgi?id=2079582 + +Signed-off-by: Ján Tomko +Reviewed-by: Michal Privoznik +(cherry picked from commit 2753eba20ce76d3d8785b23a6e940574ca12fe3c) +Signed-off-by: Ján Tomko +--- + src/qemu/qemu_virtiofs.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/qemu/qemu_virtiofs.c b/src/qemu/qemu_virtiofs.c +index 1b853a5a59..1ee3781286 100644 +--- a/src/qemu/qemu_virtiofs.c ++++ b/src/qemu/qemu_virtiofs.c +@@ -163,6 +163,10 @@ qemuVirtioFSBuildCommandLine(virQEMUDriverConfig *cfg, + virBufferAddLit(&opts, ",no_posix_lock"); + + virCommandAddArgBuffer(cmd, &opts); ++ ++ if (fs->thread_pool_size >= 0) ++ virCommandAddArgFormat(cmd, "--thread-pool-size=%i", fs->thread_pool_size); ++ + if (cfg->virtiofsdDebug) + virCommandAddArg(cmd, "-d"); + +-- +2.35.1 + diff --git a/libvirt-qemuAgentGetDisks-Don-t-use-virJSONValueObjectGetStringArray-for-optional-data.patch b/libvirt-qemuAgentGetDisks-Don-t-use-virJSONValueObjectGetStringArray-for-optional-data.patch new file mode 100644 index 0000000..2ed40d8 --- /dev/null +++ b/libvirt-qemuAgentGetDisks-Don-t-use-virJSONValueObjectGetStringArray-for-optional-data.patch @@ -0,0 +1,57 @@ +From 1ad707f19e570b76c1f6517194d9cc86b084014d Mon Sep 17 00:00:00 2001 +Message-Id: <1ad707f19e570b76c1f6517194d9cc86b084014d@dist-git> +From: Peter Krempa +Date: Thu, 1 Dec 2022 17:02:42 +0100 +Subject: [PATCH] qemuAgentGetDisks: Don't use virJSONValueObjectGetStringArray + for optional data + +The 'dependencies' field in the return data may be missing in some +cases. Historically 'virJSONValueObjectGetStringArray' didn't report +error in such case, but later refactor (commit 043b50b948ef3c2 ) added +an error in order to use it in other places too. + +Unfortunately this results in the error log being spammed with an +irrelevant error in case when qemuAgentGetDisks is invoked on a VM +running windows. + +Replace the use of virJSONValueObjectGetStringArray by fetching the +array first and calling virJSONValueArrayToStringList only when we have +an array. + +Fixes: 043b50b948ef3c2a4adf5fa32a93ec2589851ac6 +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2149752 +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +(cherry picked from commit 3b576601dfb924bb518870a01de5d1a421cbb467) +--- + src/qemu/qemu_agent.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c +index f33cd47078..8a55044c9e 100644 +--- a/src/qemu/qemu_agent.c ++++ b/src/qemu/qemu_agent.c +@@ -2550,6 +2550,7 @@ int qemuAgentGetDisks(qemuAgent *agent, + for (i = 0; i < ndata; i++) { + virJSONValue *addr; + virJSONValue *entry = virJSONValueArrayGet(data, i); ++ virJSONValue *dependencies; + qemuAgentDiskInfo *disk; + + if (!entry) { +@@ -2575,7 +2576,11 @@ int qemuAgentGetDisks(qemuAgent *agent, + goto error; + } + +- disk->dependencies = virJSONValueObjectGetStringArray(entry, "dependencies"); ++ if ((dependencies = virJSONValueObjectGetArray(entry, "dependencies"))) { ++ if (!(disk->dependencies = virJSONValueArrayToStringList(dependencies))) ++ goto error; ++ } ++ + disk->alias = g_strdup(virJSONValueObjectGetString(entry, "alias")); + addr = virJSONValueObjectGetObject(entry, "address"); + if (addr) { +-- +2.39.0 + diff --git a/libvirt-qemuProcessReconnect-Don-t-build-memory-paths.patch b/libvirt-qemuProcessReconnect-Don-t-build-memory-paths.patch new file mode 100644 index 0000000..8185b76 --- /dev/null +++ b/libvirt-qemuProcessReconnect-Don-t-build-memory-paths.patch @@ -0,0 +1,57 @@ +From c5c8bb4aafc8f247e6da146a6683174038611600 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Michal Privoznik +Date: Wed, 28 Sep 2022 10:12:36 +0200 +Subject: [PATCH] qemuProcessReconnect: Don't build memory paths +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Let me take you on a short trip to history. A long time ago, +libvirt would configure all QEMUs to use $hugetlbfs/libvirt/qemu +for their hugepages setup. This was problematic, because it did +not allow enough separation between guests. Therefore in +v3.0.0-rc1~367 the path changed to a per-domain basis: + + $hugetlbfs/libvirt/qemu/$domainShortName + +And to help with migration on daemon restart a call to +qemuProcessBuildDestroyMemoryPaths() was added to +qemuProcessReconnect() (well, it was named +qemuProcessBuildDestroyHugepagesPath() back then, see +v3.10.0-rc1~174). This was desirable then, because the memory +hotplug code did not call the function, it simply assumes +per-domain paths to exist. But this changed in v3.5.0-rc1~92 +after which the per-domain paths are created on memory hotplug +too. + +Therefore, it's no longer necessary to create these paths in +qemuProcessReconnect(). They are created exactly when needed +(domain startup and memory hotplug). + +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +(cherry picked from commit 3478cca80ea7382cfdbff836d5d0b92aa014297b) +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2123196 +Signed-off-by: Michal Privoznik +--- + src/qemu/qemu_process.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 1164340aa9..0fb665bc82 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -8869,9 +8869,6 @@ qemuProcessReconnect(void *opaque) + goto cleanup; + } + +- if (qemuProcessBuildDestroyMemoryPaths(driver, obj, NULL, true) < 0) +- goto error; +- + if ((qemuDomainAssignAddresses(obj->def, priv->qemuCaps, + driver, obj, false)) < 0) { + goto error; +-- +2.38.0 + diff --git a/libvirt-qemu_domain-Format-qemuDomainObjPrivate-originalMemlock.patch b/libvirt-qemu_domain-Format-qemuDomainObjPrivate-originalMemlock.patch new file mode 100644 index 0000000..d35edd1 --- /dev/null +++ b/libvirt-qemu_domain-Format-qemuDomainObjPrivate-originalMemlock.patch @@ -0,0 +1,55 @@ +From b221b3ab6d881efedc544e0e0ed9c507e21fd178 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Michal Privoznik +Date: Wed, 11 May 2022 16:37:27 +0200 +Subject: [PATCH] qemu_domain: Format qemuDomainObjPrivate::originalMemlock + +Now that qemuDomainObjPrivate struct gained new member format it +into XML and parse it so that the value is preserved across +daemon restarts. + +Signed-off-by: Michal Privoznik +Reviewed-by: Peter Krempa +(cherry picked from commit 21aec91790ae14d24512856b20cff49764ede637) + +https://bugzilla.redhat.com/show_bug.cgi?id=2089433 + +Signed-off-by: Jiri Denemark +--- + src/qemu/qemu_domain.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index 86d673dafa..ee7d310903 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -2383,6 +2383,12 @@ qemuDomainObjPrivateXMLFormat(virBuffer *buf, + if (qemuDomainObjPrivateXMLFormatBackups(buf, vm) < 0) + return -1; + ++ if (priv->originalMemlock > 0) { ++ virBufferAsprintf(buf, ++ "%llu\n", ++ priv->originalMemlock); ++ } ++ + return 0; + } + +@@ -3104,6 +3110,13 @@ qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt, + + priv->memPrealloc = virXPathBoolean("boolean(./memPrealloc)", ctxt) == 1; + ++ if (virXPathULongLong("string(./originalMemlock)", ++ ctxt, &priv->originalMemlock) == -2) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("failed to parse original memlock size")); ++ goto error; ++ } ++ + return 0; + + error: +-- +2.35.1 + diff --git a/libvirt-qemu_migration-Implement-VIR_MIGRATE_ZEROCOPY-flag.patch b/libvirt-qemu_migration-Implement-VIR_MIGRATE_ZEROCOPY-flag.patch new file mode 100644 index 0000000..0f91c7d --- /dev/null +++ b/libvirt-qemu_migration-Implement-VIR_MIGRATE_ZEROCOPY-flag.patch @@ -0,0 +1,120 @@ +From 35f06623b82d99dd380340eef465394975dd1c80 Mon Sep 17 00:00:00 2001 +Message-Id: <35f06623b82d99dd380340eef465394975dd1c80@dist-git> +From: Jiri Denemark +Date: Wed, 22 Jun 2022 16:37:31 +0200 +Subject: [PATCH] qemu_migration: Implement VIR_MIGRATE_ZEROCOPY flag +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Resolves: https://gitlab.com/libvirt/libvirt/-/issues/306 + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit d375993ab314a41bca7ef6c846e07afc18c37774) + +https://bugzilla.redhat.com/show_bug.cgi?id=2089433 + +Conflicts: + src/qemu/qemu_migration.c + src/qemu/qemu_migration.h + - post-copy recovery not bacported + +Signed-off-by: Jiri Denemark +--- + src/qemu/qemu_migration.c | 21 +++++++++++++++++++++ + src/qemu/qemu_migration.h | 1 + + src/qemu/qemu_migration_params.c | 6 ++++++ + src/qemu/qemu_migration_params.h | 1 + + 4 files changed, 29 insertions(+) + +diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c +index 35ad201580..db5163e993 100644 +--- a/src/qemu/qemu_migration.c ++++ b/src/qemu/qemu_migration.c +@@ -2366,6 +2366,12 @@ qemuMigrationSrcBeginPhase(virQEMUDriver *driver, + return NULL; + } + ++ if (flags & VIR_MIGRATE_ZEROCOPY && !(flags & VIR_MIGRATE_PARALLEL)) { ++ virReportError(VIR_ERR_OPERATION_INVALID, "%s", ++ _("zero-copy is only available for parallel migration")); ++ return NULL; ++ } ++ + if (flags & (VIR_MIGRATE_NON_SHARED_DISK | VIR_MIGRATE_NON_SHARED_INC)) { + if (flags & VIR_MIGRATE_NON_SHARED_SYNCHRONOUS_WRITES && + !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV)) { +@@ -4137,6 +4143,21 @@ qemuMigrationSrcRun(virQEMUDriver *driver, + migParams) < 0) + goto error; + ++ if (flags & VIR_MIGRATE_ZEROCOPY) { ++ /* Zero-copy requires pages in transfer to be locked in host memory. ++ * Unfortunately, we have no reliable way of computing how many pages ++ * will need to be locked at the same time. Thus we set the limit to ++ * the whole guest memory and reset it back once migration is done. */ ++ unsigned long long limit; ++ ++ if (virMemoryLimitIsSet(vm->def->mem.hard_limit)) ++ limit = vm->def->mem.hard_limit; ++ else ++ limit = virDomainDefGetMemoryTotal(vm->def); ++ ++ if (qemuDomainSetMaxMemLock(vm, limit << 10, &priv->preMigrationMemlock) < 0) ++ goto error; ++ } + + if (storageMigration) { + if (mig->nbd) { +diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h +index b233358a51..6f737f7b4c 100644 +--- a/src/qemu/qemu_migration.h ++++ b/src/qemu/qemu_migration.h +@@ -60,6 +60,7 @@ + VIR_MIGRATE_TLS | \ + VIR_MIGRATE_PARALLEL | \ + VIR_MIGRATE_NON_SHARED_SYNCHRONOUS_WRITES | \ ++ VIR_MIGRATE_ZEROCOPY | \ + 0) + + /* All supported migration parameters and their types. */ +diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c +index 7b225fdf4b..c985583861 100644 +--- a/src/qemu/qemu_migration_params.c ++++ b/src/qemu/qemu_migration_params.c +@@ -96,6 +96,7 @@ VIR_ENUM_IMPL(qemuMigrationCapability, + "multifd", + "dirty-bitmaps", + "return-path", ++ "zero-copy-send", + ); + + +@@ -177,6 +178,11 @@ static const qemuMigrationParamsFlagMapItem qemuMigrationParamsFlagMap[] = { + VIR_MIGRATE_TUNNELLED, + QEMU_MIGRATION_CAP_RETURN_PATH, + QEMU_MIGRATION_SOURCE | QEMU_MIGRATION_DESTINATION}, ++ ++ {QEMU_MIGRATION_FLAG_REQUIRED, ++ VIR_MIGRATE_ZEROCOPY, ++ QEMU_MIGRATION_CAP_ZERO_COPY_SEND, ++ QEMU_MIGRATION_SOURCE}, + }; + + /* Translation from VIR_MIGRATE_PARAM_* typed parameters to +diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h +index b4de8dda7b..caa5e47f0f 100644 +--- a/src/qemu/qemu_migration_params.h ++++ b/src/qemu/qemu_migration_params.h +@@ -41,6 +41,7 @@ typedef enum { + QEMU_MIGRATION_CAP_MULTIFD, + QEMU_MIGRATION_CAP_BLOCK_DIRTY_BITMAPS, + QEMU_MIGRATION_CAP_RETURN_PATH, ++ QEMU_MIGRATION_CAP_ZERO_COPY_SEND, + + QEMU_MIGRATION_CAP_LAST + } qemuMigrationCapability; +-- +2.35.1 + diff --git a/libvirt-qemu_migration-Restore-original-memory-locking-limit.patch b/libvirt-qemu_migration-Restore-original-memory-locking-limit.patch new file mode 100644 index 0000000..c8afc02 --- /dev/null +++ b/libvirt-qemu_migration-Restore-original-memory-locking-limit.patch @@ -0,0 +1,133 @@ +From 8cccd9634ecd91a5b7343eddc037e0fa7de2f9f6 Mon Sep 17 00:00:00 2001 +Message-Id: <8cccd9634ecd91a5b7343eddc037e0fa7de2f9f6@dist-git> +From: Jiri Denemark +Date: Wed, 22 Jun 2022 16:12:02 +0200 +Subject: [PATCH] qemu_migration: Restore original memory locking limit +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +For RDMA migration we update memory locking limit, but never set it back +once migration finishes (on the destination host) or aborts (on the +source host). + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit d4d3bb813031275c2c7cf72724b83c97ce82ab7a) + +https://bugzilla.redhat.com/show_bug.cgi?id=2089433 + +Conflicts: + src/qemu/qemu_migration.c + - post-copy resovery not backported + +Signed-off-by: Jiri Denemark +--- + src/qemu/qemu_domain.c | 12 ++++++++++++ + src/qemu/qemu_domain.h | 3 +++ + src/qemu/qemu_migration.c | 10 ++++++++-- + 3 files changed, 23 insertions(+), 2 deletions(-) + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index a81789f194..c24d1e4d53 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -2389,6 +2389,11 @@ qemuDomainObjPrivateXMLFormat(virBuffer *buf, + priv->originalMemlock); + } + ++ if (priv->preMigrationMemlock > 0) { ++ virBufferAsprintf(buf, "%llu\n", ++ priv->preMigrationMemlock); ++ } ++ + return 0; + } + +@@ -3117,6 +3122,13 @@ qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt, + goto error; + } + ++ if (virXPathULongLong("string(./preMigrationMemlock)", ctxt, ++ &priv->preMigrationMemlock) == -2) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("failed to parse pre-migration memlock limit")); ++ return -1; ++ } ++ + return 0; + + error: +diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h +index 6d1d23439a..d6e8a7a0fb 100644 +--- a/src/qemu/qemu_domain.h ++++ b/src/qemu/qemu_domain.h +@@ -146,6 +146,9 @@ struct _qemuDomainObjPrivate { + int nbdPort; /* Port used for migration with NBD */ + unsigned short migrationPort; + int preMigrationState; ++ unsigned long long preMigrationMemlock; /* Original RLIMIT_MEMLOCK in case ++ it was changed for the current ++ migration job. */ + + virChrdevs *devs; + +diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c +index 10338f8e87..35ad201580 100644 +--- a/src/qemu/qemu_migration.c ++++ b/src/qemu/qemu_migration.c +@@ -2974,7 +2974,8 @@ qemuMigrationDstPrepareAny(virQEMUDriver *driver, + + if (STREQ_NULLABLE(protocol, "rdma") && + vm->def->mem.hard_limit > 0 && +- qemuDomainSetMaxMemLock(vm, vm->def->mem.hard_limit << 10, NULL) < 0) { ++ qemuDomainSetMaxMemLock(vm, vm->def->mem.hard_limit << 10, ++ &priv->preMigrationMemlock) < 0) { + goto stopjob; + } + +@@ -3451,6 +3452,7 @@ qemuMigrationSrcConfirmPhase(virQEMUDriver *driver, + VIR_DOMAIN_EVENT_STOPPED_MIGRATED); + virObjectEventStateQueue(driver->domainEventState, event); + qemuDomainEventEmitJobCompleted(driver, vm); ++ priv->preMigrationMemlock = 0; + } else { + virErrorPtr orig_err; + int reason; +@@ -3471,6 +3473,7 @@ qemuMigrationSrcConfirmPhase(virQEMUDriver *driver, + + qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, + jobPriv->migParams, priv->job.apiFlags); ++ qemuDomainSetMaxMemLock(vm, 0, &priv->preMigrationMemlock); + + qemuDomainSaveStatus(vm); + } +@@ -4224,7 +4227,8 @@ qemuMigrationSrcRun(virQEMUDriver *driver, + case MIGRATION_DEST_HOST: + if (STREQ(spec->dest.host.protocol, "rdma") && + vm->def->mem.hard_limit > 0 && +- qemuDomainSetMaxMemLock(vm, vm->def->mem.hard_limit << 10, NULL) < 0) { ++ qemuDomainSetMaxMemLock(vm, vm->def->mem.hard_limit << 10, ++ &priv->preMigrationMemlock) < 0) { + goto exit_monitor; + } + rc = qemuMonitorMigrateToHost(priv->mon, migrate_flags, +@@ -5408,6 +5412,7 @@ qemuMigrationSrcPerformPhase(virQEMUDriver *driver, + if (ret < 0) { + qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, + jobPriv->migParams, priv->job.apiFlags); ++ qemuDomainSetMaxMemLock(vm, 0, &priv->preMigrationMemlock); + qemuMigrationJobFinish(driver, vm); + } else { + qemuMigrationJobContinue(vm); +@@ -5881,6 +5886,7 @@ qemuMigrationDstFinish(virQEMUDriver *driver, + cleanup: + g_clear_pointer(&jobInfo, qemuDomainJobInfoFree); + virPortAllocatorRelease(port); ++ qemuDomainSetMaxMemLock(vm, 0, &priv->preMigrationMemlock); + if (priv->mon) + qemuMonitorSetDomainLog(priv->mon, NULL, NULL, NULL); + VIR_FREE(priv->origname); +-- +2.35.1 + diff --git a/libvirt-qemu_migration-Use-qemuDomainSetMaxMemLock.patch b/libvirt-qemu_migration-Use-qemuDomainSetMaxMemLock.patch new file mode 100644 index 0000000..88a871b --- /dev/null +++ b/libvirt-qemu_migration-Use-qemuDomainSetMaxMemLock.patch @@ -0,0 +1,53 @@ +From 8354fa1d2e471699331961272bc38f5e4cfe7cb8 Mon Sep 17 00:00:00 2001 +Message-Id: <8354fa1d2e471699331961272bc38f5e4cfe7cb8@dist-git> +From: Jiri Denemark +Date: Wed, 22 Jun 2022 09:04:04 +0200 +Subject: [PATCH] qemu_migration: Use qemuDomainSetMaxMemLock +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This helper will not try to set the limit if it is already big enough, +which may be useful when libvirt daemon is running in a containerized +environment and is not allowed to change memory locking limit. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 22ee8cbf090c45f999b76e3f8dc7a45065fc9edf) + +https://bugzilla.redhat.com/show_bug.cgi?id=2089433 + +Conflicts: + src/qemu/qemu_migration.c + - refactoring for post-copy recovery not backported + +Signed-off-by: Jiri Denemark +--- + src/qemu/qemu_migration.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c +index 2635ef1162..10338f8e87 100644 +--- a/src/qemu/qemu_migration.c ++++ b/src/qemu/qemu_migration.c +@@ -2974,7 +2974,7 @@ qemuMigrationDstPrepareAny(virQEMUDriver *driver, + + if (STREQ_NULLABLE(protocol, "rdma") && + vm->def->mem.hard_limit > 0 && +- virProcessSetMaxMemLock(vm->pid, vm->def->mem.hard_limit << 10) < 0) { ++ qemuDomainSetMaxMemLock(vm, vm->def->mem.hard_limit << 10, NULL) < 0) { + goto stopjob; + } + +@@ -4224,7 +4224,7 @@ qemuMigrationSrcRun(virQEMUDriver *driver, + case MIGRATION_DEST_HOST: + if (STREQ(spec->dest.host.protocol, "rdma") && + vm->def->mem.hard_limit > 0 && +- virProcessSetMaxMemLock(vm->pid, vm->def->mem.hard_limit << 10) < 0) { ++ qemuDomainSetMaxMemLock(vm, vm->def->mem.hard_limit << 10, NULL) < 0) { + goto exit_monitor; + } + rc = qemuMonitorMigrateToHost(priv->mon, migrate_flags, +-- +2.35.1 + diff --git a/libvirt-qemu_namespace-Fix-a-corner-case-in-qemuDomainGetPreservedMounts.patch b/libvirt-qemu_namespace-Fix-a-corner-case-in-qemuDomainGetPreservedMounts.patch new file mode 100644 index 0000000..3df3a96 --- /dev/null +++ b/libvirt-qemu_namespace-Fix-a-corner-case-in-qemuDomainGetPreservedMounts.patch @@ -0,0 +1,80 @@ +From 215adedb16aa082d052f84705338de0d77721fe0 Mon Sep 17 00:00:00 2001 +Message-Id: <215adedb16aa082d052f84705338de0d77721fe0@dist-git> +From: Michal Privoznik +Date: Tue, 6 Sep 2022 13:43:22 +0200 +Subject: [PATCH] qemu_namespace: Fix a corner case in + qemuDomainGetPreservedMounts() + +When setting up namespace for QEMU we look at mount points under +/dev (like /dev/pts, /dev/mqueue/, etc.) because we want to +preserve those (which is done by moving them to a temp location, +unshare(), and then moving them back). We have a convenience +helper - qemuDomainGetPreservedMounts() - that processes the +mount table and (optionally) moves the other filesystems too. +This helper is also used when attempting to create a path in NS, +because the path, while starting with "/dev/" prefix, may +actually lead to one of those filesystems that we preserved. + +And here comes the corner case: while we require the parent mount +table to be in shared mode (equivalent of `mount --make-rshared /'), +these mount events propagate iff the target path exist inside the +slave mount table (= QEMU's private namespace). And since we +create only a subset of /dev nodes, well, that assumption is not +always the case. + +For instance, assume that a domain is already running, no +hugepages were configured for it nor any hugetlbfs is mounted. +Now, when a hugetlbfs is mounted into '/dev/hugepages', this is +propagated into the QEMU's namespace, but since the target dir +does not exist in the private /dev, the FS is not mounted in the +namespace. + +Fortunately, this difference between namespaces is visible when +comparing /proc/mounts and /proc/$PID/mounts (where PID is the +QEMU's PID). Therefore, if possible we should look at the latter. + +Signed-off-by: Michal Privoznik +Reviewed-by: Martin Kletzander +(cherry picked from commit 46b03819ae8d833b11c2aaccb2c2a0361727f51b) +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2123196 +Signed-off-by: Michal Privoznik +--- + src/qemu/qemu_namespace.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_namespace.c b/src/qemu/qemu_namespace.c +index 4bff325a2c..fc286ab0be 100644 +--- a/src/qemu/qemu_namespace.c ++++ b/src/qemu/qemu_namespace.c +@@ -110,6 +110,8 @@ qemuDomainGetPreservedMountPath(virQEMUDriverConfig *cfg, + * b) generate backup path for all the entries in a) + * + * Any of the return pointers can be NULL. Both arrays are NULL-terminated. ++ * Get the mount table either from @vm's PID (if running), or from the ++ * namespace we're in (if @vm's not running). + * + * Returns 0 on success, -1 otherwise (with error reported) + */ +@@ -124,12 +126,18 @@ qemuDomainGetPreservedMounts(virQEMUDriverConfig *cfg, + size_t nmounts = 0; + g_auto(GStrv) paths = NULL; + g_auto(GStrv) savePaths = NULL; ++ g_autofree char *mountsPath = NULL; + size_t i; + + if (ndevPath) + *ndevPath = 0; + +- if (virFileGetMountSubtree(QEMU_PROC_MOUNTS, "/dev", &mounts, &nmounts) < 0) ++ if (vm->pid > 0) ++ mountsPath = g_strdup_printf("/proc/%lld/mounts", (long long) vm->pid); ++ else ++ mountsPath = g_strdup(QEMU_PROC_MOUNTS); ++ ++ if (virFileGetMountSubtree(mountsPath, "/dev", &mounts, &nmounts) < 0) + return -1; + + if (nmounts == 0) +-- +2.38.0 + diff --git a/libvirt-qemu_namespace-Introduce-qemuDomainNamespaceSetupPath.patch b/libvirt-qemu_namespace-Introduce-qemuDomainNamespaceSetupPath.patch new file mode 100644 index 0000000..bb83813 --- /dev/null +++ b/libvirt-qemu_namespace-Introduce-qemuDomainNamespaceSetupPath.patch @@ -0,0 +1,68 @@ +From d515c964d740274d01bb8de1e5b0351490d6b9d3 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Michal Privoznik +Date: Tue, 6 Sep 2022 13:43:58 +0200 +Subject: [PATCH] qemu_namespace: Introduce qemuDomainNamespaceSetupPath() + +Sometimes it may come handy to just bind mount a directory/file +into domain's namespace. Implement a thin wrapper over +qemuNamespaceMknodPaths() which has all the logic we need. + +Signed-off-by: Michal Privoznik +Reviewed-by: Martin Kletzander +(cherry picked from commit 5853d707189005a4ea5b2215e80853867b822fd9) +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2123196 +Signed-off-by: Michal Privoznik +--- + src/qemu/qemu_namespace.c | 19 +++++++++++++++++++ + src/qemu/qemu_namespace.h | 4 ++++ + 2 files changed, 23 insertions(+) + +diff --git a/src/qemu/qemu_namespace.c b/src/qemu/qemu_namespace.c +index fc286ab0be..74ffd6fb90 100644 +--- a/src/qemu/qemu_namespace.c ++++ b/src/qemu/qemu_namespace.c +@@ -1398,6 +1398,25 @@ qemuNamespaceUnlinkPaths(virDomainObj *vm, + } + + ++int ++qemuDomainNamespaceSetupPath(virDomainObj *vm, ++ const char *path, ++ bool *created) ++{ ++ g_autoptr(virGSListString) paths = NULL; ++ ++ if (!qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT)) ++ return 0; ++ ++ paths = g_slist_prepend(paths, g_strdup(path)); ++ ++ if (qemuNamespaceMknodPaths(vm, paths, created) < 0) ++ return -1; ++ ++ return 0; ++} ++ ++ + int + qemuDomainNamespaceSetupDisk(virDomainObj *vm, + virStorageSource *src, +diff --git a/src/qemu/qemu_namespace.h b/src/qemu/qemu_namespace.h +index 020aca13d8..1ab9322061 100644 +--- a/src/qemu/qemu_namespace.h ++++ b/src/qemu/qemu_namespace.h +@@ -49,6 +49,10 @@ void qemuDomainDestroyNamespace(virQEMUDriver *driver, + + bool qemuDomainNamespaceAvailable(qemuDomainNamespace ns); + ++int qemuDomainNamespaceSetupPath(virDomainObj *vm, ++ const char *path, ++ bool *created); ++ + int qemuDomainNamespaceSetupDisk(virDomainObj *vm, + virStorageSource *src, + bool *created); +-- +2.38.0 + diff --git a/libvirt-qemu_namespace-Tolerate-missing-ACLs-when-creating-a-path-in-namespace.patch b/libvirt-qemu_namespace-Tolerate-missing-ACLs-when-creating-a-path-in-namespace.patch new file mode 100644 index 0000000..ceccc0b --- /dev/null +++ b/libvirt-qemu_namespace-Tolerate-missing-ACLs-when-creating-a-path-in-namespace.patch @@ -0,0 +1,45 @@ +From 7c7ec6e6c20675a99abe8685c715dc95e7e8dbff Mon Sep 17 00:00:00 2001 +Message-Id: <7c7ec6e6c20675a99abe8685c715dc95e7e8dbff@dist-git> +From: Michal Privoznik +Date: Tue, 6 Sep 2022 13:37:23 +0200 +Subject: [PATCH] qemu_namespace: Tolerate missing ACLs when creating a path in + namespace + +When creating a path in a domain's mount namespace we try to set +ACLs on it, so that it's a verbatim copy of the path in parent's +namespace. The ACLs are queried upfront (by +qemuNamespaceMknodItemInit()) but this is fault tolerant so the +pointer to ACLs might be NULL (meaning no ACLs were queried, for +instance because the underlying filesystem does not support +them). But then we take this NULL and pass it to virFileSetACLs() +which immediately returns an error because NULL is invalid value. + +Mimic what we do with SELinux label - only set ACLs if they are +non-NULL which includes symlinks. + +Signed-off-by: Michal Privoznik +Reviewed-by: Martin Kletzander +(cherry picked from commit 687374959e160dc566bd4b6d43c7bf1beb470c59) +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2123196 +Signed-off-by: Michal Privoznik +--- + src/qemu/qemu_namespace.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/src/qemu/qemu_namespace.c b/src/qemu/qemu_namespace.c +index 94453033f5..4bff325a2c 100644 +--- a/src/qemu/qemu_namespace.c ++++ b/src/qemu/qemu_namespace.c +@@ -1023,8 +1023,7 @@ qemuNamespaceMknodOne(qemuNamespaceMknodItem *data) + goto cleanup; + } + +- /* Symlinks don't have ACLs. */ +- if (!isLink && ++ if (data->acl && + virFileSetACLs(data->file, data->acl) < 0 && + errno != ENOTSUP) { + virReportSystemError(errno, +-- +2.38.0 + diff --git a/libvirt-qemu_process-Don-t-require-a-hugetlbfs-mount-for-memfd.patch b/libvirt-qemu_process-Don-t-require-a-hugetlbfs-mount-for-memfd.patch new file mode 100644 index 0000000..5552bf4 --- /dev/null +++ b/libvirt-qemu_process-Don-t-require-a-hugetlbfs-mount-for-memfd.patch @@ -0,0 +1,50 @@ +From f745b9ae2d12df0c0f2253c295f3d411a8a4165d Mon Sep 17 00:00:00 2001 +Message-Id: +From: Michal Privoznik +Date: Mon, 5 Sep 2022 10:34:44 +0200 +Subject: [PATCH] qemu_process: Don't require a hugetlbfs mount for memfd + +The aim of qemuProcessNeedHugepagesPath() is to determine whether +a hugetlbfs mount point is required for given domain (as in +whether qemuBuildMemoryBackendProps() picks up +memory-backend-file pointing to a hugetlbfs mount point). Well, +when domain is configured to use memfd backend then that +condition can never be true. Therefore, skip creating domain's +private path under hugetlbfs mount points. + +Signed-off-by: Michal Privoznik +Reviewed-by: Martin Kletzander +(cherry picked from commit f14f8dff9330ed51d817f190a2ee9ac76dfac00b) +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2123196 +Signed-off-by: Michal Privoznik +--- + src/qemu/qemu_process.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 5c6657a876..540eee9ff0 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -3810,8 +3810,18 @@ qemuProcessNeedHugepagesPath(virDomainDef *def, + const long system_pagesize = virGetSystemPageSizeKB(); + size_t i; + +- if (def->mem.source == VIR_DOMAIN_MEMORY_SOURCE_FILE) ++ switch ((virDomainMemorySource)def->mem.source) { ++ case VIR_DOMAIN_MEMORY_SOURCE_FILE: ++ /* This needs a hugetlbfs mount. */ + return true; ++ case VIR_DOMAIN_MEMORY_SOURCE_MEMFD: ++ /* memfd works without a hugetlbfs mount */ ++ return false; ++ case VIR_DOMAIN_MEMORY_SOURCE_NONE: ++ case VIR_DOMAIN_MEMORY_SOURCE_ANONYMOUS: ++ case VIR_DOMAIN_MEMORY_SOURCE_LAST: ++ break; ++ } + + for (i = 0; i < def->mem.nhugepages; i++) { + if (def->mem.hugepages[i].size != system_pagesize) +-- +2.38.0 + diff --git a/libvirt-qemu_process.c-Propagate-hugetlbfs-mounts-on-reconnect.patch b/libvirt-qemu_process.c-Propagate-hugetlbfs-mounts-on-reconnect.patch new file mode 100644 index 0000000..be102cd --- /dev/null +++ b/libvirt-qemu_process.c-Propagate-hugetlbfs-mounts-on-reconnect.patch @@ -0,0 +1,65 @@ +From 2aeb222d9d61868ef40932b4349af84696415e11 Mon Sep 17 00:00:00 2001 +Message-Id: <2aeb222d9d61868ef40932b4349af84696415e11@dist-git> +From: Michal Privoznik +Date: Tue, 6 Sep 2022 13:45:51 +0200 +Subject: [PATCH] qemu_process.c: Propagate hugetlbfs mounts on reconnect + +When reconnecting to a running QEMU process, we construct the +per-domain path in all hugetlbfs mounts. This is a relict from +the past (v3.4.0-100-g5b24d25062) where we switched to a +per-domain path and we want to create those paths when libvirtd +restarts on upgrade. + +And with namespaces enabled there is one corner case where the +path is not created. In fact an error is reported and the +reconnect fails. Ideally, all mount events are propagated into +the QEMU's namespace. And they probably are, except when the +target path does not exist inside the namespace. Now, it's pretty +common for users to mount hugetlbfs under /dev (e.g. +/dev/hugepages), but if domain is started without hugepages (or +more specifically - private hugetlbfs path wasn't created on +domain startup), then the reconnect code tries to create it. +But it fails to do so, well, it fails to set seclabels on the +path because, because the path does not exist in the private +namespace. And it doesn't exist because we specifically create +only a subset of all possible /dev nodes. Therefore, the mount +event, whilst propagated, is not successful and hence the +filesystem is not mounted. We have to do it ourselves. + +If hugetlbfs is mount anywhere else there's no problem and this +is effectively a dead code. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2123196 +Signed-off-by: Michal Privoznik +Reviewed-by: Martin Kletzander +(cherry picked from commit 0377177c7856bb87a9d8aa1324b54f5fbe9f1e5b) + +Conflicts: +- docs/kbase/qemu-passthrough-security.rst: Well, v8.8.0-rc1~32 + isn't backported, thus we can't remove a paragraph that the + backported commit did. It's a documentation after all, so no + harm. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2123196 +Signed-off-by: Michal Privoznik +--- + src/qemu/qemu_process.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 540eee9ff0..1164340aa9 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -3906,6 +3906,9 @@ qemuProcessBuildDestroyMemoryPathsImpl(virQEMUDriver *driver, + return -1; + } + ++ if (qemuDomainNamespaceSetupPath(vm, path, NULL) < 0) ++ return -1; ++ + if (qemuSecurityDomainSetPathLabel(driver, vm, path, true) < 0) + return -1; + } else { +-- +2.38.0 + diff --git a/libvirt-qemu_tpm-Do-async-IO-when-starting-swtpm-emulator.patch b/libvirt-qemu_tpm-Do-async-IO-when-starting-swtpm-emulator.patch new file mode 100644 index 0000000..6ee2c59 --- /dev/null +++ b/libvirt-qemu_tpm-Do-async-IO-when-starting-swtpm-emulator.patch @@ -0,0 +1,49 @@ +From 87b0f241db1eba0e9db1fd233c5ab8a8d0115979 Mon Sep 17 00:00:00 2001 +Message-Id: <87b0f241db1eba0e9db1fd233c5ab8a8d0115979@dist-git> +From: Michal Privoznik +Date: Mon, 21 Mar 2022 13:33:06 +0100 +Subject: [PATCH] qemu_tpm: Do async IO when starting swtpm emulator +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When vTPM is secured via virSecret libvirt passes the secret +value via an FD when swtpm is started (arguments --key and +--migration-key). The writing of the secret into the FDs is +handled via virCommand, specifically qemu_tpm calls +virCommandSetSendBuffer()) and then virCommandRunAsync() spawns a +thread to handle writing into the FD via +virCommandDoAsyncIOHelper. But the thread is not created unless +VIR_EXEC_ASYNC_IO flag is set, which it isn't. In order to fix +it, virCommandDoAsyncIO() must be called. + +The credit goes to Marc-André Lureau + who has done all the debugging and +proposed fix in the bugzilla. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2064115 +Fixes: a9c500d2b50c5c041a1bb6ae9724402cf1cec8fe +Signed-off-by: Michal Privoznik +Reviewed-by: Jiri Denemark +(cherry picked from commit 4d7bb0177a33c4e90fd001edfe27bc030354d875) +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2152188 +Signed-off-by: Michal Privoznik +--- + src/qemu/qemu_tpm.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/qemu/qemu_tpm.c b/src/qemu/qemu_tpm.c +index 9c5d1ffed4..29dcb2ac0f 100644 +--- a/src/qemu/qemu_tpm.c ++++ b/src/qemu/qemu_tpm.c +@@ -923,6 +923,7 @@ qemuExtTPMStartEmulator(virQEMUDriver *driver, + if (!(pidfile = qemuTPMEmulatorCreatePidFilename(cfg->swtpmStateDir, shortName))) + return -1; + ++ virCommandDoAsyncIO(cmd); + virCommandDaemonize(cmd); + virCommandSetPidFile(cmd, pidfile); + virCommandSetErrorFD(cmd, &errfd); +-- +2.39.0 + diff --git a/libvirt-security_selinux.c-Relabel-existing-mode-bind-UNIX-sockets.patch b/libvirt-security_selinux.c-Relabel-existing-mode-bind-UNIX-sockets.patch new file mode 100644 index 0000000..8332ee9 --- /dev/null +++ b/libvirt-security_selinux.c-Relabel-existing-mode-bind-UNIX-sockets.patch @@ -0,0 +1,64 @@ +From 07fb786e0d17bd395333d276ebbaad42c72ee358 Mon Sep 17 00:00:00 2001 +Message-Id: <07fb786e0d17bd395333d276ebbaad42c72ee358@dist-git> +From: David Michael +Date: Tue, 28 Jun 2022 08:33:41 -0400 +Subject: [PATCH] security_selinux.c: Relabel existing mode="bind" UNIX sockets + +This supports sockets created by libvirt and passed by FD using the +same method as in security_dac.c. + +Signed-off-by: David Michael +Signed-off-by: Michal Privoznik +Reviewed-by: Michal Privoznik +(cherry picked from commit 9f13f54a6348b54170f7de3595039c99b9da72c7) + +https://bugzilla.redhat.com/show_bug.cgi?id=2101575 + +Signed-off-by: Michal Privoznik +--- + src/security/security_selinux.c | 9 +++++++-- + tests/securityselinuxlabeldata/chardev.txt | 2 +- + 2 files changed, 8 insertions(+), 3 deletions(-) + +diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c +index 0952431064..b90e819fd2 100644 +--- a/src/security/security_selinux.c ++++ b/src/security/security_selinux.c +@@ -2545,7 +2545,12 @@ virSecuritySELinuxSetChardevLabel(virSecurityManager *mgr, + break; + + case VIR_DOMAIN_CHR_TYPE_UNIX: +- if (!dev_source->data.nix.listen) { ++ if (!dev_source->data.nix.listen || ++ (dev_source->data.nix.path && ++ virFileExists(dev_source->data.nix.path))) { ++ /* Also label mode='bind' sockets if they exist, ++ * e.g. because they were created by libvirt ++ * and passed via FD */ + if (virSecuritySELinuxSetFilecon(mgr, + dev_source->data.nix.path, + imagelabel, +@@ -2622,7 +2627,7 @@ virSecuritySELinuxRestoreChardevLabel(virSecurityManager *mgr, + case VIR_DOMAIN_CHR_TYPE_UNIX: + if (!dev_source->data.nix.listen) { + if (virSecuritySELinuxRestoreFileLabel(mgr, +- dev_source->data.file.path, ++ dev_source->data.nix.path, + true) < 0) + goto done; + } +diff --git a/tests/securityselinuxlabeldata/chardev.txt b/tests/securityselinuxlabeldata/chardev.txt +index 3f4b6302b9..bdb367f7a5 100644 +--- a/tests/securityselinuxlabeldata/chardev.txt ++++ b/tests/securityselinuxlabeldata/chardev.txt +@@ -2,6 +2,6 @@ + /plain.dev;system_u:object_r:svirt_image_t:s0:c41,c264 + /plain.fifo;system_u:object_r:svirt_image_t:s0:c41,c264 + /nolabel.sock; +-/plain.sock; ++/plain.sock;system_u:object_r:svirt_image_t:s0:c41,c264 + /yeslabel.sock;system_u:object_r:svirt_image_t:s0:c41,c264 + /altlabel.sock;system_u:object_r:svirt_image_custom_t:s0:c41,c264 +-- +2.35.1 + diff --git a/libvirt-tools-Fix-install_mode-for-some-scripts.patch b/libvirt-tools-Fix-install_mode-for-some-scripts.patch new file mode 100644 index 0000000..7cea092 --- /dev/null +++ b/libvirt-tools-Fix-install_mode-for-some-scripts.patch @@ -0,0 +1,65 @@ +From 48f4d21cf73e15e145258bf1d590ca279838168c Mon Sep 17 00:00:00 2001 +Message-Id: <48f4d21cf73e15e145258bf1d590ca279838168c@dist-git> +From: Michal Privoznik +Date: Thu, 8 Dec 2022 08:39:24 +0100 +Subject: [PATCH] tools: Fix install_mode for some scripts + +Scripts from the following list were installed with group write +bit set: virt-xml-validate, virt-pki-validate, +virt-sanlock-cleanup, libvirt-guests.sh. This is very unusual and +in contrast with the way other scripts/binaries are installed. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2151202 +Signed-off-by: Michal Privoznik +Reviewed-by: Peter Krempa +Reviewed-by: Jiri Denemark +(cherry picked from commit e771e32f15ff2b263ca70306d93080541a96792b) +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2153688 +Signed-off-by: Michal Privoznik +--- + tools/meson.build | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/tools/meson.build b/tools/meson.build +index 2d0aecb90b..7c6e527939 100644 +--- a/tools/meson.build ++++ b/tools/meson.build +@@ -247,7 +247,7 @@ configure_file( + configuration: tools_conf, + install: true, + install_dir: bindir, +- install_mode: 'rwxrwxr-x', ++ install_mode: 'rwxr-xr-x', + ) + + configure_file( +@@ -256,7 +256,7 @@ configure_file( + configuration: tools_conf, + install: true, + install_dir: bindir, +- install_mode: 'rwxrwxr-x', ++ install_mode: 'rwxr-xr-x', + ) + + executable( +@@ -293,7 +293,7 @@ if conf.has('WITH_SANLOCK') + configuration: tools_conf, + install: true, + install_dir: sbindir, +- install_mode: 'rwxrwxr-x', ++ install_mode: 'rwxr-xr-x', + ) + endif + +@@ -304,7 +304,7 @@ if conf.has('WITH_LIBVIRTD') + configuration: tools_conf, + install: true, + install_dir: libexecdir, +- install_mode: 'rwxrwxr-x', ++ install_mode: 'rwxr-xr-x', + ) + + if init_script == 'systemd' +-- +2.39.0 + diff --git a/libvirt-util-json-Split-out-array-strinlist-conversion-from-virJSONValueObjectGetStringArray.patch b/libvirt-util-json-Split-out-array-strinlist-conversion-from-virJSONValueObjectGetStringArray.patch new file mode 100644 index 0000000..11146b6 --- /dev/null +++ b/libvirt-util-json-Split-out-array-strinlist-conversion-from-virJSONValueObjectGetStringArray.patch @@ -0,0 +1,124 @@ +From b7d9527c9d9cc782933a5b852869cbd10e370a3a Mon Sep 17 00:00:00 2001 +Message-Id: +From: Peter Krempa +Date: Thu, 1 Dec 2022 13:32:07 +0100 +Subject: [PATCH] util: json: Split out array->strinlist conversion from + virJSONValueObjectGetStringArray + +Introduce virJSONValueArrayToStringList which does only the conversion +from an array to a stringlist. + +This will allow refactoring the callers to be more careful in case when +they want to handle the existance of the member in the parent object +differently. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +(cherry picked from commit 6765bdeaf7e9cbdb4c39d47f3b77fb28a498408a) +https://bugzilla.redhat.com/show_bug.cgi?id=2149752 +--- + src/libvirt_private.syms | 1 + + src/util/virjson.c | 43 ++++++++++++++++++++++------------------ + src/util/virjson.h | 2 ++ + 3 files changed, 27 insertions(+), 19 deletions(-) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 5b7a056151..fa734dfd33 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -2513,6 +2513,7 @@ virJSONValueArrayForeachSteal; + virJSONValueArrayGet; + virJSONValueArraySize; + virJSONValueArraySteal; ++virJSONValueArrayToStringList; + virJSONValueCopy; + virJSONValueFree; + virJSONValueFromString; +diff --git a/src/util/virjson.c b/src/util/virjson.c +index 6e13e97e15..5f1565107d 100644 +--- a/src/util/virjson.c ++++ b/src/util/virjson.c +@@ -1312,10 +1312,7 @@ virJSONValueObjectStealObject(virJSONValue *object, + char ** + virJSONValueObjectGetStringArray(virJSONValue *object, const char *key) + { +- g_auto(GStrv) ret = NULL; + virJSONValue *data; +- size_t n; +- size_t i; + + data = virJSONValueObjectGetArray(object, key); + if (!data) { +@@ -1325,32 +1322,40 @@ virJSONValueObjectGetStringArray(virJSONValue *object, const char *key) + return NULL; + } + +- n = virJSONValueArraySize(data); +- ret = g_new0(char *, n + 1); ++ return virJSONValueArrayToStringList(data); ++} ++ ++ ++/** ++ * virJSONValueArrayToStringList: ++ * @data: a JSON array containing strings to convert ++ * ++ * Converts @data a JSON array containing strings to a NULL-terminated string ++ * list. @data must be a JSON array. In case @data is doesn't contain only ++ * strings an error is reported. ++ */ ++char ** ++virJSONValueArrayToStringList(virJSONValue *data) ++{ ++ size_t n = virJSONValueArraySize(data); ++ g_auto(GStrv) ret = g_new0(char *, n + 1); ++ size_t i; ++ + for (i = 0; i < n; i++) { + virJSONValue *child = virJSONValueArrayGet(data, i); +- const char *tmp; + +- if (!child) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("%s array element is missing item %zu"), +- key, i); ++ if (!child || ++ !(ret[i] = g_strdup(virJSONValueGetString(child)))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("JSON string array contains non-string element")); + return NULL; + } +- +- if (!(tmp = virJSONValueGetString(child))) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("%s array element does not contain a string"), +- key); +- return NULL; +- } +- +- ret[i] = g_strdup(tmp); + } + + return g_steal_pointer(&ret); + } + ++ + /** + * virJSONValueObjectForeachKeyValue: + * @object: JSON object to iterate +diff --git a/src/util/virjson.h b/src/util/virjson.h +index aced48a538..c9f83ab2bc 100644 +--- a/src/util/virjson.h ++++ b/src/util/virjson.h +@@ -172,6 +172,8 @@ virJSONValueObjectGetString(virJSONValue *object, + char ** + virJSONValueObjectGetStringArray(virJSONValue *object, + const char *key); ++char ** ++virJSONValueArrayToStringList(virJSONValue *data); + const char * + virJSONValueObjectGetStringOrNumber(virJSONValue *object, + const char *key); +-- +2.39.0 + diff --git a/libvirt-virDomainDiskDefValidate-Improve-error-messages-for-startupPolicy-checks.patch b/libvirt-virDomainDiskDefValidate-Improve-error-messages-for-startupPolicy-checks.patch new file mode 100644 index 0000000..a6076a1 --- /dev/null +++ b/libvirt-virDomainDiskDefValidate-Improve-error-messages-for-startupPolicy-checks.patch @@ -0,0 +1,51 @@ +From 41247c87fd47f2e55825d62c697da810ba5062f5 Mon Sep 17 00:00:00 2001 +Message-Id: <41247c87fd47f2e55825d62c697da810ba5062f5@dist-git> +From: Peter Krempa +Date: Tue, 14 Jun 2022 13:13:48 +0200 +Subject: [PATCH] virDomainDiskDefValidate: Improve error messages for + 'startupPolicy' checks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Remove linebreak and mention the attribute name. Also prepare the error +messages for future by substituting the type of offending access. + +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +(cherry picked from commit 9a480737c8adf92c332aa850c5269191ceb04eb9) +https://bugzilla.redhat.com/show_bug.cgi?id=2095758 +--- + src/conf/domain_validate.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c +index a4271f1247..452742e67c 100644 +--- a/src/conf/domain_validate.c ++++ b/src/conf/domain_validate.c +@@ -778,9 +778,9 @@ virDomainDiskDefValidate(const virDomainDef *def, + if (disk->startupPolicy != VIR_DOMAIN_STARTUP_POLICY_DEFAULT) { + if (disk->src->type == VIR_STORAGE_TYPE_NETWORK) { + virReportError(VIR_ERR_XML_ERROR, +- _("Setting disk %s is not allowed for " +- "disk of network type"), +- virDomainStartupPolicyTypeToString(disk->startupPolicy)); ++ _("disk startupPolicy '%s' is not allowed for disk of '%s' type"), ++ virDomainStartupPolicyTypeToString(disk->startupPolicy), ++ virStorageTypeToString(disk->src->type)); + return -1; + } + +@@ -788,8 +788,7 @@ virDomainDiskDefValidate(const virDomainDef *def, + disk->device != VIR_DOMAIN_DISK_DEVICE_FLOPPY && + disk->startupPolicy == VIR_DOMAIN_STARTUP_POLICY_REQUISITE) { + virReportError(VIR_ERR_XML_ERROR, "%s", +- _("Setting disk 'requisite' is allowed only for " +- "cdrom or floppy")); ++ _("disk startupPolicy 'requisite' is allowed only for cdrom or floppy")); + return -1; + } + } +-- +2.35.1 + diff --git a/libvirt-virDomainDiskDefValidateStartupPolicy-Validate-disk-type-better.patch b/libvirt-virDomainDiskDefValidateStartupPolicy-Validate-disk-type-better.patch new file mode 100644 index 0000000..f57195b --- /dev/null +++ b/libvirt-virDomainDiskDefValidateStartupPolicy-Validate-disk-type-better.patch @@ -0,0 +1,42 @@ +From 26daf647925213a05509cc302d9151fe4525febb Mon Sep 17 00:00:00 2001 +Message-Id: <26daf647925213a05509cc302d9151fe4525febb@dist-git> +From: Peter Krempa +Date: Tue, 14 Jun 2022 14:07:47 +0200 +Subject: [PATCH] virDomainDiskDefValidateStartupPolicy: Validate disk type + better +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Our startup policy checkers work only for local paths, so disk sources +such as NVMe, or vhost-user can't be used with startup policy. + +Unfortunately the validation did not catch these cases. Fix it. + +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +(cherry picked from commit b90d0f0a1e4ee52c828fb683c14c14e241e6fcbb) +https://bugzilla.redhat.com/show_bug.cgi?id=2095758 +--- + src/conf/domain_validate.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c +index bfff7339ef..55759af9f8 100644 +--- a/src/conf/domain_validate.c ++++ b/src/conf/domain_validate.c +@@ -604,7 +604,10 @@ virDomainDiskDefValidateStartupPolicy(const virDomainDiskDef *disk) + if (disk->startupPolicy == VIR_DOMAIN_STARTUP_POLICY_DEFAULT) + return 0; + +- if (disk->src->type == VIR_STORAGE_TYPE_NETWORK) { ++ /* We want to allow any startup policy for un-translated _TYPE_VOLUME disks. ++ * virStorageSourceGetActualType returns _TYPE_VOLUME in such case */ ++ if (virStorageSourceGetActualType(disk->src) != VIR_STORAGE_TYPE_VOLUME && ++ !virStorageSourceIsLocalStorage(disk->src)) { + virReportError(VIR_ERR_XML_ERROR, + _("disk startupPolicy '%s' is not allowed for disk of '%s' type"), + virDomainStartupPolicyTypeToString(disk->startupPolicy), +-- +2.35.1 + diff --git a/libvirt-virDomainDiskTranslateSourcePool-Fix-check-of-startupPolicy-definition.patch b/libvirt-virDomainDiskTranslateSourcePool-Fix-check-of-startupPolicy-definition.patch new file mode 100644 index 0000000..d8ab75e --- /dev/null +++ b/libvirt-virDomainDiskTranslateSourcePool-Fix-check-of-startupPolicy-definition.patch @@ -0,0 +1,56 @@ +From 2ea89fb18aa9d2dac1e651869736fede7a2ec434 Mon Sep 17 00:00:00 2001 +Message-Id: <2ea89fb18aa9d2dac1e651869736fede7a2ec434@dist-git> +From: Peter Krempa +Date: Tue, 14 Jun 2022 14:21:33 +0200 +Subject: [PATCH] virDomainDiskTranslateSourcePool: Fix check of + 'startupPolicy' definition +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The check was historically done only for _TYPE_VOLUME disks, but +refactors to allow _TYPE_VOLUME disks in the backing chain caused a +regression where we'd reject startupPolicy also for _TYPE_BLOCK disks +which historically worked well. + +Fix it by using the 'virDomainDiskDefValidateStartupPolicy' helper and +use it only when the top level image is a _TYPE_VOLUME as in other cases +it was already validated. This also allows _TYPE_BLOCK volumes to use +startup policy. + +Fixes: 37f01262eed9f37dd5eb7de8b83edd2fea741054 +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2095758 +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +(cherry picked from commit ed8984306e1cd44c424fda3ed412a4177dd7b84d) +--- + src/conf/domain_conf.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 805a15848e..92510973e6 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -31311,13 +31311,13 @@ virDomainDiskTranslateSourcePool(virDomainDiskDef *def) + + if (virDomainStorageSourceTranslateSourcePool(n, conn) < 0) + return -1; +- } + +- if (def->startupPolicy != 0 && +- virStorageSourceGetActualType(def->src) != VIR_STORAGE_TYPE_FILE) { +- virReportError(VIR_ERR_XML_ERROR, "%s", +- _("'startupPolicy' is only valid for 'file' type volume")); +- return -1; ++ /* The validity of 'startupPolicy' setting is checked only for the top ++ * level image. For any other subsequent images we honour it only if ++ * possible */ ++ if (n == def->src && ++ virDomainDiskDefValidateStartupPolicy(def) < 0) ++ return -1; + } + + return 0; +-- +2.35.1 + diff --git a/libvirt-virpidfile-Add-virPidFileReadPathIfLocked-func.patch b/libvirt-virpidfile-Add-virPidFileReadPathIfLocked-func.patch new file mode 100644 index 0000000..b3b154f --- /dev/null +++ b/libvirt-virpidfile-Add-virPidFileReadPathIfLocked-func.patch @@ -0,0 +1,96 @@ +From 9d0247153a70ab1909d0690ec9b7f4d20e8cb602 Mon Sep 17 00:00:00 2001 +Message-Id: <9d0247153a70ab1909d0690ec9b7f4d20e8cb602@dist-git> +From: Vasiliy Ulyanov +Date: Wed, 2 Feb 2022 17:28:15 +0100 +Subject: [PATCH] virpidfile: Add virPidFileReadPathIfLocked func + +The function will attempt to read a pid from @path, and store it in +@pid. The @pid will only be set, however, if @path is locked by +virFileLock() at byte 0 and the pid in @path is running. + +Signed-off-by: Vasiliy Ulyanov +Signed-off-by: Michal Privoznik +Reviewed-by: Michal Privoznik +(cherry picked from commit 013ab22f79d1345daf6b2778ca498acb16939011) +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2152188 +Signed-off-by: Michal Privoznik +--- + src/libvirt_private.syms | 1 + + src/util/virpidfile.c | 35 +++++++++++++++++++++++++++++++++++ + src/util/virpidfile.h | 2 ++ + 3 files changed, 38 insertions(+) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index fa734dfd33..568b0f34a1 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -3061,6 +3061,7 @@ virPidFileRead; + virPidFileReadIfAlive; + virPidFileReadPath; + virPidFileReadPathIfAlive; ++virPidFileReadPathIfLocked; + virPidFileRelease; + virPidFileReleasePath; + virPidFileWrite; +diff --git a/src/util/virpidfile.c b/src/util/virpidfile.c +index 7069f8343d..9d194f7336 100644 +--- a/src/util/virpidfile.c ++++ b/src/util/virpidfile.c +@@ -302,6 +302,41 @@ int virPidFileReadIfAlive(const char *dir, + return 0; + } + ++/** ++ * virPidFileReadPathIfLocked: ++ * @path: path to pidfile ++ * @pid: variable to return pid in ++ * ++ * This will attempt to read a pid from @path, and store it in ++ * @pid. The @pid will only be set, however, if the pid in @path ++ * is running, and @path is locked by virFileLock() at byte 0 ++ * (which is exactly what virCommandSetPidFile() results in). ++ * This adds protection against returning a stale pid. ++ * ++ * Returns -1 upon error, or zero on successful ++ * reading of the pidfile. If @path is not locked ++ * or if the PID was not still alive, zero will ++ * be returned, but @pid will be set to -1. ++ */ ++int virPidFileReadPathIfLocked(const char *path, pid_t *pid) ++{ ++ VIR_AUTOCLOSE fd = -1; ++ ++ if ((fd = open(path, O_RDWR)) < 0) ++ return -1; ++ ++ if (virFileLock(fd, false, 0, 1, false) >= 0) { ++ /* The file isn't locked. PID is stale. */ ++ *pid = -1; ++ return 0; ++ } ++ ++ if (virPidFileReadPathIfAlive(path, pid, NULL) < 0) ++ return -1; ++ ++ return 0; ++} ++ + + int virPidFileDeletePath(const char *pidfile) + { +diff --git a/src/util/virpidfile.h b/src/util/virpidfile.h +index fd8013c41e..e84542f298 100644 +--- a/src/util/virpidfile.h ++++ b/src/util/virpidfile.h +@@ -48,6 +48,8 @@ int virPidFileReadIfAlive(const char *dir, + const char *name, + pid_t *pid, + const char *binpath) G_GNUC_WARN_UNUSED_RESULT; ++int virPidFileReadPathIfLocked(const char *path, ++ pid_t *pid) G_GNUC_WARN_UNUSED_RESULT; + + int virPidFileDeletePath(const char *path); + int virPidFileDelete(const char *dir, +-- +2.39.0 + diff --git a/libvirt-virsh-Add-support-for-VIR_MIGRATE_ZEROCOPY-flag.patch b/libvirt-virsh-Add-support-for-VIR_MIGRATE_ZEROCOPY-flag.patch new file mode 100644 index 0000000..c16422a --- /dev/null +++ b/libvirt-virsh-Add-support-for-VIR_MIGRATE_ZEROCOPY-flag.patch @@ -0,0 +1,80 @@ +From 20c1c86f96dd7293734888ef6f8b75c11cda5fae Mon Sep 17 00:00:00 2001 +Message-Id: <20c1c86f96dd7293734888ef6f8b75c11cda5fae@dist-git> +From: Jiri Denemark +Date: Wed, 22 Jun 2022 16:36:53 +0200 +Subject: [PATCH] virsh: Add support for VIR_MIGRATE_ZEROCOPY flag +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit efa3baeae70fbdf4ab032ca485cb9272ee96bd50) + +https://bugzilla.redhat.com/show_bug.cgi?id=2089433 + +Conflicts: + docs/manpages/virsh.rst + tools/virsh-domain.c + - post-copy recovery not backported + +Signed-off-by: Jiri Denemark +--- + docs/manpages/virsh.rst | 8 +++++++- + tools/virsh-domain.c | 7 +++++++ + 2 files changed, 14 insertions(+), 1 deletion(-) + +diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst +index dd534c10cb..d24e7774a6 100644 +--- a/docs/manpages/virsh.rst ++++ b/docs/manpages/virsh.rst +@@ -3225,7 +3225,8 @@ migrate + migrate [--live] [--offline] [--direct] [--p2p [--tunnelled]] + [--persistent] [--undefinesource] [--suspend] [--copy-storage-all] + [--copy-storage-inc] [--change-protection] [--unsafe] [--verbose] +- [--rdma-pin-all] [--abort-on-error] [--postcopy] [--postcopy-after-precopy] ++ [--rdma-pin-all] [--abort-on-error] [--postcopy] ++ [--postcopy-after-precopy] [--zerocopy] + domain desturi [migrateuri] [graphicsuri] [listen-address] [dname] + [--timeout seconds [--timeout-suspend | --timeout-postcopy]] + [--xml file] [--migrate-disks disk-list] [--disks-port port] +@@ -3298,6 +3299,11 @@ high (and thus allowing the domain to lock most of the host's memory). Doing so + may be dangerous to both the domain and the host itself since the host's kernel + may run out of memory. + ++*--zerocopy* requests zero-copy mechanism to be used for migrating memory pages. ++For QEMU/KVM this means QEMU will be temporarily allowed to lock all guest ++pages in host's memory, although only those that are queued for transfer will ++be locked at the same time. ++ + ``Note``: Individual hypervisors usually do not support all possible types of + migration. For example, QEMU does not support direct migration. + +diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c +index b56f6a90f5..c5bade1dbf 100644 +--- a/tools/virsh-domain.c ++++ b/tools/virsh-domain.c +@@ -10730,6 +10730,10 @@ static const vshCmdOptDef opts_migrate[] = { + .type = VSH_OT_BOOL, + .help = N_("automatically switch to post-copy migration after one pass of pre-copy") + }, ++ {.name = "zerocopy", ++ .type = VSH_OT_BOOL, ++ .help = N_("use zero-copy mechanism for migrating memory pages") ++ }, + {.name = "migrateuri", + .type = VSH_OT_STRING, + .completer = virshCompleteEmpty, +@@ -11133,6 +11137,9 @@ doMigrate(void *opaque) + if (vshCommandOptBool(cmd, "postcopy")) + flags |= VIR_MIGRATE_POSTCOPY; + ++ if (vshCommandOptBool(cmd, "zerocopy")) ++ flags |= VIR_MIGRATE_ZEROCOPY; ++ + if (vshCommandOptBool(cmd, "tls")) + flags |= VIR_MIGRATE_TLS; + +-- +2.35.1 + diff --git a/libvirt.spec b/libvirt.spec index 8ae795f..23a9567 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -210,7 +210,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 8.0.0 -Release: 6%{?dist}%{?extra_release} +Release: 14%{?dist}%{?extra_release} License: LGPLv2+ URL: https://libvirt.org/ @@ -242,6 +242,46 @@ Patch19: libvirt-conf-Introduce-memory-allocation-threads.patch Patch20: libvirt-qemu_capabilities-Detect-memory-backend-.prealloc-threads-property.patch Patch21: libvirt-qemu_validate-Validate-prealloc-threads-against-qemuCpas.patch Patch22: libvirt-qemu_command-Generate-prealloc-threads-property.patch +Patch23: libvirt-cpu_map-Disable-cpu64-rhel-for-host-model-and-baseline.patch +Patch24: libvirt-cputest-Drop-some-old-artificial-baseline-tests.patch +Patch25: libvirt-cputest-Give-better-names-to-baseline-tests.patch +Patch26: libvirt-cputest-Add-some-real-world-baseline-tests.patch +Patch27: libvirt-cpu_x86-Consolidate-signature-match-in-x86DecodeUseCandidate.patch +Patch28: libvirt-cpu_x86-Refactor-feature-list-comparison-in-x86DecodeUseCandidate.patch +Patch29: libvirt-cpu_x86-Penalize-disabled-features-when-computing-CPU-model.patch +Patch30: libvirt-cpu_x86-Ignore-enabled-features-for-input-models-in-x86DecodeUseCandidate.patch +Patch31: libvirt-nwfilter-fix-crash-when-counting-number-of-network-filters.patch +Patch32: libvirt-virDomainDiskDefValidate-Improve-error-messages-for-startupPolicy-checks.patch +Patch33: libvirt-domain_validate-Split-out-validation-of-disk-startup-policy.patch +Patch34: libvirt-virDomainDiskDefValidateStartupPolicy-Validate-disk-type-better.patch +Patch35: libvirt-virDomainDiskTranslateSourcePool-Fix-check-of-startupPolicy-definition.patch +Patch36: libvirt-conf-virtiofs-add-thread_pool-element.patch +Patch37: libvirt-qemu-virtiofs-format-thread-pool-size.patch +Patch38: libvirt-conf-Move-virDomainObj-originalMemlock-into-qemuDomainObjPrivate.patch +Patch39: libvirt-qemu_domain-Format-qemuDomainObjPrivate-originalMemlock.patch +Patch40: libvirt-qemu-Add-qemuDomainSetMaxMemLock-helper.patch +Patch41: libvirt-qemu_migration-Use-qemuDomainSetMaxMemLock.patch +Patch42: libvirt-qemu_migration-Restore-original-memory-locking-limit.patch +Patch43: libvirt-Add-VIR_MIGRATE_ZEROCOPY-flag.patch +Patch44: libvirt-virsh-Add-support-for-VIR_MIGRATE_ZEROCOPY-flag.patch +Patch45: libvirt-qemu_migration-Implement-VIR_MIGRATE_ZEROCOPY-flag.patch +Patch46: libvirt-security_selinux.c-Relabel-existing-mode-bind-UNIX-sockets.patch +Patch47: libvirt-RHEL-qemu_migration-Fix-restoring-memlock-limit-on-destination.patch +Patch48: libvirt-qemu_process-Don-t-require-a-hugetlbfs-mount-for-memfd.patch +Patch49: libvirt-qemu_namespace-Tolerate-missing-ACLs-when-creating-a-path-in-namespace.patch +Patch50: libvirt-qemu_namespace-Fix-a-corner-case-in-qemuDomainGetPreservedMounts.patch +Patch51: libvirt-qemu_namespace-Introduce-qemuDomainNamespaceSetupPath.patch +Patch52: libvirt-qemu_process.c-Propagate-hugetlbfs-mounts-on-reconnect.patch +Patch53: libvirt-qemuProcessReconnect-Don-t-build-memory-paths.patch +Patch54: libvirt-util-json-Split-out-array-strinlist-conversion-from-virJSONValueObjectGetStringArray.patch +Patch55: libvirt-qemuAgentGetDisks-Don-t-use-virJSONValueObjectGetStringArray-for-optional-data.patch +Patch56: libvirt-virpidfile-Add-virPidFileReadPathIfLocked-func.patch +Patch57: libvirt-qemu-tpm-Get-swtpm-pid-without-binary-validation.patch +Patch58: libvirt-qemu_tpm-Do-async-IO-when-starting-swtpm-emulator.patch +Patch59: libvirt-qemu-gpu-Get-pid-without-binary-validation.patch +Patch60: libvirt-build-Only-install-libvirt-guests-when-building-libvirtd.patch +Patch61: libvirt-tools-Fix-install_mode-for-some-scripts.patch +Patch62: libvirt-qemu-Ignore-missing-vm.unprivileged_userfaultfd-sysctl.patch Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -422,6 +462,12 @@ Summary: Server side daemon and supporting files for libvirt library # The client side, i.e. shared libs are in a subpackage Requires: %{name}-libs = %{version}-%{release} +# The libvirt-guests.sh script requires virsh from libvirt-client subpackage, +# but not every deployment wants to use libvirt-guests service. Using +# Recommends here will install libvirt-client by default (if available), but +# RPM won't complain if the package is unavailable, masked, or removed later. +Recommends: %{name}-client = %{version}-%{release} + # netcat is needed on the server side so that clients that have # libvirt < 6.9.0 can connect, but newer versions will prefer # virt-ssh-helper. Making this a Recommends means that it gets @@ -2115,6 +2161,63 @@ exit 0 %changelog +* Wed Jan 11 2023 Jiri Denemark - 8.0.0-14 +- qemu: Ignore missing vm.unprivileged_userfaultfd sysctl (rhbz#2148578) + +* Wed Jan 4 2023 Jiri Denemark - 8.0.0-13 +- build: Only install libvirt-guests when building libvirtd (rhbz#2153688) +- tools: Fix install_mode for some scripts (rhbz#2153688) + +* Tue Dec 13 2022 Jiri Denemark - 8.0.0-12 +- util: json: Split out array->strinlist conversion from virJSONValueObjectGetStringArray (rhbz#2149752) +- qemuAgentGetDisks: Don't use virJSONValueObjectGetStringArray for optional data (rhbz#2149752) +- virpidfile: Add virPidFileReadPathIfLocked func (rhbz#2152188) +- qemu: tpm: Get swtpm pid without binary validation (rhbz#2152188) +- qemu_tpm: Do async IO when starting swtpm emulator (rhbz#2152188) +- qemu: gpu: Get pid without binary validation (rhbz#2152188) +- spec: libvirt-daemon: Add optional dependency on *-client (rhbz#2136591) + +* Fri Oct 7 2022 Jiri Denemark - 8.0.0-11 +- qemu_process: Don't require a hugetlbfs mount for memfd (rhbz#2123196) +- qemu_namespace: Tolerate missing ACLs when creating a path in namespace (rhbz#2123196) +- qemu_namespace: Fix a corner case in qemuDomainGetPreservedMounts() (rhbz#2123196) +- qemu_namespace: Introduce qemuDomainNamespaceSetupPath() (rhbz#2123196) +- qemu_process.c: Propagate hugetlbfs mounts on reconnect (rhbz#2123196) +- qemuProcessReconnect: Don't build memory paths (rhbz#2123196) + +* Mon Jul 25 2022 Jiri Denemark - 8.0.0-10 +- security_selinux.c: Relabel existing mode="bind" UNIX sockets (rhbz#2101575) +- RHEL: qemu_migration: Fix restoring memlock limit on destination (rhbz#2107954) + +* Thu Jun 30 2022 Jiri Denemark - 8.0.0-9 +- conf: virtiofs: add thread_pool element (rhbz#2079582) +- qemu: virtiofs: format --thread-pool-size (rhbz#2079582) +- conf: Move virDomainObj::originalMemlock into qemuDomainObjPrivate (rhbz#2089433) +- qemu_domain: Format qemuDomainObjPrivate::originalMemlock (rhbz#2089433) +- qemu: Add qemuDomainSetMaxMemLock helper (rhbz#2089433) +- qemu_migration: Use qemuDomainSetMaxMemLock (rhbz#2089433) +- qemu_migration: Restore original memory locking limit (rhbz#2089433) +- Add VIR_MIGRATE_ZEROCOPY flag (rhbz#2089433) +- virsh: Add support for VIR_MIGRATE_ZEROCOPY flag (rhbz#2089433) +- qemu_migration: Implement VIR_MIGRATE_ZEROCOPY flag (rhbz#2089433) + +* Wed Jun 15 2022 Jiri Denemark - 8.0.0-8 +- nwfilter: fix crash when counting number of network filters (CVE-2022-0897, rhbz#2063902) +- virDomainDiskDefValidate: Improve error messages for 'startupPolicy' checks (rhbz#2095758) +- domain_validate: Split out validation of disk startup policy (rhbz#2095758) +- virDomainDiskDefValidateStartupPolicy: Validate disk type better (rhbz#2095758) +- virDomainDiskTranslateSourcePool: Fix check of 'startupPolicy' definition (rhbz#2095758) + +* Tue May 17 2022 Jiri Denemark - 8.0.0-7 +- cpu_map: Disable cpu64-rhel* for host-model and baseline (rhbz#1851227) +- cputest: Drop some old artificial baseline tests (rhbz#1851227) +- cputest: Give better names to baseline tests (rhbz#1851227) +- cputest: Add some real world baseline tests (rhbz#1851227) +- cpu_x86: Consolidate signature match in x86DecodeUseCandidate (rhbz#1851227) +- cpu_x86: Refactor feature list comparison in x86DecodeUseCandidate (rhbz#1851227) +- cpu_x86: Penalize disabled features when computing CPU model (rhbz#1851227) +- cpu_x86: Ignore enabled features for input models in x86DecodeUseCandidate (rhbz#1851227) + * Wed Apr 27 2022 Jiri Denemark - 8.0.0-6 - conf: Introduce memory allocation threads (rhbz#2067126) - qemu_capabilities: Detect memory-backend-*.prealloc-threads property (rhbz#2067126) diff --git a/sources b/sources index 776e466..ddef389 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libvirt-8.0.0.tar.xz) = e84cf2753d3c57cfe5aadbb6601fa76e0ba750471c1c24631720fe64376c3599ea252863ec671a50527e4fb380ffe0c2f02f07705b4b87d373ccf3e516ff4b1c +SHA1 (libvirt-8.0.0.tar.xz) = e440412e9b45d7e24f0ef492d8edf5cf2cbd3f4c